【问题标题】:How can I check if a point is below a line or not ?如何检查一个点是否低于一条线?
【发布时间】:2011-04-19 19:03:55
【问题描述】:

如何检查一个点是否低于一条线?

我有以下数据:

Line [ {x1,y1}, {x2,y2} ]
Points {xA,yA}, {xB,yB} ...

我需要在python中编写一个小算法来检测线的一侧和另一侧的点。

谢谢

【问题讨论】:

    标签: python math geometry line


    【解决方案1】:

    感谢Edmund 的解决方案,我为该行编写了一个模块来计算这个和其他一些用c++ 实现的简单行操作,运行速度非常快。你可以通过pip安装FastLine,然后这样使用:

    from FastLine import Line
    # define a line by two points
    l1 = Line(p1=(0,0), p2=(10,10))
    # define a line by its slope and intercept
    l2 = Line(m=4, b=-1)
    
    >>> l1.crossed_by((20,50)) # specific side
    1
    >>> l1.crossed_by((50,50)) # on the line
    0
    >>> l1.crossed_by((-20,-50)) # opposite side
    -1
    

    【讨论】:

      【解决方案2】:

      您可以尝试使用叉积 -- http://en.wikipedia.org/wiki/Cross_product

      v1 = (x2-x1, y2-y1)   # Vector 1
      v2 = (x2-xA, y2-yA)   # Vector 2
      xp = v1[0]*v2[1] - v1[1]*v2[0]  # Cross product
      if xp > 0:
          print('on one side')
      elif xp < 0:
          print('on the other')
      else:
          print('on the same line!')
      

      您需要校准每一面的内容。如果您希望它位于“下方”或“上方”,则需要确保线上的点是水平排序的。

      我还没有测试过。

      编辑我最初输入了点积公式。 :o

      编辑 2 哦,我将坐标放入集合而不是元组。如果您运行的是相当现代的 Python 版本,则将 namedtuple('point', 'x y') 用于向量会很好。

      幸运的是我找到了Calculating a 2D Vector's Cross Product

      【讨论】:

      • 如果 xp 为 0.00000000000000000000000000001(可能是由于浮点表示)怎么办?那这个点是不是真的就行了呢? (可能想与某个 epsilon 进行比较,而不是 0.0)
      • 好点!虽然我不知道你如何找到最合适的 epsilon 值。
      • cos(π/2) 应该计算为 0,但我系统上的 math.cos(math.pi/2) 给出了 6.1230317691118863e-017,所以我猜 1e-151e-16 范围内的 epsilon 大约是正确的. (将其放入您自己的常量 EPS 中,这样您就可以轻松地调整它,只需在一个地方进行调整,而不是在您进行浮点比较的任何地方进行调整。)
      • 或者,如果您使用的是 Python 3.x,则可以使用 unicode ε 作为 epsilon 的变量名。
      • 嗨。我试图运行代码。但有一次,我遇到了一个错误。错误消息说“设置对象没有属性 x”。也就是说,它不能访问向量的 x 和 y 元素。有什么解决办法吗?
      【解决方案3】:

      你可以尝试使用叉积,但诀窍是如何选择点来形成一个向量,这里我从点中选择最近的点,假设我得到了 pointA(你可以公平地循环点来计算与循环的距离指向线):

      v1 = {x2-x1, y2-y1}   # Vector 1
      v2 = {xA-x1, yA-y1}   # Vector 2
      cross_product = v1.x*v2.y - v1.y*v2.x
      if cross_product > 0:
          print 'pointA is on the counter-clockwise side of line'
      elif cross_product < 0:
          print 'pointA is on the clockwise side of line'
      else:
          print 'pointA is exactly on the line'
      

      【讨论】:

        【解决方案4】:

        假设您给出了 2 个点 A、B,并且您想知道第三个点 C 位于哪个 halfplane。作为标准的术语“下方”和“上方”非常模糊,因此您需要一个参考点,例如原点。只需确保此参考点与 A 和 B 不共线即可。

        您现在拥有的是一个三角形(A、B、C)。使用行列式,您可以计算有符号面积(see herehere)。这里唯一有趣的是记住这个标志。

        下一步:对于给定的点 D,计算三角形的有符号面积(A,B,D)。如果结果与参考三角形的区域具有相同的符号-> C 和 D 在 (A, B) 的同一侧。如果符号不同 -> C 和 D 位于线的相对两侧。如果 (A, B, D) 的面积为 0,则 A、B 和 D 共线。注意:使用 Python 内置 cmp 来比较三角形区域。

        【讨论】:

          猜你喜欢
          • 2011-04-18
          • 2014-01-20
          • 1970-01-01
          • 1970-01-01
          • 2010-10-28
          • 1970-01-01
          • 2012-08-08
          • 2016-01-14
          相关资源
          最近更新 更多