检测两条线相交的点问题

问题描述 投票:0回答:1

我试图投射一些光线来检测光线应该去哪里。现在它只是从中心点投射到墙上的任意数量的光线。

对我不起作用的解决方案:

我在 here 大约 16:20 观看了一段 Coding Train 视频。我将其复制到我的程序中,但我遇到了非常奇怪的碰撞(碰撞不在我正在测试的线上)

然后我查看了wiki,他们的内容与他所做的有所不同,所以我复制了那个。仍然是奇怪的碰撞。

然后,我用谷歌搜索了它。并在这里找到 this 页面谈论同样的问题。虽然没有一个公认的答案。 Gareth Rees 的回答我无法理解并感到困惑。然后我在那个下面找到了 Gavin 的回答并尝试实现它。仍然是奇怪的碰撞。

确实有效的解决方案,但是*

发帖时,我正在查看潜在的重复问题,我发现this 使用 Paul Bourkes 解决方案的帖子。除了奇怪地需要反转 if 条件(??)之外,它确实检测到了它!但是-很奇怪。

如果我将线的端点设置为交点,那么光线会变得相当……粘稠?到角落。我不希望他们从原点移动角度,所以这是行不通的。

如果我将光线的强度设置为新点和原点的斜边,我必须将它除以 2 才能得到它与直线之间的真实距离?就像,它应该是距离的两倍。此外,如果我移动鼠标太快(有时看似随机),它会在其相交时将强度更新回其原始值。改变更新循环的速度似乎对我没有帮助。

我是否忽略了一些重要的事情?错过错别字?我在这里迷路了。

这是我最后一次尝试的代码:

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

import java.util.ArrayList;

public class Controller extends Application {
    public static ArrayList<Ray> Rays = new ArrayList<>();
    public static double mousex;
    public static double mousey;

    public static Line line = new Line();

    @Override
    public void start(Stage stage) {
        Pane p = new Pane();
        Scene scene = new Scene(p, 400, 400);
        stage.setTitle("Hello!");
        stage.setScene(scene);
        stage.show();

        obstactles(p);
        mouseTracking(scene);
        // i originally had multiple rays using this. scaled it back to 1 when i had problems
        // so i wasn't overwhelmed.
        for (int a = 0; a < 1; a++) {
            Ray r = new Ray(200, 200, 11.25*a, 500);
            Rays.add(r);
            p.getChildren().add(r.getRay());
        }

        line.setStartX(100);
        line.setStartY(100);
        line.setEndX(100);
        line.setEndY(200);
        p.getChildren().add(line);

        AnimationTimer timer = new Update();
        timer.start();
    }

    private void mouseTracking (Scene scene) {
        scene.addEventFilter(MouseEvent.MOUSE_MOVED, e -> {
            mousex = e.getX();
            mousey = e.getY();
        });
    }

    public static void main(String[] args) {
        launch();
    }
}
import javafx.scene.shape.Line;

public class Ray {
    Line thisRay;
    double theta;
    double strength;

    Ray (int x, int y, double theta, int strength) {
        this.theta = theta;
        this.strength = strength;
        thisRay = new Line(x, y, x+(strength * Math.cos(Math.toRadians(theta))), y+(strength * Math.sin(Math.toRadians(theta))));
        thisRay.setStrokeWidth(3);
    }

    public Line getRay() {
        return thisRay;
    }

    public void updateRayOrigin (double x1, double y1) {
        thisRay.setStartX(x1);
        thisRay.setStartY(y1);
        thisRay.setEndX(x1 + (strength * Math.cos(Math.toRadians(theta))));
        thisRay.setEndY(y1 + (strength * Math.sin(Math.toRadians(theta))));
    }

    public void updateRayEndPoints (double x2, double y2) {
        thisRay.setEndX(x2);
        thisRay.setEndY(y2);
    }

    public void updateStrength (double updatedStrength) {
        strength = updatedStrength;
        thisRay.setEndX(thisRay.getEndX() + (strength * Math.cos(Math.toRadians(theta))));
        thisRay.setEndY(thisRay.getEndY() + (strength * Math.sin(Math.toRadians(theta))));
    }
}
import javafx.animation.AnimationTimer;

public class Update extends AnimationTimer {
    private long lastUpdate;
    double x1, x2, y1, y2;
    double x3, x4, y3, y4;

    @Override
    public void start() {
        super.start();
    }

    @Override
    public void handle(long now) {
        if (now - lastUpdate >= 1_000_000) {
            for (Ray r : Controller.Rays) {
                x1 = Controller.mousex;
                y1 = Controller.mousey;
                x2 = r.getRay().getEndX();
                y2 = r.getRay().getEndY();

                r.updateRayOrigin(x1, y1);
                x3 = Controller.line.getStartX();
                y3 = Controller.line.getStartY();
                x4 = Controller.line.getEndX();
                y4 = Controller.line.getEndY();
                
                //Gavin answer solution.

                double s1x = x2 - x1;
                double s1y = y2 - y1;
                double s2x = x4 - x3;
                double s2y = y4 - y3;
                double v = -s2x * s1y + s1x * s2y;
                double s = (-s1y * (x1 - x3) + s1x * (y1 - y3)) / v;
                double t = (s2x * (y1 - y3 + s2y * (x1 - x3))) / v;

                if (s >= 0 && s <= 1 && t >= 0) {
                    double intersectionX = x1 + (t * s1x);
                    double intersectionY = y1 + (t * s1y);
                    System.out.println("Detected @: " + intersectionX + "  " + intersectionY);
                }

                //Paul Bourke. comment out the previous solution and comment this one back in
                //if you wish to test it.
//                double denom = ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
//                if (denom == 0) {
//                    continue;
//                }
//                double t = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
//                double u = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
//
//
//                if (!(t < 0 || t > 1 || u < 0 || u > 1)) {
//                    double a = x1 + t * (x2 -x1);
//                    double b = y1 + t * (y2 -y1);
//                    // sticky corners.
//                    //r.updateRayEndPoints(a, b);
//                    //updating strength rather than points method.
//                    r.updateStrength((Math.sqrt(Math.pow(a-x1, 2) + Math.pow(b-y1, 2)))/2);
//                    System.out.println("Detected");
//                }
//                else {
//                    r.updateStrength(500);
//                }
                
           
            }
            lastUpdate = now;
        }
    }
}
java javafx intersection
1个回答
0
投票

我是个白痴,在记录点信息后选择更新射线原点。当我翻转它时,更新端点的 Paul Bourke 就像一个魅力。

我仍然很困惑为什么我必须将斜边除以 2。

© www.soinside.com 2019 - 2024. All rights reserved.