C# 如何判断点是在直线的右侧还是左侧

C# 如何判断点是在直线的右侧还是左侧,c#,math,geometry,convex-hull,C#,Math,Geometry,Convex Hull,我有一套观点。我想把它们分成两组。为此,我选择两个点(a和b)并在它们之间画一条假想线。现在我想把这条线左边的所有点放在一个集合里,把这条线右边的点放在另一个集合里 对于任何给定的点z,我如何判断它是在左集中还是在右集中?我试图计算a-z-b之间的角度–小于180的角度在右手侧,大于180的角度在左手侧–但是由于ArcCos的定义,计算的角度总是小于180°。是否有计算角度大于180°的公式(或选择右侧或左侧的任何其他公式)?使用向量行列式的符号(AB,AM),其中M(X,Y)是查询点: pos

我有一套观点。我想把它们分成两组。为此,我选择两个点(a和b)并在它们之间画一条假想线。现在我想把这条线左边的所有点放在一个集合里,把这条线右边的点放在另一个集合里


对于任何给定的点z,我如何判断它是在左集中还是在右集中?我试图计算a-z-b之间的角度–小于180的角度在右手侧,大于180的角度在左手侧–但是由于ArcCos的定义,计算的角度总是小于180°。是否有计算角度大于180°的公式(或选择右侧或左侧的任何其他公式)?

使用向量行列式的符号
(AB,AM)
,其中
M(X,Y)
是查询点:

position = sign((Bx - Ax) * (Y - Ay) - (By - Ay) * (X - Ax))
在直线上为
0
,在一侧为
+1
,在另一侧为
-1

使用ab,在与待排序点相同的y坐标处获取直线上的x坐标

  • 如果点的x>线的x,则点位于线的右侧
  • 如果点是 x<直线的x,点在直线的左侧
  • 如果点的x==直线的x,则点位于直线上

    • 你看到的是

      | x2-x1  x3-x1 |
      | y2-y1  y3-y1 |
      
      一侧的点为正,另一侧为负(直线上的点为零)。

      矢量
      (y1-y2,x2-x1)
      垂直于直线,始终指向右侧(或始终指向左侧,如果平面方向与我的方向不同)


      然后,您可以计算该向量的点积和
      (x3-x1,y3-y1)
      ,以确定该点是否与垂直向量(点积>
      0
      )位于直线的同一侧。

      尝试使用以下代码:

      式中a=线点1;b=线点2;c=要检查的点

      如果公式等于0,则点是共线的


      如果直线是水平的,则如果点位于直线上方,则返回true。

      首先检查是否有垂直直线:

      if (x2-x1) == 0
        if x3 < x2
           it's on the left
        if x3 > x2
           it's on the right
        else
           it's on the line
      

      基本上,我认为有一个更简单、更直接的解决方案,对于任何给定的多边形,让我们假设由四个顶点(p1、p2、p3、p4)组成,找到多边形中两个极端相反的顶点,换句话说,找到最左上角的顶点(比如p1)相反的顶点位于最右下角。因此,给定测试点C(x,y),现在必须在C和p1以及C和p4之间进行双重检查:

      如果cx>p1x和cy>p1y==>表示C位于p1的下方和右侧 下一个 如果cx表示C位于p4的左上方

      结论,C在矩形内


      谢谢:)

      我用java实现了这个,并运行了一个单元测试(源代码如下)。上述解决方案都不起作用。此代码通过了单元测试。如果有人发现单元测试没有通过,请告诉我

      代码:注意:nearlyEqual(double,double)如果两个数字非常接近,则返回true

      /*
      *@返回ab c行哪一侧的整数代码。1意味着
      *左转,-1表示右转。退换商品
      *如果三个都在一条线上,则为0
      */
      公共静态int findSide(
      双刃剑,双刃剑,
      双倍bx,双倍bx,
      双cx,双cy){
      if(近似相等(bx-ax,0)){//垂直线
      if(cx日期返回?1:-1;
      }
      如果(cx>bx){
      按>日期返回?-1:1;
      } 
      返回0;
      }
      如果(几乎相等(按ay,0)){//水平线
      if(cyax?-1:1;
      }
      如果(cy>by){
      返回bx>ax?1:-1;
      } 
      返回0;
      }
      双斜率=(by-ay)/(bx-ax);
      双yIntercept=ay-ax*斜率;
      双cSolution=(斜率*cx)+yIntercept;
      如果(坡度!=0){
      if(cy>c解){
      返回bx>ax?1:-1;
      }
      if(cyax?-1:1;
      }
      返回0;
      }
      返回0;
      }
      
      下面是单元测试:

      @Test public void testFindSide(){
      assertTrue(“1”,1==Utility.findSide(1,0,0,0,-1,-1));
      assertTrue(“1.1”,1==Utility.findSide(25,0,0,0,-1,-14));
      assertTrue(“1.2”,1==Utility.findSide(25,20,0,20,-1,6));
      assertTrue(“1.3”,1==Utility.findSide(24,20,-1,20,-2,6));
      assertTrue(“-1”,-1==Utility.findSide(1,0,0,1,1));
      assertTrue(“-1.1”,-1==Utility.findSide(12,0,0,2,1));
      assertTrue(“-1.2”,-1==Utility.findSide(-25,0,0,0,-1,-14));
      assertTrue(“-1.3”,-1==Utility.findSide(1,0.5,0,0,1,1));
      assertTrue(“2.1”,-1==Utility.findSide(0,5,1,10,10,20));
      assertTrue(“2.2”,1==Utility.findSide(0,9.1,1,10,20));
      assertTrue(“2.3”,-1==Utility.findSide(0,5,1,10,20,10));
      assertTrue(“2.4”,-1==Utility.findSide(0,9.1,1,10,20,10));
      assertTrue(“垂直1”,1==Utility.findSide(1,1,1,10,0));
      assertTrue(“垂直2”,-1==Utility.findSide(1,10,1,1,0,0));
      assertTrue(“垂直3”,-1==Utility.findSide(1,1,1,10,5,0));
      assertTrue(“垂直3”,1==Utility.findSide(1,10,1,1,5,0));
      assertTrue(“水平1”,1==Utility.findSide(1,-1,10,-1,0,0));
      assertTrue(“水平2”,-1==Utility.findSide(10,-1,1,0,0));
      assertTrue(“水平3”,-1==Utility.findSide(1,-1,10,-1,0,-9));
      assertTrue(“水平4”,1==Utility.findSide(10,-1,1,-1,0,-9));
      assertTrue(“正斜率1”,1==Utility.findSide(0,0,10,10,1,2));
      assertTrue(“正斜率2”,-1==Utility.findSide(10,10,0,0,1,2));
      assertTrue(“正斜率3”,-1==Utility.findSide(0,0,10,10,1,0));
      
      if (x2-x1) == 0
        if x3 < x2
           it's on the left
        if x3 > x2
           it's on the right
        else
           it's on the line
      
      if m > 0
        if y3 > m*x3 + b
          it's on the left
        else if y3 < m*x3 + b
          it's on the right
        else
          it's on the line
      else if m < 0
        if y3 < m*x3 + b
          it's on the left
        if y3 > m*x3+b
          it's on the right
        else
          it's on the line
      else
        horizontal line; up to you what you do
      
      det = Matrix[
        [(x2 - x1), (x3 - x1)],
        [(y2 - y1), (y3 - y1)]
      ].determinant
      
      (defn is-left? [line point]
        (let [[[x1 y1] [x2 y2]] (sort line)
              [x-pt y-pt] point]
          (> (* (- x2 x1) (- y-pt y1)) (* (- y2 y1) (- x-pt x1)))))
      
      (is-left? [[-3 -1] [3 1]] [0 10])
      true
      
      (is-left? [[3 1] [-3 -1]] [0 10])
      true
      
      (sort line)
      
      (is-left? [[1 1] [3 1]] [10 1])
      false
      
      i*vx + j*ux = T'x
      i*vy + j*uy = T'y
      i*vz + j*uz = T'z
      
      fx = x_2 - x_1
      fy = y_2 - y_1
      
      var torque = fx*(py-y_1)-fy*(px-x_1)
      if  torque>0  then
           "point on left side"
      else if torque <0 then
           "point on right side"  
      else
           "point on line"
      end if
      
      for i in rows:
      
        for j in cols:
      
          if j>m(i-a)+b:
      
            image[i][j]=0