2012-02-28 15 views
8

Otra pregunta de puntos colineales. El giro de esta es, estoy usando la aritmética de enteros, y estoy buscando exacta collinearity, no es una prueba fuzzy basada en epsilon.Cómo determinar si 3 puntos son exactamente colineales en Z^2

Con ensamblado en línea, puedo conseguir una respuesta exacta: la instrucción x86 multiplican da acceso tanto a las partes alta y baja del producto, los cuales son importantes para calcular el producto vectorial (X - Un) x (B - A); Puedo simplemente O las dos mitades juntas y probar cero. Pero espero que hay una manera de hacerlo en C, que es:

  1. desbordamiento a prueba de
  2. portátil
  3. elegante

más o menos en ese orden. Y, al mismo tiempo, una forma de hacerlo que es/no:

  1. incluyen fundición a double
  2. implicar el uso de un mayor tipo entero - supongo que ya estoy usando el mayor tipo entero disponible para mi componente de coordenadas tipo
  3. produce falsos positivos o falsos negativos.

No estoy preocupado por esta cuestión acerca de si X es más allá del segmento AB ; eso es solo cuatro comparaciones poco interesantes.

Mi situación de pesadilla es que tendré que dividir cada componente de coordenadas en dos mitades, y hacer una multiplicación larga explícitamente, solo para poder seguir todas las mitades altas en los productos parciales. (Y luego tener que hacer complemento con-llevar de forma explícita.)

+0

¿El producto cruzado se generaliza a n dimensiones? –

+0

Su título menciona Z^n, pero el texto de su pregunta menciona el producto cruzado, que creo que solo se define cuando n = 3 (o n = 2, tratándolo como n = 3 con z = 0). ¿Podría aclarar si está buscando una solución general o solo una n = 3? Pregunto porque, aunque un enfoque n = 2 o n = 3 se puede generalizar fácilmente a dimensiones arbitrarias (verificando la colinealidad a lo largo de la superposición de subconjuntos de dimensiones de dos o tres elementos), podría ser menos elegante. – ruakh

+0

@OliCharlesworth - [Sí, pero es una operación ('n-1') -ary] (http://en.wikipedia.org/wiki/Cross_product#Multilinear_algebra). –

Respuesta

2

Después de algunas comparaciones y comprobaciones simples, puede obtener 2 pares de números positivos (x1,y1), (x2,y2), que desea verificar si x1*y2==x2*y1.

Puede usar el algoritmo euclidiano para buscar el GCD de x1 y y1, y dividir ambos por el GCM. Haga lo mismo para (x2,y2).Si obtuviste la misma pareja en ambos casos, ambos vectores tienen la misma dirección.

+1

Pero, ¿y si todos los números son primos y grandes? –

+1

@OliCharlesworth Entonces el GCD es 1, y 'x1 * y2 == x2 * y1' iff' x1 == x2 && y1 == y2' – asaelr

+0

Oh, veo a lo que te refieres. –

0

Si tres puntos (a, b, c) son exactamente colineales entonces la siguiente identidad sostiene:

c = a + (a - b) * scalar 

es decir:

c - a = scalar * (a - b) 

Tome el primer componente de (c-a), divídalo por el primer componente de (a-b), guarde ese valor. Luego repite para cada componente posterior, y si alguno de ellos difiere, los puntos no son colineales.

Si desea evitar el uso total de la división de coma flotante (que sería la forma más fácil de hacerlo), tendrá que almacenar la relación y compararla en su lugar.

+0

Eso falla el requisito de "evitar la conversión al doble". Si usa racionales en lugar de dobles, puede haber un problema de desbordamiento. –

+0

Eso es lógicamente equivalente a lo que estaba a punto de responder, pero el problema es que fácilmente podría terminar flotando al dividir un componente por otro, y parece que el OP desea evitar la aritmética de punto flotante. –

+0

@Osi, Jack; ver editar. Además, las relaciones de verificación son las mismas sin reducir a la forma más básica, lo que puede ser bastante fácil con la división de enteros. – James

Cuestiones relacionadas