Java 获取直线和形状的交点

Java 获取直线和形状的交点,java,math,geometry,computational-geometry,java-2d,Java,Math,Geometry,Computational Geometry,Java 2d,我有一个自定义形状,如图所示。 假设图像中覆盖形状的蓝色矩形描绘了该形状的边界框 如果我在边界矩形的对角线上画一条线,如何获得交点(在图像中它们是用绿色绘制的)? 我使用的是Java2D,我有一个通用路径,其中包含我在屏幕上绘制形状的所有坐标 遍历定义形状的点列表。将(x,y)放在直线方程中,看看它是否“解”。伪码 int threshold = 0.01 for point in points: if (point.y - m * point.x + c)^2 < threshol

我有一个自定义形状,如图所示。 假设图像中覆盖形状的蓝色矩形描绘了该形状的边界框

如果我在边界矩形的对角线上画一条线,如何获得交点(在图像中它们是用绿色绘制的)?

我使用的是Java2D,我有一个通用路径,其中包含我在屏幕上绘制形状的所有坐标


遍历定义形状的点列表。将(x,y)放在直线方程中,看看它是否“解”。伪码

int threshold = 0.01
for point in points: 
  if (point.y - m * point.x + c)^2 < threshold : 
    print "solution found" 
int阈值=0.01
对于点到点:
如果(点y-m*点x+c)^2<阈值:
打印“找到解决方案”
Idea 您可以使用getPathIterator()方法将GenenralPath解构为其段(移动到、直线到、四边到、立方到、闭合)。现在,您可以搜索每条线段与直线的交点

public static Point[] getIntersections(Path path, Line line) {
    List<Point> intersections = new ArrayList<Point>();
    PathIterator it = path.getPathIterator();
    double[] coords = new double[6];
    double[] pos = new double[2];
    while (!it.isDone()) {
        int type = it.currentSegment(coords);
        switch (type) {
        case PathIterator.SEG_MOVETO:
            pos[0] = coords[0];
            pos[1] = coords[1];
            break;
        case PathIterator.SEG_LINETO:
            Line l = new Line(pos[0], pos[1], coords[0], coords[1]);
            pos[0] = coords[0];
            pos[1] = coords[1];
            Point intersection = getIntersection(line, l);
            if (intersection != null)
                intersections.add(intersection);
            break;
        //...
        default:
            throw new IllegalStateException("unknown PathIterator segment type: " + type);
        }
        it.next();
    }
    return intersections.toArray(new Point[] {});
}
公共静态点[]获取交叉点(路径、直线){
列表交点=新的ArrayList();
PathIterator it=path.getPathIterator();
双[]坐标=新双[6];
double[]pos=新的double[2];
而(!it.isDone()){
int type=it.currentSegment(coords);
开关(类型){
案例PathIterator.SEG_MOVETO:
pos[0]=坐标[0];
位置[1]=坐标[1];
打破
案例PathIterator.SEG_LINETO:
l行=新行(位置[0],位置[1],坐标[0],坐标[1]);
pos[0]=坐标[0];
位置[1]=坐标[1];
点交点=点交点(直线,l);
if(交叉点!=null)
交叉点。添加(交叉点);
打破
//...
违约:
抛出新的IllegalStateException(“未知的PathIterator段类型:“+type”);
}
it.next();
}
返回交叉点。toArray(新点[]{});
}
线路/线路交点 例如,可以使用向量代数直接计算直线/直线交点:

  • 二维点/线由三维矢量(x、y、w)表示
  • 点(x,y)由(x,y,1)表示
  • 通过点p1和p2的线由p1 x p2(叉积)给出
  • 对于两条直线l1=(a,b,c)和l2=(d,e,f),交点由l1 x l2(叉积)给出
  • 要将交点投影为二维,必须将x和y坐标除以w
  • 如果w=0,则不存在单交点
直线/贝塞尔交点 路径可以包含二次和三次贝塞尔曲线。要查找直线和贝塞尔曲线之间的交点,有几种算法可用,例如:

  • 德卡斯特卢分区
  • 贝塞尔剪裁
  • 牛顿法
  • 多项式求根
De Casteljau细分易于实施,但在相对罕见的情况下存在一些问题。如果您不想使用可以为您计算交点的数学库,我建议实施de Casteljau细分


编辑:另一种替代方法是通过若干线段近似路径的贝塞尔曲线段。然后你只需要找到直线/直线交点。

@Mihir这些是直线的参数@我不知道;我不太记得数学了,我有线x1,y1和x2,y2,你能给我一个例子吗?我怎么能把这两个线点转换成线参数?@Mihir当然:你需要这样使用它:x1*x+y1*y=x2+y2然后你去解释y。y1*y=x2+y2-x1*x,然后除以y1,最后的答案是:y=(x2/y1+y2/y1)-(x1/y1)*x,在第一个()中,你找到了c,在第二个()中,你找到了mI,我不认为这个答案很有用。测试形状的所有点都很昂贵。@matthia是真的!如果可以在形状两侧的直线上找到两点,则可以使用二进制搜索。我将其返回-1到0,因为这可能是解决方案的基础。顺便说一句,根据评论,我建议您检查基本几何,我不想因为缺乏记忆而责怪您,但如果您使用几何,如果重复操作,确实可以节省大量时间。这里有一个很好的开始:@csbalazs.i将刷新。getcrossion方法在哪里?@Mihir,你必须自己编写该方法。它应该计算两条线段的交点。