Quiero saber si un punto se encuentra dentro de un rectángulo o no. El rectángulo se puede orientar de cualquier forma y no es necesario alinear el eje.
Un método que se me ocurrió fue rotar el rectángulo y las coordenadas del punto para alinear el eje del rectángulo y luego simplemente probar las coordenadas del punto, ya sea que se encuentren dentro de las del rectángulo o no.
El método anterior requiere rotación y, por tanto, operaciones de coma flotante. ¿Existe alguna otra forma eficaz de hacer esto?
Respuestas:
¿Cómo se representa el rectángulo? ¿Tres puntos? ¿Cuatro puntos? ¿Punto, lados y ángulo? ¿Dos puntos y un lado? ¿Algo más? Sin saberlo, cualquier intento de responder a su pregunta tendrá un valor puramente académico.
En cualquier caso, para cualquier polígono convexo (incluido el rectángulo), la prueba es muy simple: verifique cada borde del polígono, asumiendo que cada borde está orientado en dirección contraria a las agujas del reloj, y pruebe si el punto está a la izquierda del borde (a la izquierda -medio plano de la mano). Si todos los bordes pasan la prueba, el punto está adentro. Si al menos uno falla, el punto está afuera.
Para probar si el punto se
(xp, yp)
encuentra en el lado izquierdo del borde(x1, y1) - (x2, y2)
, solo necesita calcularSi
D > 0
, el punto está en el lado izquierdo. SiD < 0
, el punto está en el lado derecho. SiD = 0
, el punto está en la línea.La versión anterior de esta respuesta describía una versión aparentemente diferente de la prueba del lado izquierdo (ver más abajo). Pero se puede demostrar fácilmente que calcula el mismo valor.
... Para probar si el punto se
(xp, yp)
encuentra en el lado izquierdo del borde(x1, y1) - (x2, y2)
, necesita construir la ecuación de la línea que contiene el borde. La ecuación es la siguientedónde
Ahora todo lo que necesita hacer es calcular
Si
D > 0
, el punto está en el lado izquierdo. SiD < 0
, el punto está en el lado derecho. SiD = 0
, el punto está en la línea.Sin embargo, esta prueba, nuevamente, funciona para cualquier polígono convexo, lo que significa que podría ser demasiado genérico para un rectángulo. Un rectángulo podría permitir una prueba más simple ... Por ejemplo, en un rectángulo (o en cualquier otro paralelogramo) los valores de
A
yB
tienen la misma magnitud pero diferentes signos para los bordes opuestos (es decir, paralelos), que se pueden aprovechar para simplificar la prueba .fuente
A'
yB'
pueden estar dados porA'=B
yB'=-A
. 3. No tiene sentido calcularA xp + B yp
ambos bordes, así que combínelos en una sola prueba. Entonces tu prueba de estar en un rectángulo se convierte en(v_min < A xp + B yp < v_max) && ( w_min < B xp - A yp < w_max )
.v_min
, etc.?v_min
es el valor mínimo deA x + B y
para todos los valores en el interior del rectángulo (que es el valor mínimo cuando se evalúa en las esquinas).v_max
es el máximo correspondiente. Losw_?
valores son los mismos, pero paraBx - A y
.Suponiendo que el rectángulo está representado por tres puntos A, B, C, con AB y BC perpendiculares, solo necesita verificar las proyecciones del punto de consulta M en AB y BC:
AB
es vector AB, con coordenadas (Bx-Ax, Por-Ay), ydot(U,V)
es el producto escalar de vectores U y V:Ux*Vx+Uy*Vy
.Actualizar . Tomemos un ejemplo para ilustrar esto: A (5,0) B (0,2) C (1,5) y D (6,3). De las coordenadas del punto, obtenemos AB = (- 5,2), BC = (1,3), punto (AB, AB) = 29, punto (BC, BC) = 10.
Para el punto de consulta M (4,2), tenemos AM = (- 1,2), BM = (4,0), punto (AB, AM) = 9, punto (BC, BM) = 4. M está dentro del rectángulo.
Para el punto de consulta P (6,1), tenemos AP = (1,1), BP = (6, -1), punto (AB, AP) = - 3, punto (BC, BP) = 3. P no está dentro del rectángulo, porque su proyección en el lado AB no está dentro del segmento AB.
fuente
He tomado prestada la respuesta de Eric Bainville:
Que en javascript se ve así:
p.ej:
entonces:
Aquí hay un codepen para dibujar la salida como una prueba visual :) http://codepen.io/mattburns/pen/jrrprN
fuente
mouseover
evento en mi proyecto, por lo que siempre que el mouse esté sobre el punto que se supone que está dentro del rectángulo, mostrará un punto circular negro alrededor del mouse, y fuera del rectángulo no debería mostrar nada. Necesito ayuda para que funcione, pero estoy muy confundido.mouseover
debería sermousemove
, solo error tipográfico.fuente
a
,b
yd
. Si bien tres puntos es una forma válida de representar un rectángulo arbitrario en teoría, en la práctica es imposible hacerlo con precisión en coordenadas enteras en el caso general. En el caso general, uno terminará con un paralelogramo, que está muy cerca de un rectángulo pero aún no es un rectángulo.Me doy cuenta de que este es un hilo antiguo, pero para cualquiera que esté interesado en ver esto desde una perspectiva puramente matemática, hay un hilo excelente en el intercambio de pila de matemáticas, aquí:
/math/190111/how-to-check-if-a-point-is-inside-a-rectangle
Editar: Inspirado por este hilo, he creado un método simple de vectores para determinar rápidamente dónde se encuentra su punto.
Suponga que tiene un rectángulo con puntos en p1 = (x1, y1), p2 = (x2, y2), p3 = (x3, y3) y p4 = (x4, y4), en sentido horario. Si un punto p = (x, y) se encuentra dentro del rectángulo, entonces el producto escalar (p - p1). (P2 - p1) estará entre 0 y | p2 - p1 | ^ 2, y (p - p1). (p4 - p1) estará entre 0 y | p4 - p1 | ^ 2. Esto equivale a tomar la proyección del vector p - p1 a lo largo y ancho del rectángulo, con p1 como origen.
Esto puede tener más sentido si muestro un código equivalente:
Y eso es. También funcionará para paralelogramos.
fuente
Acabo de implementar la respuesta de AnT usando c ++. Usé este código para verificar si la coordinación del píxel (X, Y) se encuentra dentro de la forma o no.
fuente
Si no puede resolver el problema del rectángulo, intente dividir el problema en problemas más fáciles. Divide el rectángulo en 2 triángulos y comprueba si el punto está dentro de alguno de ellos como explican aquí
Esencialmente, recorre los bordes en cada dos pares de líneas desde un punto. Luego, use el producto cruzado para verificar si el punto está entre las dos líneas usando el producto cruzado. Si se verifica para los 3 puntos, entonces el punto está dentro del triángulo. Lo bueno de este método es que no crea ningún error de punto flotante que ocurre si verifica los ángulos.
fuente
Si un punto está dentro de un rectángulo. En un avión. Para coordenadas de matemático o geodesia (GPS)
Haz una ecuación para cada l i . El tipo de ecuación:
f yo (P) = 0.
P es un punto. Para los puntos pertenecientes a l i , la ecuación es verdadera.
Entonces, tenemos que verificar esto:
f AB (P) f AB (C)> = 0
f BC (P) f BC (D)> = 0
f CD (P) f CD (A)> = 0
f DA (P) f DA (B)> = 0
Las no ecuaciones no son estrictas, porque si un punto está en el borde, también pertenece al rectángulo. Si no necesita puntos en el borde, puede cambiar las inecuaciones por estrictas. Pero mientras trabaja en operaciones de punto flotante, la elección es irrelevante.
Lo único que queda es obtener una ecuación para una línea que pasa por dos puntos. Es una ecuación lineal muy conocida. Escribámoslo para una recta AB y un punto P:
f AB (P) ≡ (x A -x B ) (y P -y B ) - (y A -y B ) (x P -x B )
La verificación podría simplificarse - vayamos a lo largo del rectángulo en el sentido de las agujas del reloj - A, B, C, D, A. Entonces todos los lados correctos estarán a la derecha de las líneas. Entonces, no necesitamos comparar con el lado donde está otro vértice. Y necesitamos comprobar un conjunto de inecuaciones más cortas:
f AB (P)> = 0
f BC (P)> = 0
f CD (P)> = 0
f DA (P)> = 0
Pero esto es correcto para el conjunto de coordenadas normal, matemático (de la escuela de matemáticas), donde X está a la derecha e Y a la parte superior. Y para las coordenadas de geodesia , como se usan en GPS, donde X está arriba e Y está a la derecha, tenemos que girar las inecuaciones:
f AB (P) <= 0
f BC (P) <= 0
f CD (P) <= 0
f DA (P) <= 0
Si no está seguro con las direcciones de los ejes, tenga cuidado con esta verificación simplificada: busque un punto con la ubicación conocida, si ha elegido las inecuaciones correctas.
fuente
La forma más fácil en la que pensé fue simplemente proyectar el punto sobre el eje del rectángulo. Dejame explicar:
Si puede obtener el vector desde el centro del rectángulo hasta el borde superior o inferior y el borde izquierdo o derecho. Y también tiene un vector desde el centro del rectángulo hasta su punto, puede proyectar ese punto en sus vectores de ancho y alto.
P = vector de puntos, H = vector de altura, W = vector de ancho
Obtenga el vector unitario W ', H' dividiendo los vectores por su magnitud
proj_P, H = P - (P.H ') H' proj_P, W = P - (P.W ') W'
A menos que me equivoque, lo cual no creo que esté ... (corríjame si me equivoco) pero si la magnitud de la proyección de su punto en el vector de altura es menor que la magnitud del vector de altura (que es la mitad de la altura del rectángulo) y la magnitud de la proyección de su punto en el vector de ancho es, entonces tiene un punto dentro de su rectángulo.
Si tiene un sistema de coordenadas universal, es posible que deba calcular los vectores de altura / ancho / punto mediante la resta de vectores. ¡Las proyecciones vectoriales son increíbles! recuérdalo.
fuente
En la continuación matts responde. Necesitamos usar la solución /math/190111/how-to-check-if-a-point-is-inside-a-rectangle/190373#190373 para que funcione
A continuación no funciona
0 <= punto (AB, AM) <= punto (AB, AB) && 0 <= punto (BC, BM) <= punto (BC, BC)
A continuación funciona
0 <= punto (AB, AM) <= punto (AB, AB) && 0 <= punto (AM, AC) <= punto (AC, AC)
verifica pegando a continuación en la consola javascript // solución Javascript para la misma
fuente