23/8/10

Ecuación paramétrica de la circunferencia

Por el tipo de aplicaciones que desarrollo es común requerir dibujar circunferencias, algo que es muy sencillo en los lenguajes en que lo he hecho, ya sea la instrucción “Circle” o “Ellipse” ya sea que reciba de parámetros el alto y ancho de la circunferencia, o ya sea que solicite el centro y el radio pero no es más que eso.

Sin embargo, también he tenido la necesidad de dibujar segmentos de circunferencias o tener que obtener N puntos que pertenezcan a la circunferencia algo que los lenguajes ya no proporcionan.

En al menos 4 ocasiones he programado la ecuación paramétrica de la circunferencia para obtener los puntos de una circunferencia o para agregarlos como lista de puntos. El proyecto en el que actualmente estoy trabajando lo vuelve a necesitar y aprovecharé para redactarlo aquí.

Empecemos imaginando que deseamos una circunferencia con centro en el punto (a,b) y radio r.
Esto se puede expresar en funciones trigonométricas de la siguiente forma:
x = a + r * cos (u)
y = b + r *sen (u)
“x” y “y” son las coordenada que deseamos obtener.
“a” es la coordenada x del centro de la circunferencia.
“b” es la coordenada y del centro de la circunferencia.
“r” es el radio.
“u” es el ángulo y va de [0,2PI] ; Es decir la circunferencia completa son 2 PI entonces dividimos 2PI para obtener algún punto en específico



Ahora que esto quedó claro vayamos al lenguaje de programación.
En esta ocasión utilizaré Silverlight y C# con Visual Studio 2010.

1. Creamos un proyecto nuevo
2. Dentro del Grid “LayoutRoot” vamos a agreagar un Grid llamado gridCirc y que tiene 80 de alto y 80 ancho.
3. Ahora agregamos un botón que mandará pintar nuestro semicírculo y le ponemos de nombre btnCirc con el texto Semicírculo
Va a quedar el MainPage.xaml así:


<     Grid x:Name="LayoutRoot" Background="White"      >
        <      Grid Height="80" HorizontalAlignment="Left" Margin="12,12,0,0" Name="gridCirc" VerticalAlignment="Top" Width="80" /         >
        <    Button Content="Pinta semicírculo" Height="24" HorizontalAlignment="Left" Margin="98,12,0,0" Name="btnCirc" VerticalAlignment="Top" Width="117" Click="btnCirc_Click" /       >
    <        /          Grid           >

4. Le damos doble clic al botón para que nos cree el método btnCirc_Click(object sender, RoutedEventArgs e) y podamos agregar nuestro código.
5. Agregamos un Polygon que contendrá los puntos de nuestra circunferencia y definimos el color y el color del contorno quedando así:


Polygon ptosCirc = new Polygon(); // El polígono que contendrá los puntos de la circunferencia
ptosCirc.Fill = new SolidColorBrush(Colors.Red); //el color de relleno
ptosCirc.Stroke = new SolidColorBrush(Colors.Black); // el color del contorno


6. Ahora necesitamos un PointCollection para almacenar los puntos que después le pasaremos al Polígono.


PointCollection ptosColeccion = new PointCollection(); 


7. Definimos cuantos puntos vamos a querer que tenga nuestra circunferencia, en este ejemplo 20.


int numPtos = 20;


8. Ahora necesitamos saber cada cuántos grados queremos un punto, es decir una circunferencia son 2 Pi, entonces tendremos que dividir los 2Pi entre el número de puntos, pero esto es para crear una circunferencia completa, en nuestro caso únicamente queremos media circunferencia entonces dividiremos Pi entre el número de puntos.


double siguiente = Math.PI / numPtos;

9. Definimos el centro de nuestra circunferencia:


System.Windows.Point centro = new System.Windows.Point(gridCirc.Width / 2, gridCirc.Height / 2);


10. Luego definimos donde queremos que inicie nuestra semicircunferencia, esto lo hacemos de nuevo dividiendo Pi.


double u = Math.PI + (Math.PI / 2); // esto iniciará como a las 12:00 es decir un la parte superior de la circunferencia.


11. Ahora vamos a recorrer los 20 puntos para calcular las x´s y las y´s de todos los puntos.


for (int i = 0; i <= numPtos; i++, u += siguiente)
{
System.Windows.Point Punto = new System.Windows.Point(centro.X + (gridCirc.Width / 2) * Math.Cos(u), centro.Y + (gridCirc.Height / 2) * Math.Sin(u));
ptosColeccion.Add(Punto);
}


12. Finalmente agregamos los puntos al polígono.


ptosCirc.Points = ptosColeccion;
gridCirc.Children.Add(ptosCirc);


13. Compilamos.

Ahora para el que lo quiere todo junto para copiar y pegar ahí les va como quedó el método:


private void btnCirc_Click(object sender, RoutedEventArgs e)
{
Polygon ptosCirc = new Polygon();
ptosCirc.Fill = new SolidColorBrush(Colors.Red);
ptosCirc.Stroke = new SolidColorBrush(Colors.Black);
PointCollection ptosColeccion = new PointCollection();
int numPtos = 20;
double siguiente = Math.PI / numPtos
System.Windows.Point centro = new System.Windows.Point(gridCirc.Width / 2, gridCirc.Height / 2);
double u = Math.PI + (Math.PI / 2
for (int i = 0; i <= numPtos; i++, u += siguiente)
{
System.Windows.Point Punto = new System.Windows.Point(centro.X + (gridCirc.Width / 2) * Math.Cos(u), centro.Y + (gridCirc.Height / 2) * Math.Sin(u));
ptosColeccion.Add(Punto);
}
ptosCirc.Points = ptosColeccion;
gridCirc.Children.Add(ptosCirc);
}

Al compilar y darle clic al botón les debe de pintar algo así:






FIN.