Java &引用;“视线”;用于多边形上的顶点到所有其他多边形顶点

Java &引用;“视线”;用于多边形上的顶点到所有其他多边形顶点,java,javafx,geometry,Java,Javafx,Geometry,我在尝试查找多边形上从多边形上的给定顶点可见的所有顶点时遇到困难。到目前为止,我写的东西只取得了有限的成功 我可以生成可见顶点的光线,但仅当原点不在顶点上时,才可以使用以下命令: private ArrayList<Polyline> getGloballyVisible(Point2D origin, ArrayList<Polygon> polys) { ArrayList<Polyline> visible = new ArrayList<

我在尝试查找多边形上从多边形上的给定顶点可见的所有顶点时遇到困难。到目前为止,我写的东西只取得了有限的成功

我可以生成可见顶点的光线,但仅当原点不在顶点上时,才可以使用以下命令:

private ArrayList<Polyline> getGloballyVisible(Point2D origin, ArrayList<Polygon> polys) {
    ArrayList<Polyline> visible = new ArrayList<>();

    for (Polygon target : polys) {
        ArrayList<Polyline> targetVisibleLines = getVisiblePointsOnPolygon(origin, target);
        ArrayList<Polygon> subTargetPolygons = new ArrayList<>(polys);
        subTargetPolygons.remove(target);
        ArrayList<Polyline> subTargetEdges = getEdges(subTargetPolygons);

        lineCheck: for (Polyline line : targetVisibleLines) {
            for (Polyline enemyLine : subTargetEdges) {
                ArrayList<Point2D> linePoints = toPoints(line.getPoints());
                ArrayList<Point2D> enemyLinePoints = toPoints(enemyLine.getPoints());
                if (linesIntersect(linePoints.get(0), linePoints.get(1), enemyLinePoints.get(0), enemyLinePoints.get(1))) {
                    continue lineCheck;
                }
            }
            visible.add(line);
        }
    }
    return visible;
}
私有ArrayList getGloballyVisible(点2D原点,ArrayList多边形){
ArrayList visible=新的ArrayList();
用于(多边形目标:多边形){
ArrayList targetVisibleLines=getVisiblePointsOnPolygon(原点,目标);
ArrayList子目标多边形=新的ArrayList(多边形);
子目标多边形。移除(目标);
ArrayList SubTargetdGes=GetEdge(subTargetPolygons);
线条检查:用于(多段线线条:targetVisibleLines){
用于(多段线-多段线:子目标页){
ArrayList linePoints=toPoints(line.getPoints());
ArrayList-enemyLinePoints=toPoints(enemyLine.getPoints());
if(linesInterSelect(linePoints.get(0)、linePoints.get(1)、enemyLinePoints.get(0)、enemyLinePoints.get(1))){
继续行检查;
}
}
可见。添加(行);
}
}
返回可见;
}


这是我尝试过的最后一种方法。我相信这种方式很可怕,如果有人能给我指出正确的方向,让它变得不那么可怕,我将不胜感激。

本互动教程可能会有所帮助:


这是一些需要分析的代码,尤其是没有注释的代码。然而,这个问题让我对这个话题感到好奇,所以我读了一些关于它的书,并通过扫描线和对场景所有线段的蛮力检查来玩弄它。有趣的是,结果很好,表现也很好。也许这有助于你了解我是如何做到的:

  • 创建由起点向量和终点向量组成的线(墙)(任何角度的线都可以)
  • 围绕视点创建扫描线
  • 根据场景中的所有行点击测试扫描行
  • 对于每个相交点,找到离视点最近的相交点
  • 连接所有相交点
这是相当容易做到的,特别是当你使用向量计算时

看起来像

截图:

扫描线(蓝色)可见时:

但请记住,这只是针对所有线段的蛮力测试。当然还有优化的空间,比如e。G计算所有线段相对于视点的距离,剪裁线段等。请看@kubuzetto的答案

如果这是您正在寻找的,您可以在找到源代码。在Algorithm.java中为您提供了逻辑和相关信息


附加信息,因为您的代码包含单词“enemyLine”,这让我觉得您需要它来进行游戏:当您简单地将所有交点相加,除以扫描线的数量并移动到目标时,您会自动获得类似的移动。

您是否尝试过任何现有库来完成此工作?也许是这样的:。你正在解决的任务相对来说比较复杂,可能需要很多努力,因此,除非你是出于研究目的,否则我建议你找一些已经做到了这一点的东西。我不想使用现有的实现,因为这是一周内到期的项目的一部分。这很好,虽然不是JavaFX,但是在两个API中都有使用的类(
Line2D
etc),它是一个带有一些调试选项的MCVE(例如绘制所有扫描线的选项):固定的扫描线计数(以及它们之间的固定角度)可能会导致问题。对于距离较大的对象,可能会出现采样错误。根据障碍物的数量,还有一种选择:可以通过从中心到所有线端点的线创建扫描线,并在两个方向上旋转一个小“ε”。这可能看起来还是有点粗糙,但我在中使用了它,它工作得很好。