Una nube de puntos que es 4-simétrica tendrá 4 ejes de simetría de reflexión, donde cada eje está desplazado del siguiente por 45 grados. Para encontrar todos los ejes, por lo tanto, basta con encontrar uno.
El siguiente algoritmo casero funciona bastante bien para encontrar ese eje. Las pruebas de ensayo de nubes con un promedio de 500 puntos dan las siguientes estadísticas con respecto a la desviación $D$ entre el ángulo del eje encontrado por el algoritmo y el verdadero ángulo del eje:
Nube perfecta:
$D \lt 1^\circ$: $100$%
Nube con 2% de puntos faltantes:
$D \lt 1^\circ$: $55$%
$D \lt 2^\circ$: $90$%
$D \lt 3^\circ$: $99$%
Discutiré áreas problemáticas al final de la publicación, pero primero el algoritmo.
Resumen del algoritmo
Para una nube 4-simétrica, al menos un eje de simetría debe existir dentro de cualquier sector de $45^\circ$, visto desde el centroide de la nube. En el extremo, habrá un eje al comienzo del sector y otro eje al final del sector. Un eje de simetría se caracteriza, en este caso, por el hecho de que todos los puntos dentro de un sector de $45^\circ$ a la "izquierda" del eje están reflejados por los puntos dentro de un sector de $45^\circ$ a la "derecha" del eje. Una forma muy simple (no robusta) de verificar si un eje en un ángulo dado es un eje de simetría, es ver si el número de puntos en el sector de $45^\circ$ a la izquierda del eje es igual al número de puntos en el sector de $45^\circ$ a la derecha del eje. Una mejor manera (que este algoritmo utiliza) es verificar si la suma de las distancias desde el centroide a los puntos en el sector de $45^\circ$ a la izquierda del eje, es igual a la suma de las distancias a los puntos en el sector de $45^\circ$ a la derecha del eje.
Por lo tanto, la idea básica del algoritmo es tener un eje que se mueva desde $91^\circ$ hasta $44^\circ$ en pasos de $1^\circ$, calculando la suma de las distancias a los puntos en el sector izquierdo y la suma de las distancias a los puntos en el sector derecho en cada paso, y comparando estas sumas. El ángulo del eje donde las sumas son "más iguales" es entonces el ángulo de simetría del algoritmo.
La razón para usar $91^\circ$ y $44^\circ$ en lugar de $90^\circ$ y $45^\circ$ es evitar problemas de redondeo. Además, uso sectores de $47^\circ$ (lo que significa que el sector izquierdo y derecho se superponen) en lugar de sectores de $45^\circ$ para evitar problemas con puntos que están en o cerca de la línea divisoria entre el sector izquierdo y el sector derecho.
Lo anterior obviamente no es un método robusto en general, pero para una nube donde se asume una simetría de 4 vías, funciona.
Algoritmo con detalles
Suponiendo que todos los puntos están en una matriz con coordenadas cartesianas:
-
Encuentra el centroide $(X_c, Y_c)$ de la nube.
-
Encuentra las coordenadas polares de cada punto, usando $(X_c, Y_c)$ como origen, y guarda los puntos que tienen un ángulo entre $91 + 46 = 137$ grados y $44 - 46 = -2$ grados en una nueva matriz $NewA$.
-
Ordena $NewA$ según el ángulo, de mayor a menor.
-
Recorre los ángulos $A$ desde $91^\circ$ hasta $44^\circ$ en pasos de $1^\circ$. En cada ángulo, calcula la suma de distancias para los puntos en el sector izquierdo (es decir, puntos con $ A - 1 \lt$ ángulo $\lt A + 46$) y compara con la suma de distancias para los puntos en el sector derecho (es decir, puntos con $ A + 1 \lt$ ángulo $\lt A - 46$).
-
El ángulo $A$ en el que esta comparación está más cerca de uno, es el ángulo del eje de simetría del algoritmo.
Áreas para mejorar
-
El algoritmo es sensible a "errores" en las coordenadas del centroide. Cuando faltan puntos o están desplazados, el centroide no está en la ubicación ideal (correcta).
-
El algoritmo también es algo sensible a los errores del 2% si ocurren principalmente en el primer y segundo cuadrante (de donde proviene la entrada de este algoritmo).
No estoy seguro de qué hacer con estos puntos.
0 votos
Esto puede ser útil: Determinación de ejes principales robusta para formas basadas en puntos utilizando la mediana menos significativa de cuadrados.
0 votos
¿Qué tal tomar un punto al azar y encontrar sus cuatro vecinos más cercanos, para ver si forman un patrón en forma de cruz?
0 votos
@Aretino: esto tiene sentido. En ciertos casos habrá complicaciones porque puede haber varias cuadrículas y/o irregularidades para que no todos los puntos formen una cruz.
0 votos
(1) ¿No tienes otro conjunto de simetrías rotadas 45 grados de tus 'ejes' negros? (2) ¿Has investigado qué sucede con la correlación al rotar?
0 votos
Quizás este enlace te pueda dar algo de inspiración. Aunque la descripción del algoritmo no es muy clara, el código fuente tiene muchos comentarios.
0 votos
Para aclarar, ¿estamos buscando ejes con simetría rotacional o con simetría de reflexión? ¿Podría la nube de puntos ser, por ejemplo, una esvástica, que es invariante mediante una rotación de $90^\circ$?
0 votos
@Jens: reflexivo.
0 votos
Encontraría los vectores de vecino más cercanos para todos los puntos, incluidos todos los vecinos más cercanos que estén a una distancia menor que $\sqrt{2}$ la distancia al vecino más cercano para ese punto. Si la mayoría de los puntos están en una red regular, digamos que $K$ puntos de $N$ están en una red regular, entonces solo necesitas considerar vecinos hasta una distancia $L$ donde al menos $K$ puntos tengan un vecino a una distancia $L$ o más cercana. Dado que conoces el número de puntos y la densidad aproximada de antemano, el método de celdas puede acelerar la búsqueda de vecinos hasta casi linealmente. Los vectores de vecino coinciden con los vectores básicos de la red, y por lo tanto con la orientación.
0 votos
@NominalAnimal: el patrón tal vez sea una combinación de retículas regulares y este enfoque podría fallar. De todas formas, dado que conocemos el patrón, tal vez un histograma de distancias/direcciones al vecino más cercano podría ayudar.
0 votos
@YvesDaoust: El histograma de direcciones suena como un enfoque muy robusto, pero tiene una precisión angular muy limitada (el ancho del bin no puede ser demasiado pequeño en comparación con el número de vectores, o no puedes detectar los picos de manera confiable). Creo que voy a considerar aplicar una estructura de datos de conjunto disjunto, ya sea fusionando los vectores $i$ y $j$ si $\vec{v}_i \cdot \vec{v}_j \ge \beta \lVert \vec{v}_i \rVert \lVert \vec{v}_j \rVert$ con $\beta$ ligeramente menor que 1; o agrupando los puntos primero en redes separadas. ¿Tienes alguna nube de puntos (¿no rotados?) con la que pueda jugar?