Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何判断点是否属于某条直线?_C#_.net_Algorithm_Gdi+_Line - Fatal编程技术网

C# 如何判断点是否属于某条直线?

C# 如何判断点是否属于某条直线?,c#,.net,algorithm,gdi+,line,C#,.net,Algorithm,Gdi+,Line,如何判断点是否属于某条直线 如果可能的话,请举例说明。您能更具体一点吗 你在说什么编程语言 你在说什么环境 你在说什么“台词”?文本?什么意思?屏幕上的XY y = m * x + c 这是直线方程。x和y是坐标。每条线以其坡度(m)和与y轴(c)相交的位置为特征 因此,给定一条直线的m&c,你可以通过检查方程是否适用于x=x1和y=y1来确定点(x1,y1)是否在直线上,以最简单的形式,只需将坐标插入直线方程并检查等式即可 鉴于: Point p (X=4, Y=5) Line l (Slo

如何判断点是否属于某条直线


如果可能的话,请举例说明。

您能更具体一点吗

你在说什么编程语言

你在说什么环境

你在说什么“台词”?文本?什么意思?屏幕上的XY

y = m * x + c
这是直线方程。x和y是坐标。每条线以其坡度(m)和与y轴(c)相交的位置为特征


因此,给定一条直线的m&c,你可以通过检查方程是否适用于x=x1和y=y1来确定点(x1,y1)是否在直线上,以最简单的形式,只需将坐标插入直线方程并检查等式即可

鉴于:

Point p (X=4, Y=5)
Line l (Slope=1, YIntersect=1)
插入X和Y:

   Y = Slope * X + YIntersect
=> 5 = 1 * 4 + 1
=> 5 = 5
所以,是的,关键是在线上

如果直线以(X1,Y1)、(X2,Y2)形式表示,则可以使用以下公式计算坡度:

 Slope = (y1 - y2) / (x1-x2)
然后得到Y-相交点:

 YIntersect = - Slope * X1 + Y1;
编辑:我修复了Y形相交(已为X1/Y1…)


您必须检查
x1-x2
是否不是
0
。如果是,则检查点是否在直线上是一个简单的问题,即检查点中的Y值是否等于
x1
x2
。此外,检查点的X不是“x1”或“x2”。

直线方程为:

y = mx + c

所以点(a,b)在这条线上,如果它满足这个方程,也就是说,
b=ma+c
通常用两个变量x和y中的方程来表示二维线这里是一个众所周知的方程

现在假设你的GDI+线是从(0,0)到(100100)绘制的,那么m的值=(0-100)/(0-100)=1,因此你的线的方程是y-0=1*(x-0)=>y=x

现在我们有了一个关于这条线的方程,很容易测试一个点是否属于这条线。当替换x=x3和y=y3时,如果给定点(x3,y3)满足直线方程,则该点属于该直线。例如,点(10,10)属于这条线,因为10=10,但(10,12)不属于这条线,因为12!=十,

注:对于垂直线,斜率(m)的值是无限的,但对于这种特殊情况,您可以直接使用垂直线的方程x=c,其中c=x1=x2

尽管我不得不说,我不确定这是否是最有效的方法。当我手头有更多的时间时,我会设法找到一种更有效的方法


希望这有帮助。

如果您有一条由端点定义的线

PointF pt1, pt2;
你有一点想核实一下

PointF checkPoint;
然后,您可以定义一个函数,如下所示:

bool IsOnLine(PointF endPoint1, PointF endPoint2, PointF checkPoint) 
{
    return (checkPoint.Y - endPoint1.Y) / (endPoint2.Y - endPoint1.Y)
        == (checkPoint.X - endPoint1.X) / (endPoint2.X - endPoint1.X);
}
if (IsOnLine(pt1, pt2, checkPoint) {
    // Is on line
}
并称之为:

bool IsOnLine(PointF endPoint1, PointF endPoint2, PointF checkPoint) 
{
    return (checkPoint.Y - endPoint1.Y) / (endPoint2.Y - endPoint1.Y)
        == (checkPoint.X - endPoint1.X) / (endPoint2.X - endPoint1.X);
}
if (IsOnLine(pt1, pt2, checkPoint) {
    // Is on line
}

不过,您需要检查是否被零除。

给出了行
L0
L1
上的两个点,以及测试
p
的点

               (L1 - L0) * (P - L0)
n = (P - L0) - --------------------- (L1 - L0)
               (L1 - L0) * (L1 - L0)
向量
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)

确定点R=(rx,ry)是否位于连接点p=(px,py)和Q=(qx,qy)的直线上的最佳方法是检查矩阵的行列式

{{qx - px, qy - py}, {rx - px, ry - py}},

即(qx-px)*(ry-py)-(qy-py)*(rx-px)接近于0。与其他已发布的解决方案相比,此解决方案有几个相关的优点:第一,它不需要对垂直线进行特殊处理;第二,它不进行分割(通常是一个缓慢的操作);第三,当线几乎是,但不是很垂直。

我认为帕特里克·麦克唐纳先生给出了几乎正确的答案,这是对他的答案的更正:

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));
}
当然还有很多其他的正确答案,特别是乔希先生,但我发现这是最好的答案


谢谢evryone

我刚刚编写了一个函数,用于处理一些额外的要求,因为我在绘图应用程序中使用了此检查:

  • 模糊性-必须存在一定的错误空间,因为该函数用于通过单击线条来选择线条
  • 这条线有一个端点和一个起点,没有无限长的线
  • 必须处理垂直和水平直线,(x2-x1)==0导致其他答案被零除
private const双选_FUZZINESS=3;
内部覆盖bool ContainsPoint(点)
{
LineGeometry lineGeo=作为LineGeometry的几何图形;
点左点;
点右点;
//将开始/结束从左到右进行规格化,以简化偏移计算。

如果(lineGeo.StartPoint.X作为
slope/y-intercept
方法的替代方法,我使用
Math.Atan2
选择了这种方法:

// as an extension method
public static bool Intersects(this Vector2 v, LineSegment s) {
    //  check from line segment start perspective
    var reference = Math.Atan2(s.Start.Y - s.End.Y, s.Start.X - s.End.X);
    var aTanTest = Math.Atan2(s.Start.Y - v.Y, s.Start.X - v.X);

    //  check from line segment end perspective
    if (reference == aTanTest) {
        reference = Math.Atan2(s.End.Y - s.Start.Y, s.End.X - s.Start.X);
        aTanTest = Math.Atan2(s.End.Y - v.Y, s.End.X - v.X);
    }

    return reference == aTanTest;
}
第一次检查
参考
确定从线段起点到其终点的弧长。 然后从起点的角度,我们确定向量
v
的弧tan

如果这些值相等,我们将从端点的角度进行检查


简单,可处理水平、垂直和中间的所有问题。

请更具体一些。您必须从哪些信息开始?您是否有一对有序的点和方程?请原谅,我应该对原始问题进行评论。您仍然可以删除您的帖子,并发布评论:)除了这个等式不能描述一条垂直线,除了你没有提到这条线厚度非零的可能性。“一条线没有厚度”——当它被画在屏幕上时(例如,当它是一个编程问题时)它的厚度至少是一个像素,可能更多。我想一条线是1像素厚(当画到屏幕上),它用这个方程式来工作。如果你想找到一个点是否在一个X厚度的线中,你真的在问一个点是否在一个矩形中。