«найти наилучшую точку пересечения» дает неправильные результаты

Привет, оригинальный вопрос можно найти по следующей ссылке, но он был приостановлен, потому что я не связывал его с моей реализацией, поэтому я сделаю это сейчас.

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

Я нашел решение этой проблемы в другом потоке, но я всегда получаю неправильные результаты с этим событием, хотя результат кажется разумным ...

Пересечение двух движущихся объектов с координатами широты / долготы

мой код прост. У меня есть класс точек (а не 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();
    }
}

проблема здесь заключается в методе getBestIntersectionPoint. Например, скажем, объекты 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}

java,math,

0

Ответов: 2


0

Положим это в некоторую алгебру, с P1 (это), 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 в своих вычислениях, которые могут работать для некоторых конфигураций, но не для других.


0 "> принят

thx 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;
    }
Java, математика,
Похожие вопросы