这个问题有点难以制定,所以我首先要展示这张图片:
我想测试点(例如图像上的p1和p2)是否在垂直于其极限线的虚线内。我知道要测试的点的坐标和线的限制。
因此,对于p1,它将是错误的,对于p2,它将是真的。
计算这个计算效率最高的方法是什么?
我正在使用Java中的浮点数。
答案 0 :(得分:3)
使用点积:
可以非常高效地完成此操作如果A
组件并行到B
,则为正,如果反并行,则为负
因此,如果您有一个由点A
和B
定义的线段以及一个测试点P
,那么您只需要两个点积运算来测试:
dot(A - B, P - B) >= 0 && dot(B - A, P - A) >= 0
编辑:图解说明:
点积可以显示为:
因此,如果θ > 90
然后dot(A, B) < 0
,反之亦然。现在为您解决问题:
在案例1中,当dot(A - B, P - B) > 0
时我们说P
位于B
虚线的正确一侧,反之亦然。通过对称我们可以做A
处的相同操作,通过交换A
和B
。
答案 1 :(得分:0)
如果测试点(tp)与范围的起点(sp)和终点(ep)一起形成一个钝角三角形,你可以断定它超出了范围。
https://en.wikipedia.org/wiki/Acute_and_obtuse_triangles
特殊情况是tp与sp和ep相同,然后计算2个距离:
如果这两个距离的总和= sp和ep之间的距离,那么tp在范围内,否则它超出范围。
答案 2 :(得分:0)
最好的方法是首先创建一个矩形 Rect ( android.graphics 包),x和width是行的开头和结尾,y和高度是屏幕高度的开始和结束。 然后使用 Rect 方法 Rect.contains(int x,int y) 来检查点坐标是否存在内。
对于浮点数,请改用 RectF 类。
答案 3 :(得分:0)
这种方法涉及使用2D矢量(无论如何应该使用它,使得在任何坐标系统中工作都更容易)和点(标量)产品。它不需要任何相对昂贵的操作,如平方根或三角函数,因此非常高效。
让A
和B
成为线段的起点和终点(按点我的意思是表示2D空间中的位置的矢量),以任何顺序排列。如果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
}
答案 4 :(得分:0)
让我们说, x1 是该行的开头, x2 是结束。然后 ax 是水平平面中的点;垂直计划中的 y1 , y2 和 ay 。
if((ax&gt; = x1&amp;&amp; ax&lt; = x2)&amp;&amp;(ay&gt; = y1&amp;&amp; ay&lt; = y2)){//做你的工作 }
答案 5 :(得分:0)
已经有一些答案,但还有另一种解决方案可以为您提供点垂直于线段的单位距离。
其中,行为x1
,y1
为x2
,y2
,点为px
,py
从行开始到结束找到向量
vx = x2 - x1;
vy = y2 - y1;
从行开始(或结束)到点
的向量vpx = px - x1;
vpy = py - y1;
然后将两个向量的点积除以线的长度平方。
unitDist = (vx * vpx + vy * vpy) / (vx * vx + vy * vy);
如果垂直截距位于线段上,则unitDist
将为0 <= unitDist <= 1
缩写形式
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);
如果您使用点通过使用最小距离来确定所选行,则可以使用一个点进行选择。
答案 6 :(得分:0)
使用复数可以很好地解决这个问题。
让a
和b
段的端点。我们使用将原点0
映射到a
并将点1
映射到b
的转换。这种转变是相似的,它的表达只是
p = (b - a) q + a
您可以通过替换q=0
或q=1
进行验证。它将垂直于给定段的整个条纹映射到垂直于段0-1
的条带。
现在逆变换显然是
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)².