"找到最佳交叉点"实施错误结果

时间:2016-10-15 09:40:35

标签: java math

嗨,我可以通过以下链接找到原始问题,但它被暂停,因为我没有将它与我的实现联系起来,所以我现在就这样做。

https://stackoverflow.com/questions/40030999/find-best-collision-point?noredirect=1#comment67383779_40030999

我在另一个线程中找到了解决这个问题的方法但是我总是得到错误的结果,尽管输出似乎合理......

Intersection of two Moving Objects with Latitude/Longitude Coordinates

我的代码很简单。我有一个点类(不是java.awt.Point,因为我的点总是位于精确的整数上),这可以帮助我确定问题。

public static class Point {
    /**
     * the x position of this position
     */
    private int x;
    /**
     * the y position of this position
     */
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    /**
     * calculates the Euclidean distance between this position and another one.
     *
     * @param point the position to which the distance should be calculated.
     * @return the Euclidean distance
     */
    public int getDistance(Point point) {
        int dx = Math.abs(x - point.getX());
        int dy = Math.abs(y - point.getY());
        return (int) Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
    }

    /**
     * calculates the angle between two points.
     *
     * @param target the point to which the angle should be calculated
     * @return the angle in degrees
     */
    public double getAngle(Point target) {
        double angle = Math.toDegrees(Math.atan2(target.y - y, target.x - x));
        if (angle < 0) {
            angle += 360;
        }
        return angle;
    }

    public Point getBestIntersectionPoint(int mySpeed, Point target, int targetSpeed, Point targetsTarget) {
        double distance = getDistance(target);

        double angle = 180 - Math.abs(target.getAngle(this) - target.getAngle(targetsTarget));

        double a = Math.pow(mySpeed, 2) - Math.pow(targetSpeed, 2);
        double b = 2 * distance * targetSpeed * Math.cos(Math.toRadians(angle));
        double c = -Math.pow(distance, 2);

        System.out.println("a: " + a);
        System.out.println("b: " + b);
        System.out.println("c: " + c);

        //Finding out the roots
        double temp1 = Math.sqrt((Math.pow(b, 2)) - 4 * a * c);

        double root1 = (-b + temp1) / (2 * a);
        double root2 = (-b - temp1) / (2 * a);

        Point intersection1 = target.getPositionInTurns(targetsTarget, targetSpeed, root1);
        Point intersection2 = target.getPositionInTurns(targetsTarget, targetSpeed, root2);
        int distance1 = intersection1.getDistance(target);
        int distance2 = intersection2.getDistance(target);

        int targetDistance = target.getDistance(targetsTarget);
        System.out.println(angle + " - " + intersection1 + "; " + intersection2);
        return null;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Point)) return false;

        Point point = (Point) o;

        if (getX() != point.getX()) return false;
        return getY() == point.getY();
    }
}

这里的问题是方法&#34; getBestIntersectionPoint&#34;。例如,假设物体1位于坐标(x = 1100,y = 1200),物体2打开(x = 8250,y = 4500),物体3打开(x = 8250,y = 8999),速度保持不变如在另一个线程的图片中。正确的交点应大约在(x = 8250,y = 5000)。但是通过这个实现,我得到了两个交叉点,甚至还没有接近这一点......

点{x = 8250,y = -4738};点{x = 8250,y = 8538}

2 个答案:

答案 0 :(得分:0)

让我们把它放到一些代数中,P1(this),P2(目标),P3(目标),v1 = mySpeed,v2 = targetSpeed。 设U是从P2到P3的单位向量。

U = (P3-P2) / sqrt( (P3-P2).(P3-P2) )

设S1和S2为时间t之后的位置。

S2 = t * v2 * U + P2

我们希望从S2到P1的距离为t * v1。所以

|S2 - P1| = t v1

对LHS进行平方可以被认为是点积

(S2 - P1) . (S2 - P1) = t^2 v1^2
(t v2 * U - P1) . (t v2 * U - P1) = t^2 v1^2
v2^2 t^2 U . U - 2 t v2 U . P1 + P1 . P1 = t^2 v1^2
(v2^2 - v1^2) t^2 - (2 v2 U . P1) t + P1 . P1 = 0

给予

a = v2^2 - v1^2
b =  -(2 v2 U . P1)
c =  P1 . P1

这与您的公式非常相似。它可能有点简单,因为你不需要计算atan2,而是单位向量。我感觉你的b标志是错误的。但我确定你不想在你的计算中使用Math.abs,这可能适用于某些配置但不适用于其他配置。

答案 1 :(得分:0)

很大程度上是Salix的帮助,但你的公式有些错误。现在我花了一些时间来解决这个问题,但这是我实现的方法,可以解决这个问题。

public Point getBestIntersectionPoint(double v1, Point p2, double v2, Point p3) {
        int diffX = p3.getX() - p2.getX();
        int diffY = p3.getY() - p2.getY();

        Point u = new Point(
                diffX == 0 ? 0 : diffX / Math.abs(diffX),
                diffY == 0 ? 0 : diffY / Math.abs(diffY));

        double p1x = getX();
        double p1y = getY();

        double p2x = p2.getX();
        double p2y = p2.getY();

        double a = v1 * v1 - v2 * v2 * (u.getX() * u.getX() + u.getY() * u.getY());
        double b = (v2 * (u.getX() * (2 * p1x - 2 * p2x) + u.getY() * (2 * p1y - 2 * p2y)));
        double c = -p2x * p2x - p2y * p2y - p1x * p1x - p1y * p1y + 2 * p2x * p1x + 2 * p2y * p1y;

        double temp = Math.sqrt(Math.pow(b, 2) - 4 * a * c);
        double t1, t2; //This is now a double, too.
        t1 = (-b + temp) / (2 * a);
        t2 = (-b - temp) / (2 * a);

        Point s2_1 = new Point(
                (int) (t1 * v2 * u.getX() + p2x),
                (int) (t1 * v2 * u.getY() + p2y));
        Point s2_2 = new Point(
                (int) (t2 * v2 * u.getX() + p2x),
                (int) (t2 * v2 * u.getY() + p2y));

        Point ut1 = new Point((int) (s2_1.getX() - p2x), (int) (s2_1.getY() - p2y));
        ut1.setX(ut1.getX() / Math.abs(ut1.getX()));
        ut1.setY(ut1.getY() / Math.abs(ut1.getY()));

        Point ut2 = new Point((int) (s2_2.getX() - p2x), (int) (s2_2.getY() - p2y));
        ut2.setX(ut2.getX() / Math.abs(ut2.getX()));
        ut2.setY(ut2.getY() / Math.abs(ut2.getY()));

        return ut1.equals(u) ? s2_1 : ut2.equals(u) ? s2_2 : null;
    }