which Point2D should I use

2019-04-08 15:32发布

The jdk8 contains 3 different Point2D classes.

  • java.awt.geom.Point2D in the rt.jar
  • javafx.geometry.Point2D in the jfxrt.jar
  • com.sun.javafx.geom.Point2D in the jfxrt.jar

Which Point2D class should I use ?

Use/application: I want to perform geometric calculations to determine if a point intersects with a line. (e.g. Line2D.contains(Point2D))

Given the fact that I'm also using other javafx features (i.e. also in the javafx.* package). My first guess, would be to use the javafx.geometry.Point2D class. However while this package does contain a Point2D class, it does not contain a Line2D class, but the other 2 packages do contain a Line2D package.

On the other hand, I don't want to pick a class that will be deprecated in the near future.

EDIT:

Perhaps a minor detail: the Point2D class of the awt and com.sun package use float's for defining their points, which requires a lot of casting. While the javafx version uses double, which is pretty convenient, since javafx also prefers double for arranging components (e.g. getPrefWidth, getLayoutX, ...).

EDIT2:

Actually the Line2D class is not a big help. The contains methods always return false. So, it looks like I have to write my own intersect method anyway.

2条回答
聊天终结者
2楼-- · 2019-04-08 16:06

I took the advice of AlmastB, and decided to create my own Line2D class for compatibility with the javafx.geometry.Point2D class.

public class Line2D {
    double x1;
    double y1;
    double x2;
    double y2;

    public Line2D(double x1, double y1, double x2, double y2) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
    }

    public Line2D(Point2D point1, Point2D point2) {
        this(point1.getX(), point1.getY(), point2.getX(), point2.getY());
    }

    public double length()
    {
        return new Point2D(x1, y1).distance(x2, y2);
    }

    public double distance(double x, double y) {
        double d1 = x * (y2 - y1) - y * (x2 - x1) + x2 * y1 - y2 * x1;
        return Math.abs(d1) / length();
    }

    public double distance(Point2D toPoint) {
        return distance(toPoint.getX(), toPoint.getY());
    }
}

As you will notice, originally I only made a distance method. An intersects method is tricky, because it requires comparing double values. Operations with floating point numbers can introduce small deviations. In short: you can only judge if a point is on a line, by a certain precision. It's hard to say what that precision should be.

The distance method has a point of attention as well. It assumes that the line runs through the 2 points, but is not bounded by it (i.e. it has an infinit length).

Intersects method

An intersects method would look as follows:

    public boolean intersects(Point2D toPoint, double precision, boolean checkBounds) {
        if (checkBounds &&
                ((toPoint.getX() < Math.min(x1, x2) - precision) ||
                 (toPoint.getX() > Math.max(x1, x2) + precision) ||
                 (toPoint.getY() < Math.min(y1, y2) - precision) ||
                 (toPoint.getY() > Math.max(y1, y2) + precision))) return false;
        return distance(toPoint.getX(), toPoint.getY()) < precision;
    }

This takes the 2 previous remarks in account (i.e. precision and bounds).

查看更多
啃猪蹄的小仙女
3楼-- · 2019-04-08 16:09

java.awt is a different UI toolkit to JavaFX. It is not recommended to mix classes from different libraries, especially provided that you already use JavaFX features.

Everything that starts with com.sun should be avoided as it is private API and there is no guarantee that it will continue working in the next update.

Your best course of action in this scenario is to use javafx.geometry.Point2D and implement your own Line2D. As an alternative you can use the JavaFX scene graph and its Circle (with radius of 0.5) and Line (with stroke width of 1) classes to help you with your calculations.

查看更多
登录 后发表回答