嘿我找到了一些時間(1.5 HOD完成),並會爲這個有趣的東西:)
可以先有的在LED_cube類,以支持體素點輸出和更新的調光,剩下的就是相同從另一個問題球...
//---------------------------------------------------------------------------
//--- LED cube class ver: 1.01 ----------------------------------------------
//---------------------------------------------------------------------------
#ifndef _LED_cube_h
#define _LED_cube_h
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
const int _LED_cube_size=32;
//---------------------------------------------------------------------------
class LED_cube
{
public:
int n,map[_LED_cube_size][_LED_cube_size][_LED_cube_size];
LED_cube() { n=_LED_cube_size; }
LED_cube(LED_cube& a) { *this=a; }
~LED_cube() { }
LED_cube* operator = (const LED_cube *a) { *this=*a; return this; }
//LED_cube* operator = (const LED_cube &a) { /*...copy...*/ return this; }
void cls(int col); // clear cube with col 0x00BBGGRR
void mul(int mul); // mull all channels by mul and then shr by 8
void point(int x,int y,int z,int col); // draws voxel with col 0x00BBGGRR
void sphere(int x0,int y0,int z0,int r,int col); // draws sphere surface with col 0x00BBGGRR
void glDraw(); // render cube by OpenGL as 1x1x1 cube at 0,0,0
};
//---------------------------------------------------------------------------
void LED_cube::cls(int col)
{
int x,y,z;
for (x=0;x<n;x++)
for (y=0;y<n;y++)
for (z=0;z<n;z++)
map[x][y][z]=col;
}
//---------------------------------------------------------------------------
void LED_cube::mul(int mul)
{
union { BYTE db[4]; int dd; } c;
int x,y,z,i;
for (x=0;x<n;x++)
for (y=0;y<n;y++)
for (z=0;z<n;z++)
{
c.dd=map[x][y][z];
i=c.db[0]; i=(i*mul)>>8; c.db[0]=i;
i=c.db[1]; i=(i*mul)>>8; c.db[1]=i;
i=c.db[2]; i=(i*mul)>>8; c.db[2]=i;
map[x][y][z]=c.dd;
}
}
//---------------------------------------------------------------------------
void LED_cube::point(int x,int y,int z,int col)
{
if ((x>=0)&&(x<n))
if ((y>=0)&&(y<n))
if ((z>=0)&&(z<n))
map[x][y][z]=col;
}
//---------------------------------------------------------------------------
void LED_cube::sphere(int x0,int y0,int z0,int r,int col)
{
int x,y,z,xa,ya,za,xb,yb,zb,xr,yr,zr,xx,yy,zz,rr=r*r;
// bounding box
xa=x0-r; if (xa<0) xa=0; xb=x0+r; if (xb>n) xb=n;
ya=y0-r; if (ya<0) ya=0; yb=y0+r; if (yb>n) yb=n;
za=z0-r; if (za<0) za=0; zb=z0+r; if (zb>n) zb=n;
// project xy plane
for (x=xa,xr=x-x0,xx=xr*xr;x<xb;x++,xr++,xx=xr*xr)
for (y=ya,yr=y-y0,yy=yr*yr;y<yb;y++,yr++,yy=yr*yr)
{
zz=rr-xx-yy; if (zz<0) continue; zr=sqrt(zz);
z=z0-zr; if ((z>0)&&(z<n)) map[x][y][z]=col;
z=z0+zr; if ((z>0)&&(z<n)) map[x][y][z]=col;
}
// project xz plane
for (x=xa,xr=x-x0,xx=xr*xr;x<xb;x++,xr++,xx=xr*xr)
for (z=za,zr=z-z0,zz=zr*zr;z<zb;z++,zr++,zz=zr*zr)
{
yy=rr-xx-zz; if (yy<0) continue; yr=sqrt(yy);
y=y0-yr; if ((y>0)&&(y<n)) map[x][y][z]=col;
y=y0+yr; if ((y>0)&&(y<n)) map[x][y][z]=col;
}
// project yz plane
for (y=ya,yr=y-y0,yy=yr*yr;y<yb;y++,yr++,yy=yr*yr)
for (z=za,zr=z-z0,zz=zr*zr;z<zb;z++,zr++,zz=zr*zr)
{
xx=rr-zz-yy; if (xx<0) continue; xr=sqrt(xx);
x=x0-xr; if ((x>0)&&(x<n)) map[x][y][z]=col;
x=x0+xr; if ((x>0)&&(x<n)) map[x][y][z]=col;
}
}
//---------------------------------------------------------------------------
void LED_cube::glDraw()
{
#ifdef __gl_h_
int x,y,z;
float p[3],dp=1.0/float(n-1);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_ONE);
glPointSize(2.0);
glBegin(GL_POINTS);
for (p[0]=-0.5,x=0;x<n;x++,p[0]+=dp)
for (p[1]=-0.5,y=0;y<n;y++,p[1]+=dp)
for (p[2]=-0.5,z=0;z<n;z++,p[2]+=dp)
{
glColor4ubv((BYTE*)(&map[x][y][z]));
glVertex3fv(p);
}
glEnd();
glDisable(GL_BLEND);
glPointSize(1.0);
#endif
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//--------------------------------------------------------------------------
- 重要的東西是:
void mul(int mul);
- 用於調出整體素地圖
void point(int x,int y,int z,int col);
- 用於設置單體素的科洛爾
現在的顆粒
//---------------------------------------------------------------------------
class particle
{
public:
double x, y, z; // position
double vx,vy,vz; // velocity
double ax,ay,az; // acceleration driving force/m after update is reseted
double i; // intensity
particle()
{
x=0.0; y=0.0; z=0.0;
vx=0.0; vy=0.0; vz=0.0;
ax=0.0; ay=0.0; az=0.0;
i=0.0;
};
particle(particle& a){ *this=a; };
~particle(){};
particle* operator = (const particle *a) { *this=*a; return this; };
// particle* operator = (const particle &a) { ...copy... return this; };
void update(double dt)
{
double c0,c;
// gravity
ay-=9.81;
// friction in gass
c=0.001;
if (vx>0.0) c0=-c; else c0=+c; ax+=vx*vx*c0;
if (vy>0.0) c0=-c; else c0=+c; ay+=vy*vy*c0;
if (vz>0.0) c0=-c; else c0=+c; az+=vz*vz*c0;
// friction in liquid
c=0.0;
ax-=vx*vx*vx*c;
ay-=vy*vy*vy*c;
az-=vz*vz*vz*c;
// D'Lambert
vx+=ax*dt;
vy+=ay*dt;
vz+=az*dt;
x+=vx*dt;
y+=vy*dt;
z+=vz*dt;
// reset acceleration
ax=0.0; ay=0.0; az=0.0;
}
};
//---------------------------------------------------------------------------
List<particle> particles; // use any list/array you have at your disposal you need just function add and delete item
//---------------------------------------------------------------------------
這是如何繪製場景:
cube.mul(200); // dimm the voxel map insted of clearing it (intensity*=200/256)
for (int i=0;i<particles.num;i++)
{
particle *p=&particles[i];
int j=double(255.0*p->i);
if (j<0) j=0;
if (j>255) j=255;
cube.point(p->x,p->y,p->z,0x00010101*j);
}
cube.glDraw();
這是如何更新模擬一些定時器(double dt =定時器間隔,單位爲秒)
double i0=1.0; // intensity at shoot start
double i1=0.9*i0; // intensity after explosion
double v0=0.6*double(_LED_cube_size); // shoot start speed
double v1=0.5*v0,v1h=0.5*v1; // explosion speed
if (particles.num==0) // shoot new particle if none in list
{
particle p;
p.x=_LED_cube_size>>1;
p.y=0.0;
p.z=_LED_cube_size>>1;
p.vy=v0;
p.i=i0;
particles.add(p);
}
for (int i=0;i<particles.num;i++) // update all particles in list
{
particle *p=&particles[i];
p->update(dt);
if (fabs(p->i-i0)<1e-6) // intensity detect state before explosion
{
if (p->vy<=0.0) // explode near/after peak reached
{
particle q;
q.x=p->x; // copy position
q.y=p->y;
q.z=p->z;
q.i=i1; // new intensity
particles.del(i); // remove old particle
i--;
for (int j=0;j<50;j++) // add new random particles
{
q.vx=v1*Random()-v1h;
q.vy=v1*Random()-v1h;
q.vz=v1*Random()-v1h;
particles.add(q)-v1h;
}
continue; // avoid usage of p pointer after delete
}
}
else{ // after explosion
p->i*=0.95; // dimm intensity
}
if ((p->y<0.0)||(p->i<0.01))// remove particles below the ground or too dimmed out
{
particles.del(i);
i--;
continue; // avoid usage of p pointer after delete
}
}
這是它的外觀
很抱歉的旗幟,但我沒有什麼紮實的GIF轉換與本網站不接受WMV ......你有常量來匹配玩所需的LED立方體尺寸常數上的輸出:
- 整個立方體貼圖dimm率(立方體。每幀MUL(200))目前(256分之200)
- 速度,強度
v0,v1,i0,i1
- 數目新粒子的後爆炸目前0.95
[後爆炸目前50
粒子強度DIMM率注意事項] List<>
是動態數組可以用任何東西從std::
或自己的數組只是模板...
不要忘記將dt
設置爲與更新之間經過的時間不變。希望我沒有忘記複製一些東西。希望它有幫助
彈道學更接近拋物線,實際上... – EOF
除非你的煙花有一些小推進器和集成制導系統,使它們能夠沿着正弦路徑行進,否則它們將遵循拋物線路徑 - 至少在目前強制執行的物理定律,並忽略風阻等的影響...... – twalberg
@Ezio_我很可能會使用粒子模擬(重力+某些峯值控制的爆炸......只是在一段時間或高度後分裂到各個方向。 ..)http://stackoverflow.com/a/20017455/2521214幾十年來沒有編碼這個效果(在ZXS之前最後一次在386上的asm中)也許我會爲了樂趣,如果我有時間以後(如果是的會在這裏發佈) – Spektre