检查线是否位于多边形内部

时间:2015-08-07 22:28:56

标签: geometry polygon computational-geometry

在我的问题中,我有一条传送带,一条行李在逆时针方向上移动(每次在行李箱旁移动时左侧都在里面)。我知道有一条线可能位于传送带内。传送带由线路建模,包括起点和终点以及要检查的线路。要检查的生产线的起点等于其中一条输送带的线的起点(输送带是一个简单的多边形)。我的方法是检查这个点周围的顺时针角度(从作为传送带一部分的线开始)是否大于180度(比它在内部),但这并不适用于所有情况。我可以通过在前一个起始点(传送带的前一行)旁边放置线来减少故障的数量,但仍有一些情况下这不起作用。

感谢您的帮助,如果可以的话,我会提供所需的任何进一步信息。

编辑: 它适用于以下,alpha为333度但beta仅为171;因此,蓝线位于(黑色)传送带之外:enter image description here

然而,它不适用于其他示例。想象一下右侧的这个图像的上半部分(看起来就像一座城堡;),一条从蓝色右边的点开始到右上角的线(将是坐标(3,2)),具有小于180(145)的alpha值,因此它被认为是在外面,虽然它实际上在里面。

2 个答案:

答案 0 :(得分:1)

如果我理解,你想检查一个线段是否完全位于任意多边形内。

首先转换线段使其成为(0, 0)-(L, 0);这需要翻译和旋转(你也可以缩放到(0, 0)-(1, 0));将相同的变换应用于多边形。

查找多边形边与X轴的所有交点(它们由条件Yi > 0 != Yi+1 > 0检测)。如果有0 < X < L的任何交集,则报告错误。否则,如果交叉点的数量为X < 0为奇数,则报告为真。

Yi=0X=0X=L的堕落案例。在您可以调整算法以正确处理它们之前,由您自行决定“内部”是否成立。

答案 1 :(得分:0)

我建议您查看确定点是否位于Paul Bourke's amazing website上的多边形内部

point in poly method 1

point in poly method 2

我想象确定一条线是否在多边形内是否相同,检查两个点是否位于多边形内(例如,如果第一个点不在多边形内,则检查第二个点没有点)。 p>

<强>更新 根据您更新的问题,这里有一些图片来解释评论中解释的天真算法:

  1. 找到线条的角度
  2. 旋转坐标系,使线条水平
  3. 检查形状点(标记为绿色)是否高于或低于此(现在水平)线:上面表示线在外面,下面表示线在里面
  4. step1

    step2

    我说天真的方法,因为你会检查你的线坐标之间的每一个形状点,我不确定它会有多高效。

    类似的方法可能是这样的:

    1. 计算线的角度
    2. 表示线的起点/终点之间的每个形状点
    3. 检查开始和当前形状点之间的直线角度
    4. 如果角度较小,则线条在形状之外,退出循环,否则,继续测试
    5. 偏离主题但很有趣,这里是顶部的想法片段:在poly中测试一行:

      var numPts = 32;
      var pts = [];
      var hlh = 30;//half line height
      
      function setup(){
        createCanvas(400,400);
        var ai = TWO_PI/numPts;
        for(var i = 0 ; i < numPts ; i++) pts.push(createVector(200+cos(ai*i)*random(100,150),200+sin(ai*i)*random(100,150)));  
      }
      function draw(){
        background(255);
        fill(0,(lineInPoly(mouseX,mouseY-hlh,mouseX,mouseY-hlh,pts) ? 192 : 0),0);
        beginShape();
        for(var i = 0 ; i < numPts ; i++) vertex(pts[i].x,pts[i].y);
        endShape(CLOSE);
        line(mouseX,mouseY-hlh,mouseX,mouseY+hlh);
      }
      function pointInPoly(x, y,pts)
      {
        var i, j,npol = pts.length;
        var c = false; 
        for (i = 0, j = npol-1; i < npol; j = i++) {
          var p0 = pts[i];
          var p1 = pts[j];
          if ((((p0.y <= y) && (y < p1.y)) ||
               ((p1.y <= y) && (y < p0.y))) &&
              (x < (p1.x - p0.x) * (y - p0.y) / (p1.y - p0.y) + p0.x))
            c = !c;
        }
        return c;
      }
      function lineInPoly(x1,y1,x2,y2,pts){
        var isFirstInPoly = pointInPoly(x1,y1,pts);
        if(isFirstInPoly){
          return (isFirstInPoly && pointInPoly(x2,y2,pts));
        }else return false;
      }
      /*
      based on Paul Bourke's solution http://paulbourke.net/geometry/polygonmesh/
      int pnpoly(int npol, float *xp, float *yp, float x, float y)
          {
            int i, j, c = 0;
            for (i = 0, j = npol-1; i < npol; j = i++) {
              if ((((yp[i] <= y) && (y < yp[j])) ||
                   ((yp[j] <= y) && (y < yp[i]))) &&
                  (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
                c = !c;
            }
            return c;
          }
      */
      <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.7/p5.min.js"></script>

相关问题