¿Cómo puedo saber si un punto pertenece a una determinada línea?

Ejemplos son apreciados, si es posible.

  • Por favor, ser más específico. ¿Qué información usted tiene que comenzar con? ¿Tiene usted un par ordenado de punto y una ecuación?
InformationsquelleAutor Wahid Bitar | 2009-05-25

11 Comentarios

  1. 28

    En la forma más simple, sólo tienes que conectar las coordenadas en la línea de la ecuación y la verificación de la igualdad.

    Dado:

    Point p (X=4, Y=5)
    Line l (Slope=1, YIntersect=1)

    Enchufe de X y de y:

       Y = Slope * X + YIntersect
    => 5 = 1 * 4 + 1
    => 5 = 5

    Así que sí, el punto está en la línea.

    Si las líneas están representadas en (X1,Y1),(X2,Y2) formulario a continuación, usted puede calcular la pendiente con:

     Slope = (y1 - y2) / (x1-x2)

    Y, a continuación, obtener la Y-se Cruzan con este:

     YIntersect = - Slope * X1 + Y1;

    Edit: me fijo el eje Y se Cruzan (que ha sido X1 /Y1 …)

    Usted tendrá que verificar que x1 - x2 no es 0. Si es así, a continuación, comprobar si el punto está en la línea es una simple cuestión de comprobar si el valor de Y en su punto es igual a x1 o x2. También, compruebe que el quid de la cuestión no es ‘x1’ o ‘x2’.

    • ¿Qué lenguaje de la biblioteca es esto?
    • No es sólo pseudo-código.
    • No es hasta el pseudo-código – es sólo matemáticas.
    • Sí, bastante.
    • Yo creo que sobre el movimiento de la EDICIÓN: corrección para la Y-se Cruzan fórmula más en la parte superior de la original versión incorrecta. Tomó una segunda lectura a cuenta de que.
    • Método más fácil es comparar la Math.Atan2 resultados tanto desde el segmento de los puntos de inicio y final para el tema de punto. Véase mi respuesta a continuación un ejemplo. No se preocupe acerca de horizontal o vertical problemas o ¿cómo cercano a cero antes de su cero que la slope-intercept método confiere.

  2. 23

    Acabo de escribir una función que se encarga de un par de requisitos desde que uso esta comprobación en una aplicación de dibujo:

    • Tolerancia – debe haber un margen de error ya que la función se utiliza para seleccionar las líneas haciendo clic sobre ellos.
    • La línea consiguió un punto final y un punto de partida, no infinitas líneas.
    • Que debe afrontar la recta vertical y horizontal de las líneas (x2 – x1) == 0 hace que la división por cero en las otras respuestas.
    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;            
    }
    • Por qué no es este el aceptado la respuesta? Todos los demás son sólo matemáticas y bla. Este es un mundo real, endurecidos por la batalla de la función y debe ser preferida. Me refiero a que esta es StackOverflow para los dioses causa, no MathOverflow.
    • esta es la mejor respuesta gracias funciona . pero ¿cuál sería el mejor valor por SELECTION_FUZZINESS ??
    • el SELECTION_FUZZINESS se corresponden con el ancho de la línea. El más pequeño es el valor, mayor será la precisión
  3. 19

    La mejor manera de determinar si un punto R = (rx, ry) se encuentra en la línea que une los puntos P = (px, py) y Q = (qx, qy) es comprobar si el determinante de la matriz de

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

    a saber, (qx – px) * (ry – py) – (qy – py) * (rx – px) es cercano a 0. Esta solución tiene varias ventajas sobre las demás, publicado: en primer lugar, no requiere ningún caso especial de líneas verticales, segundo, que no se dividen (generalmente una operación lenta), tercero, no se dispara la mala de punto flotante de comportamiento cuando la línea es casi, pero no completamente vertical.

    • Para una línea de 0,0 a 10,10 con un punto 5.1, 5.1, el determinante es cero. Pero el punto no está en la línea.
    • ¿qué exactamente significa «cercano a 0»?
    • Esta es una mucho mejor respuesta que la de la «aceptado» uno. La única cosa que falta es una definición de «cerca». Esto tiene que ser entendido en el contexto de los números que se restan: dado que hay 5 sustracciones, hay 5 oportunidades para la «pérdida significativa de precisión», lo que significa que es realmente un poco difícil de poner una buena especificación de «cerca».
    • Piense de nuevo – la línea de (0,0) a través de (10,10) puede ser descrito por la ecuación y = x, y todos los puntos que resolver esta ecuación mentira en la línea. (5.1, 5.1) resuelve la ecuación, y por lo tanto se encuentra en la línea.
  4. 6

    Pienso que el Señor Patrick McDonald poner la casi correcta respuesta y esta es la corrección de su respuesta:

    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));
    }

    y, por supuesto, hay muchas otras respuestas correctas especialmente el Señor Josh, pero encontré este es el mejor.

    Thankx para evryone.

    • Le da un div por cero si el punto de control.x == extremo.x o si los puntos finales tienen el mismo valor de x
  5. 6

    Dados dos puntos en la línea L0 y L1 y el punto de prueba P.

                   (L1 - L0) * (P - L0)
    n = (P - L0) - --------------------- (L1 - L0)
    (L1 - L0) * (L1 - L0)

    La norma del vector n es la distancia del punto de P de la línea a través L0 y L1. Si esta distancia es cero o muy pequeño (en el caso de errores de redondeo), el punto se encuentra sobre la línea.

    El símbolo * representa el producto escalar.

    Ejemplo

    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)
    • +1 por mencionar a los errores de redondeo. El uso exacto de la igualdad en la aritmética de punto flotante hará que el otro propone soluciones a fallar en muchos de los casos. No estoy seguro acerca de la solidez numérica del algoritmo propuesto, pero solidez numérica es lo suficientemente complicado como que si la precisión es importante, entonces es aconsejable buscar en la literatura científica sobre el tema. O, al menos, el uso de una biblioteca donde es probable que el autor ha realizado la investigación.
    • No creo que tu ejemplo es correcta, porque después de algunas transformaciones n = (p - L0) - (p - L0) y en cada caso de tener siempre tendrá n = (0, 0).
  6. 4
    y = m * x + c

    Esta es la ecuación de una línea. x & y son las coordenadas. Cada línea se caracteriza por su pendiente (m ) y donde se intersecta con el eje y (c).

    Así que, dado que m & c para una línea, usted puede determinar si el punto (x1, y1) está en la línea, mediante la comprobación de si la ecuación se cumple para x = x1, y = y1

    • Excepto que esta ecuación no se puede describir una línea vertical, y con la excepción de que usted no menciona la posibilidad de que la línea que no-de espesor cero.
    • Una línea no tiene grosor.
    • «Una línea no tiene espesor» — cuando se dibuja en una pantalla (es decir, cuando se trata de una programación de la pregunta): su grosor es de al menos un píxel, y puede ser más.
    • Yo consideraría una línea de 1 píxel de grosor (cuando se dibuja una pantalla), que funciona con esta ecuación. Si usted quería saber si un punto está en línea con X espesor usted se está preguntando si un punto está dentro de un rectángulo.
  7. 3

    Si usted tiene una línea definida por sus extremos, de

    PointF pt1, pt2;

    y tiene un punto en el que desea comprobar

    PointF checkPoint;

    a continuación, puede definir una función como la siguiente:

    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);
    }

    y la llamada de la siguiente manera:

    if (IsOnLine(pt1, pt2, checkPoint) {
    //Is on line
    }

    Usted tendrá que comprobar para la división por cero, aunque.

    • Esto no puede ser a la derecha… Desde el punto de coordenadas son enteros, tendrías (crítica) de la pérdida de n percisio cuando el punto está cerca de endPoint1 y lejos de endPoint2. Tal vez si la ha cambiado a decimal o doble que podría funcionar bien para ambos lados, pero aún así yo no confiar en este equasion la exactitud.
    • Punto justo (juego de palabras), cambiado a PointF
    • Hay dos problemas: Que no se revise el final de la línea, por lo que (4,6) sería entre (1,2) y (3,4) de acuerdo a esta función, y no hay el problema de la precisión – supongamos una línea que va desde (1,100) a (2,200). No hay un solo punto en el medio con coordenadas enteras – el cheque siempre sería falsa de coordenadas enteras.
    • java.lang.ArithmeticException: división por cero NO ACEPTAR
    • Como el algoritmo es sólo la comprobación de la pendiente de relación, las líneas paralelas se iba a dar resultados positivos falsos
  8. 2

    2D línea es generalmente representado a través de una ecuación en dos variables x y y aquí es bien conocida ecuación de

    ¿Cómo puedo saber si un punto pertenece a una determinada línea?

    Ahora imagine que en su GDI+ línea se dibuja a partir de (0,0) a (100, 100), entonces el valor de m=(0-100)/(0-100) = 1 por lo tanto la ecuación de su recta es y-0=1*(x-0) => y=x

    Ahora que tenemos una ecuación de la línea en cuestión es fácil comprobar si un punto pertenece a esta línea. Un determinado punto (x3, y3) pertenece a esta línea si se satisface la ecuación de la línea de al sustituir x=x3 y y=y3. Por ejemplo, el punto (10, 10) pertenece a esta línea desde 10=10 pero (10,12) no pertenece a esta línea desde el 12 != 10.

    NOTA: Para una línea vertical el valor de la pendiente (m) es infinito, pero para este caso especial, usted puede usar la ecuación para una línea vertical directamente x=c, donde c = x1 = x2.

    Aunque tengo que decir que no estoy seguro de si esta es la manera más eficiente de hacer esto. Voy a tratar de encontrar una manera más eficiente cuando tengo algo más de tiempo en la mano.

    Espero que esto ayude.

  9. 1

    Ecuación de la recta es:

    y = mx + c

    Por lo que un punto(a,b) es en esta línea si se satisface esta ecuación es decir, b = ma + c

  10. 0

    ¿Podría ser más específico?

    ¿Qué lenguaje de programación estás hablando?

    Lo que el entorno está usted hablando?

    Lo «líneas» estás hablando? El texto? ¿En qué punto? XY en la pantalla?

    • La excusa esta debería haber comentado en la pregunta original
    • Aún puede eliminar tu post, y publicar el comentario : )
  11. 0

    Como una alternativa a la slope/y-intercept método, elegí este enfoque el uso de 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;
    }

    El primer cheque reference determina la arcTan desde el punto de inicio del segmento de la línea a es punto final.
    Entonces, desde el punto de inicio de la perspectiva, podemos determinar la arcTan para el vector v.

    Si los valores son iguales, podemos comprobar desde la perspectiva de la punto final.

    Simple y asas horizontales, verticales y de todos los demás en el medio.

Dejar respuesta

Please enter your comment!
Please enter your name here