Java 测试点是否在二维空间上的线范围内
这个问题有点难以解释,因此我将首先展示以下图片: 我想测试点(如图像上的p1和p2)是否在虚线范围内,这些虚线在其极限处垂直于该线。我知道要测试的点的坐标和线的极限 所以对于p1,它是假的,而对于p2,它是真的 计算这个的最有效的方法是什么 我正在使用Java中的浮点运算。如果要测试的点(tp)与范围的起点(sp)和终点(ep)一起形成一个钝角三角形,则可以断定它超出范围 特殊情况是tp与sp和ep的坡度相同,然后计算2个距离:Java 测试点是否在二维空间上的线范围内,java,algorithm,math,geometry,Java,Algorithm,Math,Geometry,这个问题有点难以解释,因此我将首先展示以下图片: 我想测试点(如图像上的p1和p2)是否在虚线范围内,这些虚线在其极限处垂直于该线。我知道要测试的点的坐标和线的极限 所以对于p1,它是假的,而对于p2,它是真的 计算这个的最有效的方法是什么 我正在使用Java中的浮点运算。如果要测试的点(tp)与范围的起点(sp)和终点(ep)一起形成一个钝角三角形,则可以断定它超出范围 特殊情况是tp与sp和ep的坡度相同,然后计算2个距离: distSpAndTp-sp和tp之间的距离 distEpA
- distSpAndTp-sp和tp之间的距离
- distEpAndTp-ep和tp之间的距离
- distSpAndTp-sp和tp之间的距离
- distEpAndTp-ep和tp之间的距离
如果这两个距离之和=sp和ep之间的距离,则tp在范围内,否则超出范围。最好的方法是首先创建一个矩形Rect(android.graphics package),x和宽度是行的开始和结束,y和高度是屏幕高度的开始和结束。 然后使用Rect方法Rect.contains(int x,int y)检查点坐标是否在范围内
对于浮动,请改用RectF类。最好的方法是首先创建一个矩形Rect(android.graphics package),x和宽度是行的开始和结束,y和高度是屏幕高度的开始和结束。 然后使用Rect方法Rect.contains(int x,int y)检查点坐标是否在范围内
对于浮点数,请改用RectF类。这可以通过点积非常有效地完成: 如果
A
有一个与B
平行的分量,则为正,如果反平行,则为负
因此,如果您有一条由点a
和B
定义的线段,以及一个测试点p
,则您只需要两个点积操作即可进行测试:
dot(A-B,p-B)>=0&&dot(B-A,p-A)>=0
编辑:图形说明: dot产品可以显示为: 因此,如果
θ>90
,则点(A,B)<0
,反之亦然。现在谈谈你的问题:
在案例1中,当
dot(A-B,p-B)>0
时,我们说p
位于B
虚线的正确一侧,反之亦然。通过对称,我们可以在A
处执行相同的操作,通过交换A
和B
这可以非常有效地使用点积完成:
如果A
有一个与B
平行的分量,则为正,如果反平行,则为负
因此,如果您有一条由点a
和B
定义的线段,以及一个测试点p
,则您只需要两个点积操作即可进行测试:
dot(A-B,p-B)>=0&&dot(B-A,p-A)>=0
编辑:图形说明: dot产品可以显示为: 因此,如果
θ>90
,则点(A,B)<0
,反之亦然。现在谈谈你的问题:
在案例1中,当
dot(A-B,p-B)>0
时,我们说p
位于B
虚线的正确一侧,反之亦然。通过对称,我们可以在A
上执行相同的操作,通过交换A
和B
这种方法涉及到使用2D向量(无论如何,您应该使用它,使在任何坐标系下工作都更容易)和点(标量)积。它不需要任何相对昂贵的操作,如平方根或三角函数,因此性能非常好
让A
和B
以任意顺序作为线段的起点和终点(点指代表二维空间中位置的向量)。如果P
是测试点,则:
- 如果
和dot(PA,AB)
具有相同的符号,则该点位于该区域之外(如示例中的dot(PB,AB)
)p1
- 如果上面的点积有相反的符号,则点位于区域内(如
)p2
PA=A-p
,PB=B-p
和AB=B-A
这种情况可以推测如下:
if dot(PA, AB) * dot(PB, AB) <= 0 {
// Opposite signs, inside region
// If the product is equal to zero, the point is on one of the dotted lines
}
else {
// Same signs, outside region
}
if-dot(PA,AB)*dot(PB,AB)这种方法包括使用2D向量(无论如何,您都应该使用2D向量,这使得在任何坐标系下工作都更容易)和dot(标量)乘积。它不需要任何相对昂贵的操作,如平方根或三角函数,因此性能非常好
让A
和B
以任意顺序作为线段的起点和终点(点指代表二维空间中位置的向量)。如果P
是测试点,则:
- 如果
dot(PA,AB)
和dot(PB,AB)
具有相同的符号,则该点位于区域之外(如exa中的p1
)
vx = x2 - x1;
vy = y2 - y1;
vpx = px - x1;
vpy = py - y1;
unitDist = (vx * vpx + vy * vpy) / (vx * vx + vy * vy);
x2 -= x1;
y2 -= y1;
unitDist = (x2 * (px - x1) + y2 * (py - y1)) / (x2^2 + y2^2);
if (unitDist >= 0 && unitDist <= 1) {
// point px,py perpendicular to line segment x1,y1,x2,y2
}
p2x = vx * unitDist + x1;
p2y = vy * unitDist + y1;
dist = hypot(p2x - px, p2y - py);
p = (b - a) q + a
q = (p - a) / (b - a),
0 <= Re((p - a) / (b - a)) <= 1.
0 <= Re((p - a) (b - a)*) <= |b-a|²
0 <= (px - ax)(bx - ax) + (py - ay)(by - ay) <= (bx - ax)² + (by - ay)².