3D烟花影响C / C ++使用正弦或余弦函数(3D Fireworks Effect in C/C

2019-10-20 13:14发布

我想实现烟花效果C.我有尺寸10x10x10的立方体。 火箭从地面开始,当它到达八楼它爆炸。 下面是我不能做点 - 爆炸。 我怎样才能实现这个用正弦或余弦函数?

因此,在点(5,0,7)//(X,Y,Z)//火箭进入空气中的

for (j=0; j<9; j++) {
    setpoint(x, y, j);
    delay(100);
    clean();  //clears everything
}

这里谈到的一点,使爆炸。 这可怎么实现的? 它可以在随机位置神采奕奕了。 提前致谢。

Answer 1:

这是更好地做到这一点使用倒置的抛物线,而不是正弦/余弦。 在爆炸点给每个粒子的随机水平速度。 这个速度是恒定的,直到粒子撞击地面。 你还需要给每个粒子随机垂直速度。 这一次,但是,你会加入到这个速度成正比的量-0.5*g*dt^2 (严格的说,这是错误的数字,但除非你做科学的分析,你不会注意到)。 这里, g是由于重力和加速度dt是时间步长。 就这样。



Answer 2:

嘿我确实发现了一些时间(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'ALembert
        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();

这是如何更新在一些计时器模拟(双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立方体的大小常数随打出场比赛:

  1. 每帧整个立方图DIMM率(cube.mul(200))目前(256分之200)
  2. 速度,强度v0,v1,i0,i1
  3. 爆炸目前50后的新粒子的数目
  4. 粒子强度DIMM速率爆炸目前0.95后

[笔记]

List<>仅仅是动态数组可以用任何东西,从模板std::或自己的数组...

不要忘记设置dt常数更新之间经过的时间。 希望我没有忘记拷贝一些东西。 希望能帮助到你



文章来源: 3D Fireworks Effect in C/C++ using sine or cosine function