3D en C

Iniciado por @synthesize, 16 Julio 2010, 03:47 AM

0 Miembros y 1 Visitante están viendo este tema.

@synthesize

(Directamente desde mi blog)

Cualquier persona puede creer que hacer gráficos en 3 dimensiones, programando en C, es algo absurdo e innecesario. Pero, realmente es algo útil, pues con el mas simple ejemplo de rotar un cubo, tenemos que aplicar operaciones con 8 vértices a la vez, ala par de controlar zonas visibles, etc.

Y ya que hablábamos del cubo, vamos a poner ejemplos, en primer lugar, con un cubo.

Antes de empezar, decir que trabajamos con la cabecera graphics.h desde Borland C++ 3.1 (No es estándar, desgraciadamente).

Una vez tengamos el entorno preparado, debemos clasificar nuestro programa en 2 partes: Operaciones y database.

En operaciones, evidentemente, haremos las operaciones básicas del cubo, crearlo, moverlo, etc.

En database, almacenaremos los distintos valores que necesitemos: En el caso de un cubo, nos sobra con las posiciones de los vértices. Si deseamos crear movimiento en el cubo, necesitamos que nuestros datos sean completamente accesibles (No usar constantes) y a ser posible, poder acceder lo mas rápidamente a ellos. Por ello, una de las mejores es crear estructuras para cada uno de los objetos (No confundir con objetos de POO).

Por lo cual, para dibujar un cubo, necesitaremos mínimo 8 vértices, los cuales podemos crear de esta forma:

   typedef struct vertices
   {
   int ver0;
   int ver1;
   int ver2;
   int ver3;
   int ver4;
   int ver5;
   int ver6;
   int ver7;
   } vertices;



También podríamos crearlo con punteos para optimizar el rendimiento. Y para los mas vagos, podemos crear solamente un vector de la siguiente forma:

   int vertices[8];

Tras definir esta parte (la base de datos para el objeto) debemos pasar a construirlo. Para ello debemos distinguir 2 partes, el cuadrado superior y el inferior.

Al superior, le corresponden los vértices del 0 al 3, y al inferior, del 4 al 7.



Para dibujarlo, nos basta con usar la función line. Una línea del vértice 0 al 1 y del 0 al 2. Por igual, otra del 3 al 2 y del 3 al 1. La misma operación con el cuadrado inferior. Para terminar el cubo, faltan 4 líneas, uniendo los vértices: Del 0 al 4, del 2 al 6, del 1 al 5 y del 3 al 7.

Una vez formado, podemos modificar su forma, o moverlo, modificando los valores sobre la base de datos, pero, ¿Cómo hacemos para eliminar la parte oculta?


Métodos de Espacio-Objeto

Hay varios métodos para eliminar las "Partes traseras" de nuestros objetos. Y es que, como comprenderéis, no es necesario mantener algo que no vemos.

Método 1: Preclasificación Radial: El mas sencillo, si conocemos con adelanto la dirección desde la cual será visto el objeto, el programa solo creará las partes visibles.

Pros: Ahora memoria y optimiza la velocidad.
Contras: Incapacidad de rotar y ver el objeto desde otros ángulos de visión.

Método 2: Clasificación Radial: El programa determina que partes son visibles y cuales no, dependiendo del ángulo de visión. Esto se calcula, generalmente (Aunque no únicamente) con la posición de los vértices.

Pros: Rápida ejecución.
Contras: Hace demasiado uso de la base de datos, lo que puede llegar a ser pesado.

Método 3: Ecuación del plano: Utilizando el producto vectorial, es posible determinar la posición de los planos, por lo que el programa puede determinar que parte mostrar y cual no.

Pros: Hace poco uso de la base de datos.
Contras: Es mas lento, respecto a los 2 otros métodos.

Por lo tanto, qué método es mejor para ocultar las superficies no visibles de un cubo?

Dependiendo de si lo vamos a rotar:

Si no queremos rotarlo: Evidentemente, la preclasificación radial, optimiza la memoria y la db.

Si queremos rotarlo: Una mezcla de la clasificación radial y la ecuación de plano puede ser bastante óptimo: En vez de tomar como valor el producto, podemos usar la posición de los vértices para determinar lo oculto y lo visible.

En futuras entradas, explicaré métodos de rotación y distintos objetos.

Foxy Rider

Disiento, realmente considero atroz usar C para 3D, primero ... no tenés sobrecarga de operadores, ergo, no podés abstraer las operaciones con vectores ... y se hacen cochinadas como esa estructura .... (o con punteros)
en C++ de forma simple, podrías abstraer todo a Vector4 , Vector3 y Vector2 ...y usar contenedores para mandar listas de vértices de forma "limpia"

Saludos.

@synthesize

Cuando empiece a estudiar POO, quizás, de mientras, tengo que seguir con eso  ;)

.:BlackCoder:.

Y es que no hay una forma standard de hacerlo en C o en C++?... Yo no se del tema pero no me gusta cuando se usan librerias no standard... Por eso la pregunta... Ojo no critico el aporte...

Saludos...
"No te esfuerzes por saber mas, esfuerzate por ser el mejor en lo que sabes... Y asi sabras mas" .:BlackCoder:. jajaja




braulio--

Cita de: .:BlackCoder:. en 16 Julio 2010, 16:53 PM
Y es que no hay una forma standard de hacerlo en C o en C++?... Yo no se del tema pero no me gusta cuando se usan librerias no standard... Por eso la pregunta... Ojo no critico el aporte...

Saludos...
Standard standard me parece que no , pero hay librerías muy usadas como la de openGL .

.:BlackCoder:.

Y las librerias con las q se hacen juego no se pueden utilizar para eso? Allegro, que es la unica de la q e escuchado  :xD, si no me equivoco es standard o no?, no sirve para ese tipo de cosas?...

Saludos...
"No te esfuerzes por saber mas, esfuerzate por ser el mejor en lo que sabes... Y asi sabras mas" .:BlackCoder:. jajaja




Foxy Rider

Pero depende mucho de qué tomes por estándar en este contexto, pero lo que sí puedo decirte es que tanto C como C++ no tienen librerías gráficas definidas en el estándar ....
OpenGL no es una librería, es una especificación y un estándar abierto de la industria que define una API para gráficos, de ahí, salen diferentes implementaciones, como la de nVIDIA y ATI ...

y ... ¿ Allegro ? nope, OpenGL
de paso, WebSerch, te comento, normalmente, se trabaja con números de punto flotante, comunmente llamados floats y double en C/C++

Saludos.



IDarknightI

Bueno, yo creo que es mejor utilizar C++ con el API OpenGL o Mesa3D, tambien puedes usar SDL que son mutiplataforma y lo puedes encapsular con clases, ademas esas librerias se especializan en graficos. Si utilizas las librerias graficas de C estas perdiendo portabilidad y velocidad.
El Conocimiento ahora es libre. Compartelo!!   -   The Knowledge is now free. Share it!!