Ejercicio obligatorio 2

Fecha de entrega: Viernes 22 de abril

Introducción

Polilíneas

Una polilínea es una sucesión de segmentos de rectas en \(\mathbb R^2\) y puede ser construída a partir de una sucesión de puntos. Una polilínea de \(n - 1\) segmentos se construye a partir de \(n\) puntos.

En el lenguaje de programación C podemos representar este vector de puntos utilizando una matriz float [N][2] como se muestra en el siguiente esquema:

../_images/20221_ej2.png

Distancia de punto a segmento de recta

Para determinar la distancia de un punto \(\vec P = (p_x, p_y)\) a un segmento de recta \(\overline{AB}\) dados por dos puntos \(\vec A = (a_x, a_y)\) y \(\vec B = (b_x, b_y)\), y asumiendo que la longitud de \(\overline{AB}\) es distinta de cero, puede computarse:

\[\alpha = \frac{\left(\vec P - \vec A \right) \cdot \left(\vec B - \vec A \right)}{\left\lVert \vec B - \vec A \right\rVert^2}.\]

Si el parámetro \(\alpha \leq 0\) entonces el punto del segmento más cercano a \(\vec P\) es el punto \(\vec A\), si \(\alpha \geq 1\) el punto más cercano será \(\vec B\), y en el caso de que \(0 < \alpha < 1\) el punto más cercano estará dado por \(\vec A + \alpha \left( \vec B - \vec A \right)\).

Sabiendo cuál es el punto del segmento más cercano a \(\vec P\) se puede calcular esa distancia que será la distancia deseada.

Implementación

Traslación de puntos

Se pide implementar una función void trasladar(float polilinea[][2], size_t n, float dx, float dy); que, dado un vector polilinea con n puntos y el formato ya descrito modifique cada una de sus componentes mediante la adición del par (dx, dy).

Rotación de puntos

Se pide implementar una función void rotar(float polilinea[][2], size_t n, double rad); que dada una polilinea rote cada una de ella rad radianes con respecto al origen de coordenadas.

Nota

Recordar que para rotar un par de coordenadas \((x, y)\) un ángulo \(\theta\) se debe realizar la operación:

\(\begin{bmatrix}x' \\y' \\\end{bmatrix} = \begin{bmatrix}\cos \theta & -\sin \theta \\\sin \theta & \cos \theta \\\end{bmatrix}\begin{bmatrix}x \\y \\\end{bmatrix}\).

La operación puede descomponerse como:

\(x' = x \cos \theta - y \sin \theta\),

\(y' = x \sin \theta + y \cos \theta\).

Distancia de punto a polilínea

Se pide implementar una función double distancia_punto_a_polilinea(const float polilinea[][2], size_t n, float px, float py); que dada una polilinea y un punto \(P\) de coordenadas (px, py) calcule la distancia del punto a la polilínea.

Nota

Es recomendable construir funciones auxiliares para realizar este proceso.

Pruebas

Teniendo la poliínea \([(0, 1), (1, 3), (1, 5), (2, 5), (3, 4), (4, 4), (5, 3), (4, 2), (5, 1), (2, 0)]\) y además los puntos \([(0, 0), (0, 2), (6, 1), (2, 2), (1, 1), (1, 4), (5, 4), (-1, -3), (3, 3), (5, 3), (0, 7)]\) las distancias de cada uno de esos puntos a la polilínea respectivamente son:

1.0000000000
0.4472136322
1.0000000000
1.3416407687
0.8944271977
0.0000000000
0.7071067812
4.1231056256
1.0000000000
0.0000000000
2.2360679775

llamar a la función distancia_punto_a_polilinea() con TODOS estos valores, validar que la distancia sea correcta (notar que la misma está expresada con diez dígitos, no se espera un valor exacto a los 16 dígitos del double) e imprimir un mensaje de error si alguno de los puntos no valida lo esperado.

Nota

Se estima que se pueden validar hasta 7 dígitos de estos valores, no más por acarreo de diferencias en las diferentes implementaciones.

Queda del lado del alumno probar las funciones trasladar() y rotar().

El main() del programa deberá correr los casos de prueba dados.

Entrega

Deberá entregarse el código fuente del programa desarrollado.

El programa debe compilar correctamente con los flags:

-Wall -Werror -std=c99 -pedantic

y validar los ejemplos dados.

La entrega se realiza a través del sistema de entregas.

El ejercicio es de entrega individual.