Algoritmos: Dados n puntos en un plano, ¿cuál es el ángulo más pequeño por el cual se debe rotar el plano para que al menos dos puntos tengan la misma coordenada x después de la rotación?

Nota: La siguiente solución hace que [math] y [/ math] -coordinates sea igual, la solución para hacer [math] x [/ math] -coordinates seguirá siendo la misma con alguna transformación de coordenadas.

Digamos que dos puntos [matemática] (x_1, y_1) [/ matemática] y [matemática] (x_2, y_2) [/ matemática] tendrán la misma [matemática] y [/ matemática] -coordinada después de la rotación, lo que significa que rotamos el plano por un ángulo [math] \ textrm {tan} ^ {- 1} (\ frac {| y_2-y_1 |} {| x_2-x_1 |}) [/ math]. Entonces, queremos el valor más pequeño de [math] \ frac {| y_2-y_1 |} {| x_2-x_1 |} [/ math] para todos los pares de puntos.

Imagine un punto [matemático] (x_i, y_i) [/ matemático], digamos que puse una varilla horizontal con el centro en [matemático] (x_i, y_i) [/ matemático] y se extiende hacia negativo [matemático] x [/ matemático] -eje. Si lo giro en el sentido de las agujas del reloj, quiero saber cuál es el primer punto [matemático] (x_j, y_j) [/ matemático] que toca de tal manera que [matemático] y_j \ ge y_i [/ ​​matemático]. Del mismo modo, si giro esta barra en sentido antihorario, quiero saber cuál es el primer punto [matemático] (x_j, y_j) [/ matemático] que toca de tal manera que [matemático] y_j \ le y_i [/ ​​matemático] . Llamemos a estos ángulos de tocar como ángulos arriba y abajo. Tenga en cuenta que esto cubrirá todos los pares de puntos.

Ahora, algunas observaciones básicas lo ayudarán. Considere esta imagen donde hemos ordenado todos los puntos de acuerdo con sus coordenadas [matemáticas] y [/ matemáticas]. Considere un nuevo orden de estos puntos como [matemática] p_1, p_2, …, p_n [/ matemática].

Digamos que estamos calculando dos ángulos más pequeños hacia arriba y hacia abajo para el punto [math] p_i [/ ​​math]. Al calcular estos ángulos, podemos ignorar con seguridad los puntos que no están en el casco convexo rojo de los puntos [matemática] p_1, p_2, …, p_i [/ ​​matemática]; de manera similar, también podemos ignorar los puntos que no están en el casco convexo azul de los puntos [math] p_i, p_ {i + 1}, …, p_n [/ math]. Además, el ángulo ascendente que estamos viendo está definido por el punto que viene después de [math] p_i [/ ​​math] en el casco convexo azul y el ángulo descendente similar está definido por el punto que viene justo antes de [math] p_i [/ ​​math] en casco convexo rojo.

Ahora, esto se puede resolver fácilmente utilizando el algoritmo Monotone Chain Convex Hull en [math] O (n) [/ math], manteniendo dos pilas, una para los cascos convexos rojos y otros azules. Estoy iterando sobre todo [matemáticas] i [/ matemáticas]. La razón es que la complejidad es general [matemática] O (n) [/ matemática] debido al algoritmo de Andrew en el que mantenemos dos pilas que en cada paso mantienen dos cascos convexos: uno para los puntos [matemática] [1, i] [/ matemática] y otra para puntos [matemática] [i, n] [/ matemática]. La transformación de [matemáticas] i [/ matemáticas] a [matemáticas] i + 1 [/ matemáticas] y viceversa se amortiza el tiempo constante en el algoritmo de Andrew.

Es suficiente encontrar un par de puntos para los cuales se maximiza la magnitud de la pendiente de la línea que los conecta. Primero ordenemos los puntos por sus coordenadas [matemáticas] x [/ matemáticas]. Esa operación se puede hacer en [math] O (n \ log {n}) [/ math]. Ahora podemos observar que el par para el cual se maximiza la magnitud de la pendiente debe ser consecutivo. Supongamos, por el contrario, que hay un punto con una coordenada intermedia [matemática] x [/ matemática] entre las del par maximizador. Entonces, la línea desde ese punto intermedio a uno de los otros dos debe tener una pendiente de magnitud mayor o igual a la de la línea entre los dos originales, y puede ser igual solo si el punto intermedio cae en la línea que conecta la maximización par (contradiciendo uno de los detalles sobre los puntos). Por lo tanto, solo necesitamos una búsqueda lineal en el tiempo de los puntos ordenados para encontrar el par consecutivo con la magnitud máxima de la pendiente.

La suposición de que no hay 3 puntos colineales es una especie de arenque rojo, ya que, incluso sin eso, aún sería cierto que hay un par consecutivo que maximiza la magnitud de la pendiente. Entonces, se supone que no hay dos puntos que tengan la misma coordenada [matemática] x [/ matemática], ya que un ángulo de [matemática] 0 [/ matemática] es una respuesta razonable; pero tendría que verificarlo como un caso especial para evitar dividirlo por cero.