从A点到B点画一条线。让d偏移。让C指向要测试。
我将使用偏移量对该线进行一种命中测试。
如何围绕具有给定偏移的线进行命中测试。
Ex:A =(10,10),B(30,30),偏移= 2.选择C作为任意点。请参阅链接中的图片。
http://s10.postimg.org/6by2dzvax/reference.png
请帮帮我。
提前致谢。
答案 0 :(得分:0)
查找C的偏移量 例如dx1和dy1。如果dy1 / dx1 = dy / dx,则你的C击中该线。 对于段,您还应检查是否dx1< dx或dy1< DY
答案 1 :(得分:0)
换句话说,您要检查该点C
是否位于特定矩形内,尺寸为2*d
和|A-B|+2*d
。
您需要将该行表示为u*x+v*y+w=0
,这可以通过
u = A.y-B.y
v = B.x-A.x
w = A.x*B.y - A.y * B.x
然后C
与该行的(签名)距离为
d = (u*C.x + v*C.y +w) / sqrt( u*u+v*v)
您将abs(d)
与偏移量进行比较。
下一步是检查C
在线方向上的位置。为此,您将正交线u2*x+v2*y+w2=0
与
u2 = v
v2 = -u
w2 = -u2*(A.x+B.x)/2 - v2*(A.y+B.y)/2
和距离
d2 = (u2 * C.x + v2 * C.y + w2 ) / sqrt( u2*u2+v2*v2 )
必须将此距离与线的长度+偏移量进行比较:
abs(d2) < |A-B| / 2 + offset
答案 2 :(得分:0)
一个方便的技巧是旋转和平移平面,使得AB
段映射到段(0, 0)-(0, L)
(就像在图像上一样),L
是段长度。
如果将相同的变换应用于C
,那么在矩形中测试包含是一件非常简单的事情。
有用的转换由:
给出x = ((X - XA).(XB - XA) + (Y - YA).(YB - YA)) / L
y = ((X - XA).(YB - YA) - (Y - YA).(XB - XA)) / L
答案 3 :(得分:0)
也许您可以使用此功能来计算点到线的最短距离。如果距离是&lt; = offset,则该点击中该线。
private double pointDistanceToLine(PointF line1, PointF line2, PointF pt)
{
var isValid = false;
PointF r = new PointF();
if (line1.Y == line2.Y && line1.X == line2.X)
line1.Y -= 0.00001f;
double U = ((pt.Y - line1.Y ) * (line2.Y - line1.Y )) + ((pt.X - line1.X) * (line2.X - line1.X));
double Udenom = Math.Pow(line2.Y - line1.Y , 2) + Math.Pow(line2.X - line1.X, 2);
U /= Udenom;
r.Y = (float)(line1.Y + (U * (line2.Y - line1.Y ))); r.X = (float)(line1.X + (U * (line2.X - line1.X)));
double minX, maxX, minY , maxY ;
minX = Math.Min(line1.Y , line2.Y );
maxX = Math.Max(line1.Y , line2.Y );
minY = Math.Min(line1.X, line2.X);
maxY = Math.Max(line1.X, line2.X);
isValid = (r.Y >= minX && r.Y <= maxX) && (r.X >= minY && r.X <= maxY );
//return isValid ? r : null;
if (isValid)
{
double result = Math.Pow((pt.X - r.X), 2) + Math.Pow((pt.Y - r.Y), 2);
result = Math.Sqrt(result);
return result;
}
else {
double result1 = Math.Pow((pt.X - line1.X), 2) + Math.Pow((pt.Y - line1.Y), 2);
result1 = Math.Sqrt(result1);
double result2 = Math.Pow((pt.X - line2.X), 2) + Math.Pow((pt.Y - line2.Y), 2);
result2 = Math.Sqrt(result2);
return Math.Min(result1, result2);
}
}