Universidad de Costa Rica. Escuela de Computación. CI-0113 Programación II
2018a. Grupo 05. Examen 02 [30-Jun-2018]. Profesor Jeisson Hidalgo-Céspedes.
# Polígono
El polígono es un concepto matemático que tiene mucha utilidad en diversidad de aplicaciones. Por citar algunos ejemplos: para calcular el área de terrenos, para perforar el centro de una pieza industrial, y para dibujar figuras en una aplicación de diseño gráfico.
Matemáticamente un **polígono** (*polygon*) es una figura geométrica que está delimitada por una secuencia finita de segmentos rectilíneos consecutivos que encierran una región en el plano. A estos segmentos se les llaman **lados** (*edge* o *side*), y los puntos en los que se intersecan se llaman **vértices** (singular: *vertex*, plural: *vertices*). Un polígono requiere al menos tres lados (triángulo). Los lados del polígono se pueden o no intersecar.
Se necesita una plantilla para generar clases `Polygon`, las cuales representam polígonos de una cantidad arbitraria de lados. La plantilla debe satisfacer los siguientes requerimientos:
1. [15%] Representar el polígono como una colección de vértices. Dado que un polígono es una figura plana, los vértices se componen de dos coordenadas $x$ y $y$. El tipo de datos de las coordenadas debe ser arbitrario, ya que sólo lo conoce el usuario de la plantilla. Por ejemplo, podrían representarse por tipos de aritmética de punto fijo cortos (`short int`), largos (`long long`), aritmética flotante (`float`, `double`, `long double`), tipos propios como fracciones (`Fraction`), o tipos de una biblioteca de aritmética de precisión arbitraria. Debe justificar con un comentario corto, la estructura de datos escogida para representar el polígono.
2. [5%] El usuario de la clase podría o no conocer la cantidad de vértices del polígono. La plantilla debe proveer un constructor que permita crear polígonos vacíos si no se conoce esta cantidad, o aprovecharla con fines de eficiencia en caso de que el usuario la conozca. En su diseño debe cuestionarse si tiene sentido convertir eneros en polígonos.
3. [20%] La cantidad de vértices que podría tener el polígono se conoce en tiempo de ejecución y podría ser gigantesca, por tanto debe alojarlos en memoria dinámica. Debe permitir a los usuarios de la clase crear copias de los polígonos, por ejemplo, para almacenarlos en contenedores. Por tanto, su implementación debe evitar fugas de memoria y accesos inválidos.
4. [10%] Se necesita poder agregar dinámicamente vértices al polígono, por ejemplo, cuando un usuario está dibujando un polígono en una aplicación de diseño gráfico. Implemente un método `addVertex(x,y)` para este fin.
5. [15%] Se necesita poder acceder a los vértices del polígono. Implemente un método `vertexCount()` que retorne la cantidad de vértices en el polígono. Provea un método `x(i)` que permita acceder a la coordenada $x$ del vértice $i$ del polígono. De forma análoga, provea un método `y(i)` que permita acceder a la coordenada $y$ del vértice $i$ del polígono. Debe prover versiones de sólo-lectura y lectura-escritura de ambos métodos. Dado que el polígono es una figura cerrada de $n$ vértices, el vértice en la posición 0 es el mismo que el vértice en la posición $n$.
6. [10%] Implemente una plantilla para generar métodos `area()` que calculan el área con signo del polígono. El tipo de datos de retorno del área (`AreaType`) podría ser distinto del tipo de datos de las coordenadas de los vértices, por tanto, se debe recibir por parámetro de la plantilla. Por ejemplo, si se tiene un polígono de enteros, el área no necesariamente será un entero. Haga que este parámetro sea opcional. Si el invocador no lo especifica, asuma el tipo de datos de las coordenadas de los vértices. El área con signo de un polígono se calcula con la relación:
$$A = \frac{1}{2} \sum\_{i=0}^{n-1}{\left(x\_i y\_{i+1} - x\_{i+1} y\_i\right)}$$
7. [15%] Implemente una plantilla para generar métodos `centroidX()` y `centroidY()` que calculan las coordenadas del centroide del polígono. El tipo de datos de las coordenadas del centroide podrían ser distintas a las coordenadas de los vértices, de la misma forma que ocurre con el método de `area`, por tanto, debe recibir este tipo de datos por parámetro de la plantilla. Las coordenadas $(x\_c, y\_c)$ del centroide se calculan con las relaciones:
$$x\_c = \frac{1}{6A} \sum\_{i=0}^{n-1}{\left(x\_i + x\_{i+1}\right) \left(x\_i y\_{i+1} - x\_{i+1} y\_i\right)}$$
$$y\_c = \frac{1}{6A} \sum\_{i=0}^{n-1}{\left(y\_i + y\_{i+1}\right) \left(x\_i y\_{i+1} - x\_{i+1} y\_i\right)}$$
En el polígono de la figura de arriba, el centroide se ubica en las coordenadas `(-1.66, 0.49)`. Se llama centroide o centro de gravedad porque puede estar fuera de la figura en caso de un polígono cóncavo.
8. [10%] Sobrecargue el operador `>>` para leer un polígono de la entrada brindada. Deberá leer vértices repetidamente hasta que se acaben. Por ejemplo, las coordenadas de abajo generan el polígono de la figura de arriba. Sobrecargue el operador `<<` para imprimir los vértices del polígono en la salida brindada, en formato `(x1, y1), (x2, y2), ..., (xn, yn)`.
```
0 2
-2 8
-6 1
-4 -6
6 2
```
Para efectos de esta evaluación, no debe utilizar contenedores de la biblioteca estándar, sino que debe crear su propio contenedor. Recuerde en cada punto anterior implementar buenas prácticas de programación.