检查 3 个点是不是在同一条线上
Posted
技术标签:
【中文标题】检查 3 个点是不是在同一条线上【英文标题】:Checking to see if 3 points are on the same line检查 3 个点是否在同一条线上 【发布时间】:2011-04-18 08:09:41 【问题描述】:我想知道一段代码,它实际上可以告诉我 2D 空间中的 3 个点是否在同一条线上。伪代码也足够了,但 Python 更好。
【问题讨论】:
你的线是怎么定义的?二维平面上的函数? 你到底得到了什么?三分?还是三点和一条线? 【参考方案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,并用它找到通过前两点的直线方程。按照说明查找m
和b
。然后对于您的第三点,计算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 < 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
【讨论】:
以上是关于检查 3 个点是不是在同一条线上的主要内容,如果未能解决你的问题,请参考以下文章
Educational Codeforces Round 41