CitarCoordenadas de la linea o rectaMi pregunta es, existe alguna formula o ecuacion para comprobar esto mismo que fuese mas simple o rapido sin tanto calculo?
{
A.X = 0, A.Y = 0
B.X = 100, B.Y = 100
}
Coordenadas del punto a comprobar
{
C.X = 50, C.Y = 50
}
@AB = 45º
@AC = 45º
Existe interseccion
Public Function GetIntersect3(Src As Vector, Dest As Vector, Point As Vector) As Boolean
Dim D As Vector, N As Vector, Normal As Vector
Dim dSrc As Double, Product As Double, Dist As Double
'Direccion de la recta = Vector2( B.X - A.X, B.Y - A.Y);
D.X = Dest.X - Src.X: D.Y = Dest.Y - Src.Y
'Normal a la recta = Vector2( A.Y - B.Y, B.X - A.X ) normalizado;
N.X = Src.Y - Dest.Y: N.Y = Dest.X - Src.X
Call NormalizeVector(Normal, N)
'Dezplazamiento del origen = - Producto punto de la Normal a la recta por A o por B (que comodo!)
Product = (Normal.X * Point.X) + (Normal.Y * Point.Y)
dSrc = -((Product * Src.X) + (Product * Src.Y))
'Distancia del punto C a la recta = Producto punto de la normal + Dezplazamiento del origen
Dist = Product + dSrc
'Si la distancia es 0 el punto C esta en la recta ...
If Dist = 0 Then GetIntersect3 = True
End Function
Public Sub NormalizeVector(Out As Vector, Src As Vector)
Dim m As Double
'Hayamos el modulo del vector:
m = Sqr((Src.X * Src.X) + (Src.Y * Src.Y))
'Normalizamos el vector:
Out.X = Src.X / m
Out.Y = Src.Y / m
End Sub
Public Function GetIntersect3(Src As Vector, Dest As Vector, Point As Vector) As Boolean
Dim D As Vector, N As Vector, Normal As Vector
Dim dSrc As Double, Product As Double, Dist As Double
'Direccion de la recta = Vector2( B.X - A.X, B.Y - A.Y);
D.X = Dest.X - Src.X: D.Y = Dest.Y - Src.Y
'Normal a la recta = Vector2( A.Y - B.Y, B.X - A.X ) normalizado;
N.X = Src.Y - Dest.Y: N.Y = Dest.X - Src.X
Call NormalizeVector(Normal, N)
'Dezplazamiento del origen = - Producto punto de la Normal a la recta por A o por B (que comodo!)
'Lo escribí mal!
'Dezplazamiento del origen = - Producto punto entre la Normal a la recta y A (o B) (que comodo!)
dSrc = -((Normal.X * Src.X) + (Normal.Y * Src.Y))
dDest = -((Normal.X * Dest.X) + (Normal.Y * Dest.Y))
'Ambas te tienen que dar lo mismo, compruebalo ...
Proyeccion = (Normal.X * Point.X) + (Normal.Y * Point.Y)
'Distancia del punto C a la recta = Producto punto de la normal + Dezplazamiento del origen
Dist = Proyeccion + dSrc
' Se puede optimizar sensiblemente sin tener que sacar dSrc ni Proyeccion haciendo:
Dist = (Normal.X * (Point.X-Src.X)) + (Normal.Y * (Point.Y-Src.Y))
'Si la distancia es 0 el punto C esta en la recta ...
'If Dist = 0 Then GetIntersect3 = True
'Ya que esta normalizado seria bueno agregar un delta (lo cercano que ya consideras dentro de la recta) pues puede haber un error de precision
If Abs(Dist) < 0.00001 Then GetIntersect3 = True
End Function
Public Sub NormalizeVector(Out As Vector, Src As Vector)
Dim m As Double
'Hayamos el modulo del vector:
m = Sqr((Src.X * Src.X) + (Src.Y * Src.Y))
'Normalizamos el vector:
'Para evitar la division por 0 y optimizar el codigo:
if m <> 0 then m = 1.0/m;
Out.X = Src.X * m
Out.Y = Src.Y * m
End Sub
Cita de: "zxs"¿onde andará mi libro de algebra lineal? ¿onde? (ole)Calla, que yo hace solo 3 meses que di temas de vectores en unas clases preparatorias, que triste xD
hace mucho ya que no toco estas cosas
#define EPSILON 1.0 // Dejamos 1.0 de error posible
struct Vector {
float x, y;
};
int ComprobarPuntoEnRectaRecta(Vector A, Vector B, Vector P)
{
float d;
Vector D, N;
D.x = B.x - A.x;
D.y = B.y - A.y;
d = sqrt(D.x*D.x + D.y*D.y);
if( d > 0.0f) d = 1.0f / d;
N.x = D.y * d;
N.y = -D.x * d;
d = N.x * (P.x - A.x) + N.y * (P.y - A.y);
return fabs(d) < EPSILON; // Devuelve 1 si esta y 0 si no
}
Cita de: "Pogacha"No es mi metodo, es el metodo general, te lo enseñan en algebra I y tiene siglos de antiguedad ...Era una mera forma de referirme a la implementacion que me explicastes de la de vicho, ya imagino que esto se dara en universidad (y quizas en bachiller... pero yo curse el de artes :ph34r:)
Cita de: "Pogacha"Esto es elemental, no hay posibilidad de error ... te aseguro que este es el metodo.No lo dudo (y mas cuando el que tiene idea en esto eres tu y yo no tengo en absoluto) pero he traducido el codigo, lo he probado y sigue sin funcionar :(
Public Function GetIntersect(A As Vertex, B As Vertex, P As Vertex) As Boolean
Const EPSILON As Single = 1.5! '#define EPSILON 1.0 // Dejamos 1.0 de error posible
Dim Dir As Single 'float d;
Dim D As Vertex, N As Vertex 'Vector D, N;
D.X = B.X - A.X 'D.x = B.x - A.x;
D.Y = B.Y - A.Y 'D.y = B.y - A.y;
Dir = Sqr(D.X * D.X + D.Y * D.Y) 'd = sqrt(D.x*D.x + D.y*D.y);
If Dir > 0! Then Dir = 1! / Dir 'if( d > 0.0f) d = 1.0f / d;
N.X = D.Y * Dir 'N.x = D.y * d;
N.Y = -D.X * Dir 'N.y = -D.x * d;
Dir = N.X * (P.X - A.X) + N.Y * (P.Y - A.Y) 'd = N.x * (P.x - A.x) + N.y * (P.y - A.y);
GetIntersect = Abs(Dir) < EPSILON 'return fabs(d) < EPSILON; // Devuelve 1 si esta y 0 si no
End Function
Public Function GetIntersect(A As Vertex, B As Vertex, P As Vertex) As Boolean
Dim m As Double, n As Double
'Pendiente a la recta:
m = (B.Y - A.Y) / (B.X - A.X)
'Termino independiente:
n = (A.Y * B.X - B.Y * A.X) / (B.X - A.X)
'Ecuacion de la recta:
GetIntersect = (P.Y = (4 / 3) * P.X + 0) Or (P.Y = (4 / 3) * P.X)
End Function
Cita de: "Pogacha"1 - por las dudas, una recta no tiene principio ni fin, un segmento si, para acotar la prueba hasta el segmento debes agregar que se fije si el punto esta dentro de la caja de contención del segmento. Supongo que esto es obvio.La colision solo la realizaba en el metodo de los angulos para evitar que me diera por correcto un angulo fuera del alcance de la linea. No lo tengo implementado en el otro metodo pero lo añadire.
Cita de: "Pogacha"2 - El sqrt se refiere al square root (raiz cuadrada). No es si el sqr del basic es lo mismo.En teoria se supone que si :ph34r:
QUOTE (MSDN 6.0) |
Sqr (Función) Devuelve un tipo Double que especifica la raíz cuadrada de un número. Sintaxis Sqr(número) El númeroargumento es un tipoDouble o cualquierexpresión numérica válida mayor o igual a cero.[/quote] Cita de: "Pogacha"3 - Fijate que las componentes de los vectores sean flotantes por que sino vamos fritos y creo que es ese el error según el programa que me mandas. Las normales tienen modulo 1 o sea que sus componentes tienen valores de (-1 a 1) puedes usar un truco de punto fijo si fuera el caso o si no declara a la normal fuera como dosMmm, mira por donde puede venir por ahi el error ya que el tipo Vertex que aparece en mi codigo es un tipo de la dx_lib32 y sus componentes son todos tipo Long. Voy a hacer una implementacion Vector a pelo en el ejemplo y vuelvo a probar (no cai en este detalle (nooo) ) Cita de: "Pogacha"4 - El segundo programa usa la misma técnica que proponia vicho, la mas tentadora en un principio, pero tiene el problema de la division por 0 y la diferencia de presicion a diferentes pendientes. No controlé que estuviera bien tampoco, ando mal de tiempo :(No te preocupes, bastante que le estas dedicando tiempo a este tema, que ya es suficiente de agradecer :) Voy a probar el codigo con la modificacion del nuevo tipo Vector y te cuento. Agregare tambien la implementacion de Lex para probar. Salu2...
Título: Existe Una Formula Mas Rapida/sencilla/logica?
Publicado por: [EX3] en 13 de Mayo de 2006, 06:07:12 AM
Confirmado Pogacha, era problema de la estructura Vertex de dx_lib32 y sus componentes tipo Long, con la clase Vector y sus componentes tipo Single va 100% precisa a la linea (ole) Siento haber tenido mi descuido con lo de la estructura y el tipo de dato que usa, no me percate y por ello te he tenido 3 dias revisando un codigo que funcionaba desde el principio, perdon por las molestias y muchas gracias por tu tiempo :)
Te dejo el programa arreglado para que lo veas ;) IntersectPointLine(FINAL).rar Lex, tu codigo no me funciono en ninguno de los casos :( Salu2...
Título: Existe Una Formula Mas Rapida/sencilla/logica?
Publicado por: Lex en 13 de Mayo de 2006, 03:17:40 PM
...
Título: Existe Una Formula Mas Rapida/sencilla/logica?
Publicado por: Pogacha en 13 de Mayo de 2006, 03:43:38 PM
Que bueno que te ha funcionado al fin!
No necesitas cambiar la estructura vector, tan solo ajustar la normal para que sean 2 flotantes independientes. Saludos.
Título: Existe Una Formula Mas Rapida/sencilla/logica?
Publicado por: [EX3] en 14 de Mayo de 2006, 04:20:09 AM Cita de: "Pogacha"No necesitas cambiar la estructura vector, tan solo ajustar la normal para que sean 2 flotantes independientes.Cierto, no lo habia mirado, como la normal es el unico vector que recibiria valores que se trabajan en punto flotante el tipo Vertex seria igual de valido para los argumentos de entrada de la funcion :) Cita de: "Lex"quizás mirando el código de tu aplicación podría ver en qué falla lo mioTodo tuyo ;) He añadido al paquete actual los fuentes. Vienen tambien las implementaciones que me hicieron en los foros de DivSite.net (foros de Fenix) en el codigo del proyecto. Salu2...
Título: Existe Una Formula Mas Rapida/sencilla/logica?
Publicado por: Lex en 15 de Mayo de 2006, 11:50:09 PM
...
Título: Existe Una Formula Mas Rapida/sencilla/logica?
Publicado por: [EX3] en 16 de Mayo de 2006, 12:36:45 AM
En serio, entre lo del Select Case y lo de no renombrar unas variables en una implementacion que me pasaron en otro foro si no fuera por que tengo 22 años diria que estoy empezando a chochear (nooo)
Aun con esas como te comente en el MSN el codigo que me pasastes no funcionaba en todos los casos, pero esta ultima modificacion que le has hecho parece que va 100% perfecta :) Yo estaba ya tratando con mi logica "anti-matematicamente-correcta" de buscar una solucion mediante comparativas que no iba a ser tan optimizada como el codigo de pogacha o el tuyo. Y pensar que me quede en los umbrales de estos temas cuando abandone el curso preparatorio del modulo, menudo acierto por mi parte (nooo) Salu2... |