Kevin David Rosales Santana - [email protected]
-
Descripción del trabajo realizado
3.2 Decisiones en el desarrollo
-
3.2.1 Generación del Modelo 3D
-
3.2.2 Colores
-
3.2.3 Rotación
-
3.2.5 Menú
-
En la presente práctica se pedía implementar un Generador de Modelos 3D de Sólidos de Revolución, sirviendo para el aprendizaje de Processing, el cual tiene como objetivo facilitar los desarrollos con fines creativos en entornos digitales.
Dicho prototipo debe recoger puntos de un perfil del sólido de revolución al hacer click izquierdo con el ratón sobre la ventana. Dicho perfil es utilizado para crear un objeto 3D por medio de una superficie de revolución, almacenando la geometría resultante en una variable tipo PShape.
Por tanto, en este repositorio se tiene una implementación que incluye:
- Generación de sólidos de revolución de forma sucesiva.
- El modelo generado se mueve junto al ratón del usuario.
- Al pulsar click derecho tras generar el modelo 3D, se puede volver a generar otro.
- [Aportación Propia] Cambio de color del objeto 3D.
- [Aportación Propia] Rotación del objeto 3D.
- [Aportación Propia] Capacidad para eliminar el último punto del perfil del sólido de revolución.
- [Aportación Propia] Menú.
Para realizar este trabajo, se han creado estos cinco ficheros (presentes en la carpeta Practica2):
Fichero | Descripción |
---|---|
Practica2.pde | Fichero encargado de la interfaz gráfica del generador. Además, al ser el fichero principal, gestiona el setup() y el draw() del proyecto haciendo uso del resto de ficheros del este. Por último, incluye los gestores de eventos del teclado y del ratón. |
Controller.pde | Clase controlador. Se encarga de gestionar los nuevos puntos del perfil, de generar el sólido de revolución con el PShape del Modelo 3D, de administrar la limpieza del perfil o del último punto de este y de manejar el cambio de color y la rotación del sólido de revolución. |
Model2D.pde | Clase modelo que representa a un objeto Modelo 2D. Dicho objeto contiene la lista de puntos usados para generar el Modelo 3D. |
Model3D.pde | Clase modelo que representa a un objeto Modelo 3D. Dicho objeto contiene el PShape utilizado para representar el sólido de revolución. |
Point.pde | Clase modelo que representa a un objeto punto con precisión float. |
Tabla 1: Estructura de ficheros
A la hora de realizar el sólido de revolución se ha tenido que tomar una serie de decisiones respecto al desarrollo del proyecto. A continuación, se listarán dichas decisiones:
A la hora de generar el sólido de revolución, se recogen los puntos que el usuario ha introducido previamente para formar un perfil del sólido de revolución. A continuación, utilizando PShape con TRIANGLE_STRIP, se va formando el modelo 3D con los triángulos de dichos puntos.
Cada triángulo se forma gracias a que los puntos del perfil del sólido de revolución se rotan usando las siguientes fórmulas (recogidas de indicaciones de la práctica (referencia 1)):
Teniendo en cuenta que los puntos del perfil tienen z = 0
y que las coordenadas originales se sitúan en la mitad derecha del generador (con lo que es necesario situarlo alrededor x=0
restándole width/2
), el código generador de los vértices resulta de esta manera:
void fillVertex() {
PShape sor = model3d.getSor();
ArrayList<Point> points = model2d.getPoints();
float px, py, pz, pxNext, pyNext, pzNext, px2, pz2, pxNext2, pzNext2;
for (int i = 0; i < points.size()-1; i++) {
px = points.get(i).getX() - width/2;
py = points.get(i).getY();
pz = points.get(i).getZ();
pxNext = points.get(i+1).getX() - width/2;
pyNext = points.get(i+1).getY();
pzNext = points.get(i+1).getZ();
for (float j = 0; j < TWO_PI + 0.1; j += theta) {
px2 = px * cos(theta) - pz * sin(theta);
pz2 = px * sin(theta) + pz * cos(theta);
pxNext2 = pxNext * cos(theta) - pzNext * sin(theta);
pzNext2 = pxNext * sin(theta) + pzNext * cos(theta);
sor.vertex(px2, py, pz2);
sor.vertex(pxNext2, pyNext, pzNext2);
px = px2;
pz = pz2;
pxNext = pxNext2;
pzNext = pzNext2;
}
}
sor.endShape();
}
Fragmento de Código 1: Generación del Modelo 3D con PShape
La razón por la que la condición del for
es j <= TWO_PI + 0.1
es debido a que se deben tratar los 360º (más un pequeño solapamiento para evitar huecos en el modelo 3D resultante). Theta
, que mide la cantidad de rotación, definirá el número de triángulos finales. El valor theta
con el que se entrega el proyecto es TWO_PI/50
.
La parte imprescindible de la generación del modelo 3D es que los puntos deben estar intercalados para que, mediante la técnica de TRIANGLE_STRIP se puedan formar correctamente los triángulos.
Como aportación propia, se le permite al usuario que cambie el color del Modelo 3D . Para ello, tan solo debe (como el menú informa) pulsar las flechas izquierda y derecha del teclado (← y →) cuando genere el modelo.
Modelo de color verde | Modelo de color violeta |
---|---|
Tabla 2: Colores en el Modelo 3D
Para lograr este cambio de color, se almacena en una matriz colors
el RGB de 7 colores (ver fichero Model3D.pde). Tras ello, se cambia el color haciendo uso de setFill(color(R,G,B))
Para implementar la rotación, se ha hecho uso del mismo sistema de gestión de eventos de teclado que se usó para el Pong. Es decir, mediante unas variables de estado del modelo 3D (isUpPressed
, isDownPressed
, isLeftPressed
, isRightPressed
) se gestiona cómo se quiere realizar la rotación.
La rotación se realiza usando el método rotateX(angle)
y rotateY(angle)
:
void rotate3dModel(){
PShape sor = model3d.getSor();
if (model3d.isDownPressed) sor.rotateX(0.01);
if (model3d.isUpPressed) sor.rotateX(-0.01);
if (model3d.isLeftPressed) sor.rotateY(0.01);
if (model3d.isRightPressed) sor.rotateY(-0.01);
}
Fragmento de Código 2: Rotación del Modelo 3D con PShape
Así pues, pulsando (como el menú informa) las teclas A
, W
, S
y D
se puede rotar el modelo:
Fase A | Fase B | Fase C | Fase D |
---|---|---|---|
Tabla 3: Rotaciones en el Modelo 3D
Se debe tener en cuenta que para que el modelo 3D, al ser creado, siga de forma apropiada al ratón y al ser rotado no supere en exceso los límites de la ventana, se ha tenido que programar un translate
tal que: translate(mouseX, mouseY-500, -100)
.
Para favorecer al principio de Jakob Nielsen Control y libertad del usuario, se le da la posibilidad al usuario de pulsar la tecla Retroceso para eliminar el último punto que ha insertado en el perfil del sólido de revolución.
Se ha desarrollado un menú previo al generador que introduce a los usuarios al sistema y les informa sobre sus controles:
Para realizar este menú, se han seguido las indicaciones de la referencia de Processing (Referencia 2). Por ello, se realiza un noLoop()
al ejecutar el setup()
, evitando que se ejecute en bucle el draw()
. Además, se dibuja el menú que se puede observar en la Figura 3.
Al pulsar ENTER
, se llama a loop()
(reanudando el bucle del draw()
) y se desactiva el "Modo menú" que no permitía acceder al contenido del draw()
.
Nota importante: Para pulsar ENTER
, la ventana de este debe estar focuseada.
La idea de que los controles no aparezcan siempre a la hora de hacer el perfil del sólido de revolución o de observar el modelo 3D generado es no llenar al usuario de información por pantalla. Por ello, si quiere volver a ver los controles si tiene cualquier duda tan solo debe pulsar 'M' como se ve en las siguientes imágenes:
Perfil | Modelo 3D |
---|---|
Tabla 4: Opciones para visualizar el menú y controles
Los procesos realizados tras ir al menú y volver no se pierden.
Esta práctica ha servido como aprendizaje para Processing y, además, se ha tratado de una práctica muy entretenida donde se ha tenido contacto con una herramienta que permite facilitar el tipo de desarrollos similares al visto en este proyecto.
Además, realizar este tipo de trabajos da una idea lo pragmáticas que resultan este tipo de técnicas para desarrollar modelos 3D.
Por último, se debe recalcar que gracias a esta segunda práctica de Creando Interfaces de Usuario, se ha podido estudiar el manejo del PShape, incluyendo su generación, movimiento o, en este caso, rotación.
Para ejecutar este proyecto, es necesario:
- Tener instalado Processing (Referencia 3)
Para ejecutar el proyecto, tan solo se debe abrir el fichero Practica2.pde y darle al botón de ejecutar.
- [1] Modesto Fernando Castrillón Santana, José Daniel Hernández Sosa. Creando Interfaces de Usuario. Guion de Prácticas
- [2] Processing Foundation. Processing Reference.
- [3] Processing Foundation. Processing Download.
- [4] Extrapixel. GifAnimation Processing Library.