0

hi I the original question can be found with the following link but it was put on hold because I did not relate it to my implementation so I will do this now.

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

I found a solution to this problem in another thread but I always get wrong results with this eventhough the output seems reasonable...

Intersection of two Moving Objects with Latitude/Longitude Coordinates

my code is straightforward. I have a point class (not java.awt.Point since my points always lie on exact integers) that should help me determining the problem.

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();
    }
}

the problem here is the method "getBestIntersectionPoint". For example lets say objects 1 is on coordinates (x=1100,y=1200), object 2 on (x=8250, y=4500) and object 3 is on (x=8250, y=8999) the velocities keep the same as in the picture of the other thread. the correct intersection point should be approximately on (x=8250, y=5000). But with this implementation I get two intersections not even close to this point...

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

Community
  • 1
  • 1
Goldfish
  • 614
  • 1
  • 7
  • 19

2 Answers2

0

Lets put this into some algebra, with P1 (this), P2 (target), P3 (target), v1 = mySpeed, v2 = targetSpeed. Let U be a unit vector from P2 to P3.

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

Let S1 and S2 be the position after time t.

S2 = t * v2 * U + P2

We want the distance from S2 to P1 to be t * v1. So

|S2 - P1| = t v1

squaring the LHS can be thought of as a dot product

(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

Giving

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

this looks quite similar to the formula you have. It might be a little simpler as you don't need to calculate atan2, but a unit vector. I've a feeling your sign for b is wrong. But I'm sure you don't want to use Math.abs in you calcultion which may work for some configurations but not others.

Salix alba
  • 7,536
  • 2
  • 32
  • 38
0

thx Salix for the help but you had some mistakes in your formula. It took me quiet some time now to solve this issue but here is my implemented method that does the trick.

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;
    }
Goldfish
  • 614
  • 1
  • 7
  • 19