【问题标题】:Checking to see if 3 points are on the same line检查 3 个点是否在同一条线上
【发布时间】:2011-04-18 08:09:41
【问题描述】:

我想知道一段代码,它实际上可以告诉我 2D 空间中的 3 个点是否在同一条线上。伪代码也足够了,但 Python 更好。

【问题讨论】:

  • 你的线是怎么定义的?二维平面上的函数?
  • 你到底得到了什么?三分?还是三点和一条线?

标签: pseudocode


【解决方案1】:

这是 C++,但你可以将它改编成 python:

bool collinear(int x1, int y1, int x2, int y2, int x3, int y3) {
  return (y1 - y2) * (x1 - x3) == (y1 - y3) * (x1 - x2);
}

基本上,我们正在检查点 1 和点 2 以及点 1 和点 3 之间的斜率是否匹配。斜率是 y 的变化除以 x 的变化,所以我们有:

y1 - y2     y1 - y3
-------  =  --------
x1 - x2     x1 - x3

交叉乘法得到(y1 - y2) * (x1 - x3) == (y1 - y3) * (x1 - x2);

注意,如果您使用双打,您可以检查一个 epsilon:

bool collinear(double x1, double y1, double x2, double y2, double x3, double y3) {
  return fabs((y1 - y2) * (x1 - x3) - (y1 - y3) * (x1 - x2)) <= 1e-9;
}

【讨论】:

  • @dtb - 我添加了解释,如果您还有问题,请告诉我。
  • 不错的把戏。但是,检查浮点数是否相等并不安全。您可以根据预定义的阈值测试绝对差异,该阈值取决于您想要达到的分辨率(灵敏度)
  • 不能一斜一负吗?我认为你应该比较它们的绝对值。
  • @dtb - x1==x2 工作正常,考虑以下情况: collinear(-2,0,-2,1,-1,1) 返回 false,而 collinear(-2,0, -2,1,-2,2) 返回真。我认为极端情况已经涵盖,如果您不同意,请告诉我。
  • 这需要比@florin 的答案更少的计算,即使它是等效的(所以我投票赞成)。
【解决方案2】:

阅读this,并用它找到通过前两点的直线方程。按照说明查找mb。然后对于您的第三点,计算mx + b - y。如果结果为零,则第三个点与前两个点在同一条线上。

【讨论】:

    【解决方案3】:

    规则 1:在任何线性二维空间中,两点总是在同一条线上。

    取 2 个点并建立一个表示穿过它们的线的方程。 然后检查第三个点是否也在该线上。

    祝你好运。

    【讨论】:

      【解决方案4】:

      可以检查ABC三角形的面积是否为0:

      [ Ax * (By - Cy) + Bx * (Cy - Ay) + Cx * (Ay - By) ] / 2
      

      当然,您实际上不需要除以 2。

      【讨论】:

      • 这样好很多,因为没有被0除的风险。
      • 只是指出一些事情......这在数学上等同于@dcp 上面的答案(如果您忽略/2),但检查面积是否为0 可以更容易地添加容差。 ..(即stuff &lt; err_tolerance 而不是stuff1 == stuff2 就像上面的@dcp 所做的那样)
      • +1 在数学上是相同的,但概念更简单/直观/直截了当(我喜欢它)。
      • @Hossein:你问的是绝对值还是符号?有了你的分数和我的公式,我得到-510。该符号表示您选择了一定的点顺序。您可以将 A 与 C 或 B 交换,您会得到一个正区域,即使它是同一个三角形。
      • @Joe Kington:(1)你需要做-tolerance == 更改为 - 进行调整,需要 2 次乘法和 5 次减法才能给出“应该为零”的结果。我会给@dcp打勾,而不是@florin。
      【解决方案5】:

      y - y0 = a(x-x0) (1) 而a = (y1 - y0)/(x1 - x0)A(x0, y0) B(x1, y1) C(x2, y2)。查看C 是否满足 (1)。您只需替换适当的值。

      Details

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-19
        • 1970-01-01
        • 2016-07-02
        • 2014-01-20
        • 1970-01-01
        • 2017-12-28
        相关资源
        最近更新 更多