如果我们有一个线段(A.x, A.y, B.x, B.y)
和一个点(C.x, C.y)
,我如何分辨该点在该线段的左侧还是右侧,顶部还是底部?我尝试过以前文章中涉及跨产品的解决方案,但这使我遇到了另一个问题。使用叉积使得A和B的顺序重要。还有什么其他方法可以使A和B的顺序无关紧要?
以前帖子的解决方案:
使用向量的行列式(AB,AM)的符号,其中M(X,Y)是查询点:
position = sign((Bx - Ax) * (Y - Ay) - (By - Ay) * (X - Ax))
在线上为0,一侧为+1,另一侧为-1。
来源:How to tell whether a point is to the right or left side of a line
((我假设笛卡尔坐标系的正x和y分别指向右边和上面)
给出一条通过点(a,b),(c,d)的线,其方程为:
现在您有一个要点(e,f)。如果用x = e,y = f代替,并且它们满足方程式,则表示该点在直线上。如果方程式的左侧较大,则意味着您的点在直线的左/上。如果方程式的右侧较大,则意味着您的点在直线的右侧/底部。
请注意,在特殊情况下,您需要处理垂直线。
在Java中,
double lhs = e;
double gradient = (b - d)/(a - c);
if (Double.isInfinite(gradient)) {
// vertical line, compare only x coordinates
if (e < a) {
// on the left
} else if (e > a) {
// on the right
} else {
// on the line
}
}
double rhs = (gradient * (e - a)) + b;
if (lhs > rhs) {
// on the left/top
} else if (lhs < rhs) {
// on the right/bottom
} else {
// on the line
}
为了证明重新排列点的顺序不会改变结果,这非常简单。更改点的顺序会生成此等式(a更改为c,b更改为d):
如果同时展开上面的方程式和一个方程式,您将发现它们实际上是相同的方程式,即: