Las siguientes funciones se basan en la herramienta de las coordenadas polares, con las que en lugar de ubicar un punto de acuerdo a coordenadas x
, y
, z
(distancia al origen paralela a cad eje), lo ubicamos de acuerdo a un radio (distancia al centro) y a un ángulo respecto a una referencia.
Estas son las fórmulas para convertir coordenadas polares r,a
con centro en cx,cy
, a coordenadas rectangulares x,y
.
// calcula coordenadas rectangulares x,y a partir de:
// r: radio
// a: ángulo
// cx,cy: centro / punto de referencia
float x = r*cos(a) + cx;
float y = r*sin(a) + cy;
Las siguientes funciones aprovechan el modo de dibujo TRIANGLE_FAN
y la conversión de coordenadas polares a rectangulares para dibujar distintas mallas cónicas.
Esta función dibuja un cono de radio r, altura h, y una base con N lados.
void cono(float r, float h, int N){
// dibuja un cono tradicional
// r: radio de la base
// h: altura
// N: número de divisiones en la base
// variables auxiliares:
float x,y;
beginShape(TRIANGLE_FAN);
vertex(0,0,h); // vértice de la punta
// ciclo para los vértices de la base
for(float angulo=0; angulo<=TWO_PI; angulo=angulo+TWO_PI/N){
cos(angulo);
x = r*sin(angulo);
y = r*vertex(x,y,0);
}endShape();
}
Aquí se le suma o resta una cantidad aleatoria al radio que le corresponde a cada vértice.
Los parámetros son el radio r, altura h, una base con N lados, y un rango de cuánto puede variar el radio.
void cono(float r, float h, int N, float rango){
// dibuja un cono con base pseudoaleatoria
// r: radio de la base
// h: altura
// N: número de divisiones en la base
// rango: cuánto puede variar el radio hacia arriba y hacia abajo
int seed = 100;
randomSeed(seed);
// variables auxiliares:
float x,y,angulo,radio;
beginShape(TRIANGLE_FAN);
vertex(0,0,h); // vértice de la punta
// ciclo para los vértices de la base
for(int i=0;i<=N;i=i+1){
angulo = i*TWO_PI/N;random(-rango, rango);
radio = r + cos(angulo);
x = radio*sin(angulo);
y = radio*vertex(x,y,0);
if(i==N-1){ randomSeed(seed); }
}endShape();
}
En este ejemplo se utiliza una función senoidal para ir cambiando de manera continua y periódica la magnitud del radio.
Los parámetros son el radio r, altura h, una base con N lados, un rango de cuánto puede variar el radio, y un número de ciclos/picos nciclos que existirán en la base.
void cono(float r, float h, int N, float rango, int nciclos){
// dibuja un cono con base periódica
// r: radio de la base
// h: altura
// N: número de divisiones en la base
// rango: cuánto puede variar el radio hacia arriba y hacia abajo
// nciclos: cuántos ciclos/picos tiene la base
// variables auxiliares:
float x,y,angulo,radio;
beginShape(TRIANGLE_FAN);
vertex(0,0,h); // vértice de la punta
// ciclo para los vértices de la base
for(int i=0;i<=N;i=i+1){
angulo = i*TWO_PI/N;sin( i*TWO_PI*nciclos/N );
radio = r + rango*cos(angulo);
x = radio*sin(angulo);
y = radio*vertex(x,y,0);
}endShape();
}
En estos ejemplos se aprovecha el modo de dibujo QUAD_STRIP y la conversión de coordenadas polares a rectangulares para establecer mallas cilíndricas.
Esta función recibe tres parámetros: r para el radio, h para la altura, y N para el número de lados en la base/tapa.
void cilindro(float r, float h, int N){
// dibuja un cilindro tradicional
// r: radio de la base
// h: altura
// N: número de divisiones en la base
// variables auxiliares
float x,y;
beginShape(QUAD_STRIP);
for(float angulo=0; angulo<=TWO_PI; angulo=angulo+TWO_PI/N){
cos(angulo);
x = r*sin(angulo);
y = r*// vértice en la base
vertex(x,y,0);
// vértice en la tapa
vertex(x,y,h);
}endShape();
}
Esta función permite determinar el ángulo de inicio y fin del cilindro. Nota que los ángulos se especifican en radianes.
void cilindro(float r, float h, int N, float anguloInicial, float anguloFinal){
// dibuja un cilindro tradicional, en un rango específico de ángulo
// r: radio de la base
// h: altura
// N: número de divisiones en la base
// anguloInicial: a partir de qué ángulo empieza el cilindro (en radianes)
// anguloFinal: en qué ángulo termina el cilindro (en radianes)
// variables auxiliares
float x,y;
beginShape(QUAD_STRIP);
for(float angulo=anguloInicial; angulo<=anguloFinal; angulo += (anguloFinal-anguloInicial)/N){
cos(angulo);
x = r*sin(angulo);
y = r*// vértice en la base
vertex(x,y,0);
// vértice en la tapa
vertex(x,y,h);
}endShape();
}
Esta función recibe cuatro parámetros: r para el radio, h para la altura, N para el número de lados en la base/tapa, y rango para cuánto puede variar el radio.
void cilindro(float r, float h, int N, float rango){
// dibuja un cilindro con base pseudoaleatoria
// r: radio de la base
// h: altura
// N: número de divisiones en la base
// rango: cuánto puede variar el radio hacia arriba y hacia abajo
// variables auxiliares
float x,y,angulo,radio;
int seed = 100;
randomSeed(seed);
beginShape(QUAD_STRIP);
for(int i=0; i<=N; i=i+1){
angulo = i*TWO_PI/N;random(-rango, rango);
radio = r + cos(angulo);
x = radio*sin(angulo);
y = radio*// vértice en la base
vertex(x,y,0);
// vértice en la tapa
vertex(x,y,h);
if(i==N-1){ randomSeed(seed); }
}endShape();
}
Esta función recibe cinco parámetros: r para el radio, h para la altura, N para el número de lados en la base/tapa, rango para cuánto puede variar el radio, y nciclos para indicar cuántos picos tendrá la base/tapa.
void cilindro(float r, float h, int N, float rango, int nciclos){
// dibuja un cilindro con base periódica
// r: radio de la base
// h: altura
// N: número de divisiones en la base
// rango: cuánto puede variar el radio hacia arriba y hacia abajo
// nciclos: cuántos ciclos/picos tiene la base
// variables auxiliares
float x,y,angulo,radio;
beginShape(QUAD_STRIP);
for(int i=0; i<=N; i=i+1){
angulo = i*TWO_PI/N;sin( i*TWO_PI*nciclos/N );
radio = r + rango*cos(angulo);
x = radio*sin(angulo);
y = radio*// vértice en la base
vertex(x,y,0);
// vértice en la tapa
vertex(x,y,h);
}endShape();
}
Esta función recibe seis parámetros: r para el radio, h para la altura, N para el número de lados en la base/tapa, rango para cuánto puede variar el radio, nciclos para indicar cuántos picos tendrá la base/tapa, y fase para indicar el desfase entre la base y la tapa.
void cilindro(float r, float h, int N, float rango, int nciclos, float fase){
// dibuja un cilindro con base periódica
// r: radio de la base
// h: altura
// N: número de divisiones en la base
// rango: cuánto puede variar el radio hacia arriba y hacia abajo
// nciclos: cuántos ciclos/picos tiene la base
// fase: cuánto está desfasada (en radianes) la tapa de la base
// variables auxiliares
float x,y,angulo,radio;
beginShape(QUAD_STRIP);
for(int i=0; i<=N; i=i+1){
angulo = i*TWO_PI/N;sin( i*TWO_PI*nciclos/N );
radio = r + rango*cos(angulo);
x = radio*sin(angulo);
y = radio*// vértice en la base
vertex(x,y,0);
sin( i*TWO_PI*nciclos/N + fase);
radio = r + rango*cos(angulo);
x = radio*sin(angulo);
y = radio*// vértice en la tapa
vertex(x,y,h);
}endShape();
}
Estas mallas son modificación de las cilíndricas, con la posibilidad de cambiar el radio y/o la forma de la base respecto a la tapa
En esta malla se puede cambiar el radio de la base y de la tapa.
Los parámetros que recibe con: r1 para el radio de la base, r2 para el radio de la tapa, h para la altura, y N para el número de lados en base y tapa.
void cilindroCono(float r1, float r2, float h, int N){
// dibuja un cilindro con base y tapa de diferente radio
// r1: radio de la base
// r2: radio de la tapa
// h: altura
// N: número de divisiones en la base/tapa
// variables auxiliares
float x,y,angulo;
beginShape(QUAD_STRIP);
for(int i=0; i<=N; i++){
angulo = i*TWO_PI/N;cos(angulo);
x = r1*sin(angulo);
y = r1*// vértice en la base
vertex(x,y,0);
cos(angulo);
x = r2*sin(angulo);
y = r2*// vértice en la tapa
vertex(x,y,h);
}endShape();
}
Esta versión de la función permite especificar el ángulo inicial y final de la figura. Nota que los ángulos son en radianes:
void cilindroCono(float r1, float r2, float h, int N, float anguloInicial, float anguloFinal) {
// dibuja un cilindro con base y tapa de diferente radio
// r1: radio de la base
// r2: radio de la tapa
// h: altura
// N: número de divisiones en la base/tapa
// anguloInicial: a partir de qué ángulo empieza el cilindro (en radianes)
// anguloFinal: en qué ángulo termina el cilindro (en radianes)
// variables auxiliares
float x, y;
beginShape(QUAD_STRIP);
for (float angulo=anguloInicial; angulo<=anguloFinal; angulo += (anguloFinal-anguloInicial)/N) {
cos(angulo);
x = r1*sin(angulo);
y = r1*// vértice en la base
vertex(x, y, 0);
cos(angulo);
x = r2*sin(angulo);
y = r2*// vértice en la tapa
vertex(x, y, h);
}endShape();
}
En esta malla la tapa y la base son figuras periódicas, con diferente radio, rango de cambio de radio, y número de picos/ciclos.
Los parámetros que recibe con: r1 para el radio de la base, r2 para el radio de la tapa, h para la altura, N para el número de lados en base y tapa, rango1 para indicar cuánto cambia el radio de la base, rango2 para indicar cuánto cambia el radio de la tapa, nciclos1 para indicar cuántos picos tiene la base, y nciclos2 para indicar cuántos picos tiene la tapa.
void cilindroCono(float r1, float r2, float h, int N, float rango1, float rango2, int nciclos1, int nciclos2){
// dibuja un cilindro con base y tapa de diferente radio y diferente rango
// r1: radio de la base
// r2: radio de la tapa
// h: altura
// N: número de divisiones en la base/tapa
// rango1: cuánto puede variar el radio de la base hacia arriba y hacia abajo
// rango2: cuánto puede variar el radio de la tapa hacia arriba y hacia abajo
// nciclos1: cuántos ciclos/picos tiene la base
// nciclos2: cuántos ciclos/picos tiene la tapa
// variables auxiliares
float x,y,angulo,radio;
beginShape(QUAD_STRIP);
for(int i=0; i<=N; i++){
angulo = i*TWO_PI/N;sin( i*TWO_PI*nciclos1/N);
radio = r1 + rango1*cos(angulo);
x = radio*sin(angulo);
y = radio*// vértice en la base
vertex(x,y,0);
sin( i*TWO_PI*nciclos2/N);
radio = r2 + rango2*cos(angulo);
x = radio*sin(angulo);
y = radio*// vértice en la tapa
vertex(x,y,h);
}endShape();
}