Ecl*_*pse 29
在最简单的形式中,只需将坐标插入线方程并检查是否相等.
鉴于:
Point p (X=4, Y=5)
Line l (Slope=1, YIntersect=1)
Run Code Online (Sandbox Code Playgroud)
插入X和Y:
Y = Slope * X + YIntersect
=> 5 = 1 * 4 + 1
=> 5 = 5
Run Code Online (Sandbox Code Playgroud)
所以,是的,重点是在线.
如果您的线条以(X1,Y1),(X2,Y2)形式表示,那么您可以使用以下公式计算坡度:
Slope = (y1 - y2) / (x1-x2)
Run Code Online (Sandbox Code Playgroud)
然后得到Y-Intersect:
YIntersect = - Slope * X1 + Y1;
Run Code Online (Sandbox Code Playgroud)
编辑:我修复了Y-Intersect(已经是X1/Y1 ...)
你必须检查x1 - x2
不是0
.如果是,那么检查点是否在线是一个简单的问题,检查你的点中的Y值是否等于x1
或x2
.另外,检查点的X不是'x1'或'x2'.
Rob*_*son 24
我刚刚写了一个函数来处理一些额外的要求,因为我在绘图应用程序中使用了这个检查:
private const double SELECTION_FUZZINESS = 3;
internal override bool ContainsPoint(Point point)
{
LineGeometry lineGeo = geometry as LineGeometry;
Point leftPoint;
Point rightPoint;
// Normalize start/end to left right to make the offset calc simpler.
if (lineGeo.StartPoint.X <= lineGeo.EndPoint.X)
{
leftPoint = lineGeo.StartPoint;
rightPoint = lineGeo.EndPoint;
}
else
{
leftPoint = lineGeo.EndPoint;
rightPoint = lineGeo.StartPoint;
}
// If point is out of bounds, no need to do further checks.
if (point.X + SELECTION_FUZZINESS < leftPoint.X || rightPoint.X < point.X - SELECTION_FUZZINESS)
return false;
else if (point.Y + SELECTION_FUZZINESS < Math.Min(leftPoint.Y, rightPoint.Y) || Math.Max(leftPoint.Y, rightPoint.Y) < point.Y - SELECTION_FUZZINESS)
return false;
double deltaX = rightPoint.X - leftPoint.X;
double deltaY = rightPoint.Y - leftPoint.Y;
// If the line is straight, the earlier boundary check is enough to determine that the point is on the line.
// Also prevents division by zero exceptions.
if (deltaX == 0 || deltaY == 0)
return true;
double slope = deltaY / deltaX;
double offset = leftPoint.Y - leftPoint.X * slope;
double calculatedY = point.X * slope + offset;
// Check calculated Y matches the points Y coord with some easing.
bool lineContains = point.Y - SELECTION_FUZZINESS <= calculatedY && calculatedY <= point.Y + SELECTION_FUZZINESS;
return lineContains;
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*ave 19
确定点R =(rx,ry)是否位于连接点P =(px,py)和Q =(qx,qy)的线上的最佳方法是检查矩阵的行列式
{{qx - px, qy - py}, {rx - px, ry - py}},
Run Code Online (Sandbox Code Playgroud)
即(qx - px)*(ry - py) - (qy - py)*(rx - px)接近0.此解决方案与其他方案相比具有几个相关的优点:首先,它不需要垂直线的特殊情况,第二,它不分(通常是慢速操作),第三,当线几乎但不是很垂直时,它不会触发不良的浮点行为.
鉴于上线两分L0
和L1
和测试点P
.
(L1 - L0) * (P - L0)
n = (P - L0) - --------------------- (L1 - L0)
(L1 - L0) * (L1 - L0)
Run Code Online (Sandbox Code Playgroud)
矢量的范数n
是点P
与线的距离L0
和L1
.如果该距离为零或足够小(在舍入误差的情况下),则该点位于该线上.
符号*
代表点积.
例
P = (5, 5)
L0 = (0, 10)
L1 = (20, -10)
L1 - L0 = (20, -20)
P - L0 = (5, -5)
(20, -20) * (5, -5)
n = (5, -5) - --------------------- (20, -20)
(20, -20) * (20, -20)
200
= (5, -5) - --- (20, -20)
800
= (5, -5) - (5, -5)
= (0, 0)
Run Code Online (Sandbox Code Playgroud)
我认为帕特里克麦克唐纳先生提出了几乎正确的答案,这是对他答案的更正:
public bool IsOnLine(Point endPoint1, Point endPoint2, Point checkPoint)
{
return (((double)checkPoint.Y - endPoint1.Y)) / ((double)(checkPoint.X - endPoint1.X))
== ((double)(endPoint2.Y - endPoint1.Y)) / ((double)(endPoint2.X - endPoint1.X));
}
Run Code Online (Sandbox Code Playgroud)
当然还有许多其他正确答案,尤其是Mr.Josh,但我发现这是最好的答案.
感谢evryone.
归档时间: |
|
查看次数: |
32757 次 |
最近记录: |