Una vez mas traigo un ejemplo de como realizar un motor grafico en 3d basico, esta vez decidi recordar los viejos tiempos de estudiante, las formulas de rotacion de puntos en 3d son las siguientes, basandome en el articulo de la wikipedia
en processing y la mayor parte de los lenguajes de progamacion deberian de quedar asi:
void rot(float a, float b, float c) {
xt=x;
yt=y;
zt=z;
//rotar sobre x
xr=xt;
yr=yt*cos1(a)-zt*sin1(a);
zr=yt*sin1(a)+zt*cos1(a);
xt=xr;
yt=yr;
zt=zr;
//rotar sobre y
xr=xt*cos1(b)+zt*sin1(b);
yr=yt;
zr=-xt*cos1(b)+zt*cos1(b);
xt=xr;
yt=yr;
zt=zr;
//rotar sobre z
xr=xt*cos1(c)-yt*sin1(c);
yr=xt*sin1(c)+yt*cos1(c);
zr=zt;
xt=xr;
yt=yr;
zt=zr;
}
Pero al no utilizar las librerias 3d de los programas se tiene que representar los puntos 3d en 2d, de la siguiente manera:
int tx() {
ri=cx+(int)(100000*xt/(zt+100000));
return ri;
}
int ty() {
rj= cy-(int)(100000*yt/(zt+100000));
return rj;
}
Teniendo la teoria matematica podemos realizar graficas, o la representacion de objetos 3d,
Video
Una vez logrado el cometido, la meta es obtener objetos del mundo exterior a traves de fotografias y representarlos virtualmente en un software , modificarlos y posteriormente imprimirlos en alguna impresora 3d.
Anexo codigo fuente para processing:
float [] coseno=new float[63];
float [] seno=new float[63];
float [][][] malla=new float[101][101][3];
float [][][] malla2d=new float[101][101][3];
float theta=0,alfa=0 ,pi=3.14159265358979, rrr, it, jt;
int i, j, k, click=0;
int con=0, cx=250, cy=250;
p3d px=new p3d(100, 0, 0);
p3d py=new p3d(0, 100, 0);
p3d pz=new p3d(0, 0, 100);
//
p3d p1=new p3d(0, 0, 0);
void setup() {
size(500, 500);
con=0;
for (theta=0; theta<=6.2; theta+=.1) {
seno[con]=sin(theta);
coseno[con]=cos(theta);
con++;
}
for (i=0; i<=60; i+=1) {
for (j=0; j<=60; j+=1) {
malla[i][j][0]=i*5-150;
malla[i][j][1]=j*5-150;
//plano
//malla[i][j][2]=0;
//silla
//malla[i][j][2]=malla[i][j][0]*malla[i][j][0]/100-malla[i][j][1]*malla[i][j][1]/100;
//sombrero
jt=(j-30)*.50;
it=(i-30)*.50;
rrr=sqrt(it*it+jt*jt)+3*cos(sqrt(it*it+jt*jt));
malla[i][j][2]=rrr*10-100;
}
}
i=0;
}
void draw() {
background(255);
fill(0);
stroke(0);
px.rot(theta, alfa, .75);
py.rot(theta, alfa, .75);
pz.rot(theta, alfa, .75);
stroke(255, 0, 0);
line(cx, cy, px.tx(), px.ty());
stroke(0, 255, 0);
line(cx, cy, py.tx(), py.ty());
stroke(0, 0, 255);
line(cx, cy, pz.tx(), pz.ty());
stroke(0);
//rotar malla
for (i=0; i<=60; i+=1) {
for (j=0; j<=60; j+=1) {
p1.set(malla[i][j][0], malla[i][j][1], malla[i][j][2]);
p1.rot(theta, .5, .75);
malla2d[i][j][0]=p1.tx();
malla2d[i][j][1]=p1.ty();
//dibujar malla
if (j>0 &&i>0) {
line(malla2d[i][j][0], malla2d[i][j][1], malla2d[i-1][j-1][0], malla2d[i-1][j-1][1]);
line(malla2d[i][j][0], malla2d[i][j][1], malla2d[i][j-1][0], malla2d[i][j-1][1]);
}
}
}
delay(10);
theta+=.1;
alfa+=.03;
if (theta>=6.2) {
theta=0;
}
if(alfa>=6.2){
alfa=0;
}
}
void mouseClicked() {
if (click==0) {
for (i=0; i<=60; i+=1) {
for (j=0; j<=60; j+=1) {
malla[i][j][0]=i*5-150;
malla[i][j][1]=j*5-150;
//plano
malla[i][j][2]=0;
}
}
}
if (click==1) {
for (i=0; i<=60; i+=1) {
for (j=0; j<=60; j+=1) {
malla[i][j][0]=i*5-150;
malla[i][j][1]=j*5-150;
//silla
malla[i][j][2]=malla[i][j][0]*malla[i][j][0]/100-malla[i][j][1]*malla[i][j][1]/100;
}
}
}
if (click==2) {
for (i=0; i<=60; i+=1) {
for (j=0; j<=60; j+=1) {
malla[i][j][0]=i*5-150;
malla[i][j][1]=j*5-150;
//sombrero
jt=(j-30)*.50;
it=(i-30)*.50;
rrr=sqrt(it*it+jt*jt)+3*cos(sqrt(it*it+jt*jt));
malla[i][j][2]=rrr*10-100;
}
}
}
click+=1;
if (click>=3) {
click=0;
}
}
float sin1(float ang) {
if (ang<0) {
ang=-ang;
}
return seno[(int)(ang*10)];
}
float cos1(float ang) {
if (ang<0) {
ang=-ang;
}
return coseno[(int)(ang*10)];
}
class p3d {
float x, y, z, xt, yt, zt, xr, yr, zr;
int ri, rj;
p3d(float xx, float yy, float zz) {
x=xx;
y=yy;
z=zz;
}
void set(float xx, float yy, float zz) {
x=xx;
y=yy;
z=zz;
}
void rot(float a, float b, float c) {
xt=x;
yt=y;
zt=z;
//rotar sobre x
xr=xt;
yr=yt*cos1(a)-zt*sin1(a);
zr=yt*sin1(a)+zt*cos1(a);
xt=xr;
yt=yr;
zt=zr;
//rotar sobre y
xr=xt*cos1(b)+zt*sin1(b);
yr=yt;
zr=-xt*cos1(b)+zt*cos1(b);
xt=xr;
yt=yr;
zt=zr;
//rotar sobre z
xr=xt*cos1(c)-yt*sin1(c);
yr=xt*sin1(c)+yt*cos1(c);
zr=zt;
xt=xr;
yt=yr;
zt=zr;
}
int tx() {
ri=cx+(int)(100000*xt/(zt+100000));
return ri;
}
int ty() {
rj= cy-(int)(100000*yt/(zt+100000));
return rj;
}
}
domingo, 28 de diciembre de 2014
domingo, 21 de diciembre de 2014
efecto de fuego basico en processing
A continuacion les muestro como pueden hacer efecto de fuego aplicando la siguiente ecuacion, la cual consiste en el promedio de color basado en las posiciones del pixel.
(x,y)=((x,y)+(x-1,y+1)+(x,y+1)+(x+1,y+1))/4
El random de los colores van desde rojo, amarillo, negro y blanco, en el cual solamente se generan aletareamente en el ultimo renglon.
Codigo en processing:
Video
float y;
int r, g, b, i, j, n, np=20, cc=0;
int [][][] colores1=new int[101][101][3];
void setup() {
size(510, 510);
noStroke();
for (i=1; i<=100; i++) {
for (j=1; j<=100; j++) {
colores1[i][j][0]=0;
colores1[i][j][1]=0;
colores1[i][j][2]=0;
}
}
}
void draw() {
delay(10);
for (i=1; i<=100; i++) {
for (j=1; j<=100; j++) {
if (j==100 ) {
if ((int)random(0, 10)%3==0) {
//rojo
r=255;
g=0;
b=0;
} else if ((int)random(0, 10)%2==0) {
//amarillo
r=g=255;
b=0;
} else if ((int)random(0, 10)%2==0) {
r=g=b=255;
} else {
r=g=255;
b=0;
}
colores1[i][j][0]=r;
colores1[i][j][1]=g;
colores1[i][j][2]=b;
} else if (i<100 && j<100 &&i>1 &&j>1) {
if ((int)random(0, 10)%5==0) {
n=0;
} else {
n=(int)random(0, 5);
}
r=(colores1[i][j][0]+colores1[i-1][j+1][0]+colores1[i][j+1][0]+colores1[i+1][j+1][0])/4-n;
g=(colores1[i][j][1]+colores1[i-1][j+1][1]+colores1[i][j+1][1]+colores1[i+1][j+1][1])/4-n;
b=(colores1[i][j][2]+colores1[i-1][j+1][2]+colores1[i][j+1][2]+colores1[i+1][j+1][2])/4-n;
if (r<0)
r=0;
if (g<0)
g=0;
if (b<0)
b=0;
////////////
//////////
colores1[i][j][0]=r;
colores1[i][j][1]=g;
colores1[i][j][2]=b;
cuadro c=new cuadro(i, j, r, g, b);
if (j<96)
c.pinta();
}
}
}
}
class cuadro {
int x, y, r, g, b;
cuadro(int xx, int yy, int rr, int gg, int bb) {
x=xx;
y=yy;
r=rr;
g=gg;
b=bb;
}
void pinta() {
fill(r, g, b);
rect(x*5, y*5, 5, 5);
}
}
(x,y)=((x,y)+(x-1,y+1)+(x,y+1)+(x+1,y+1))/4
El random de los colores van desde rojo, amarillo, negro y blanco, en el cual solamente se generan aletareamente en el ultimo renglon.
Codigo en processing:
Video
float y;
int r, g, b, i, j, n, np=20, cc=0;
int [][][] colores1=new int[101][101][3];
void setup() {
size(510, 510);
noStroke();
for (i=1; i<=100; i++) {
for (j=1; j<=100; j++) {
colores1[i][j][0]=0;
colores1[i][j][1]=0;
colores1[i][j][2]=0;
}
}
}
void draw() {
delay(10);
for (i=1; i<=100; i++) {
for (j=1; j<=100; j++) {
if (j==100 ) {
if ((int)random(0, 10)%3==0) {
//rojo
r=255;
g=0;
b=0;
} else if ((int)random(0, 10)%2==0) {
//amarillo
r=g=255;
b=0;
} else if ((int)random(0, 10)%2==0) {
r=g=b=255;
} else {
r=g=255;
b=0;
}
colores1[i][j][0]=r;
colores1[i][j][1]=g;
colores1[i][j][2]=b;
} else if (i<100 && j<100 &&i>1 &&j>1) {
if ((int)random(0, 10)%5==0) {
n=0;
} else {
n=(int)random(0, 5);
}
r=(colores1[i][j][0]+colores1[i-1][j+1][0]+colores1[i][j+1][0]+colores1[i+1][j+1][0])/4-n;
g=(colores1[i][j][1]+colores1[i-1][j+1][1]+colores1[i][j+1][1]+colores1[i+1][j+1][1])/4-n;
b=(colores1[i][j][2]+colores1[i-1][j+1][2]+colores1[i][j+1][2]+colores1[i+1][j+1][2])/4-n;
if (r<0)
r=0;
if (g<0)
g=0;
if (b<0)
b=0;
////////////
//////////
colores1[i][j][0]=r;
colores1[i][j][1]=g;
colores1[i][j][2]=b;
cuadro c=new cuadro(i, j, r, g, b);
if (j<96)
c.pinta();
}
}
}
}
class cuadro {
int x, y, r, g, b;
cuadro(int xx, int yy, int rr, int gg, int bb) {
x=xx;
y=yy;
r=rr;
g=gg;
b=bb;
}
void pinta() {
fill(r, g, b);
rect(x*5, y*5, 5, 5);
}
}
Suscribirse a:
Entradas (Atom)




