在OpenGL中编写特定的3d(星形)模型? [英] Programming a specific 3d (star-like) model in OpenGL?

查看:79
本文介绍了在OpenGL中编写特定的3d(星形)模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何创建以下模型:


从第一个图形开始.是否可以完全在OpenGL中进行编程,还是应该使用其他软件,例如3d Studio Max或Unity?是否应该使用一些特定的算法?

by starting from the first drawing. Could it be programmed in OpenGL entirely or should I use other software like 3d Studio Max or Unity? Are there some specific algorithms that should be used?

推荐答案

是的,可以在 C ++/OpenGL

  1. 创建从中心发射的随机曲线

简单的3D二次多项式曲线将满足要求.

simple 3D quadratic polynomial curve will fit the bill.

将曲线转换为圆锥形

沿每条曲线简单地插入点,并将其用作圆锥切片的中心.方向由沿曲线的上一个或下一个点设置.插入圆锥体切片并将其点添加到某个点列表中.参见:

simply interpolate points along each curve and use it as a center for the cone slice. The direction is set by the previous or next point along the curve. Interpolate the cone slices and add their points to some point list. See:

创建面孔

使用任何原始元素简单地连接计算点以形成圆锥体...我建议GL_QUAD s ...

simply connect the computed points to form the cones using any primitive ... I would suggest GL_QUADs...

核心

如果您还想添加核(核?),可以做一个球体,在该球体的表面上添加一些噪点,并可能进行一些滤波以使其变得平滑...

if you want to add also the core (nuclei?) it can be done a s a sphere with some noise added to its surface and probably some filtering to smooth it a bit...

以下是简单的曲线生成C ++示例:

Here simple curve generation C++ example:

List<double> pnt;
void spicule_init()
    {
    double t,tt,x,y,z;
    double a0[3],a1[3],a2[3];
    int ix0,ix,i,j;
    Randomize();
    for (i=0;i<20;i++)                      // cones
        {
        // random quadratic 3D curve coeff
        for (j=0;j<3;j++)
            {
            a0[j]=0.0;                      // center (0,0,0)
            a1[j]=2.0*(Random()-0.5);       // main direction
            a2[j]=1.0*(Random()-0.5);       // curvature
            }
        // curve interpolation
        ix0=pnt.num;
        for (t=0.0;t<=1.0;t+=0.04)
         for (tt=t*t,j=0;j<3;j++)
          pnt.add(a0[j]+(a1[j]*t)+(a2[j]*tt));
        }
    }

生成的点的预览:

[Edit1] 当添加了圆锥体,法线和面时,它看起来像这样:

When added the cones,normals and faces it looks like this:

它远非完美,但我认为这是一个很好的起点.只需调整半径r和曲线系数a1[],a2[]即可获得所需的形状...,并且可以添加核心和/或检查自相交,我太懒了……

Its far from perfect but I think is a good start point. Just tweak the radius r and the curve coefficients a1[],a2[] to achieve desired shape ... and may be add the core and or check for self intersections too, I am too lazy to do that...

以下是更新的C ++/GL代码:

//---------------------------------------------------------------------------
List<double> pnt,nor;   // points, normals
List<int> fac;          // QUAD faces
//---------------------------------------------------------------------------
void Circle3D(List<double> &pnt,List<double> &nor,double *p0,double *n0,double r,int N)
    {
    int i;
    double a,da=divide(pi2,N),p[3],dp[3],x[3],y[3];
    vector_ld(x,1.0,0.0,0.0); if (fabs(vector_mul(x,n0)>0.7)) vector_ld(x,0.0,1.0,0.0);
    vector_mul(x,x,n0); vector_one(x,x);
    vector_mul(y,x,n0); vector_one(y,y);
    for (a=0.0,i=0;i<N;i++,a+=da)
        {
        vector_mul( p,x,cos(a));
        vector_mul(dp,y,sin(a));
        vector_add(p,p,dp); nor.add(p[0]); nor.add(p[1]); nor.add(p[2]);
        vector_mul(p,p,r);
        vector_add(p,p,p0); pnt.add(p[0]); pnt.add(p[1]); pnt.add(p[2]);
        }
    }
//---------------------------------------------------------------------------
void spicule_init() // generate random spicule mesh
    {
    const int N=36;                         // points/circle
    const int N3=3*N;
    double t,tt,x,y,z,r;
    double a0[3],a1[3],a2[3];
    double p[3],n[3];
    int e,i,j,i00,i01,i10,i11;
    Randomize();
    pnt.num=0; nor.num=0; fac.num=0;
    for (i=0;i<20;i++)                      // cones
        {
        // random quadratic 3D curve coeff
        for (j=0;j<3;j++)
            {
            a0[j]=0.0;                      // center (0,0,0)
            a1[j]=2.0*(Random()-0.5);       // main direction and size
            a2[j]=1.0*(Random()-0.5);       // curvature
            }
        // curve interpolation
        vector_ld(n,0.0,0.0,0.0);
        for (e=0,t=0.05;t<=1.0;t+=0.05)
            {
            // points,normals
            for (tt=t*t,j=0;j<3;j++) p[j]=a0[j]+(a1[j]*t)+(a2[j]*tt);
            r=0.15*(1.0-pow(t,0.1));        // radius is shrinking with t
            vector_sub(n,p,n);              // normal is p(t)-p(t-dt)
            Circle3D(pnt,nor,p,n,r,N);      // add circle to pnt (N points)
            vector_copy(n,p);               // remember last point
            // faces
            if (!e){ e=1; continue; }       // ignore first slice of cone
            i00=pnt.num- 3; i10=i00-N3;
            i01=pnt.num-N3; i11=i01-N3;
            for (j=0;j<N;j++)
                {
                fac.add(i00);
                fac.add(i01);
                fac.add(i11);
                fac.add(i10);
                i00=i01; i01+=3;
                i10=i11; i11+=3;
                }
            }
        }
    }
//---------------------------------------------------------------------------
void spicule_draw() // render generated spicule
    {
    glEnable(GL_CULL_FACE);
    glFrontFace(GL_CCW);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    int i,j;
    glColor3f(1.0,1.0,1.0);
    glBegin(GL_QUADS);
    for (i=0;i<fac.num;i++)
        {
        j=fac.dat[i];
        glNormal3dv(nor.dat+j);
        glVertex3dv(pnt.dat+j);
        }
    glEnd();
    }
//---------------------------------------------------------------------------

如果您不知道如何计算矢量运算,例如叉/点积或绝对值,请参阅:

If you do not know how to compute vector operations like cross/dot products or absolute value see:

// cross product: W = U x V
W.x=(U.y*V.z)-(U.z*V.y)
W.y=(U.z*V.x)-(U.x*V.z)
W.z=(U.x*V.y)-(U.y*V.x)
// dot product: a = (U.V)
a=U.x*V.x+U.y*V.y+U.z*V.z
// abs of vector a = |U|
a=sqrt((U.x*U.x)+(U.y*U.y)+(U.z*U.z))


vector_mul(a[3],b[3],c[3])是叉积a = b x c
a = vector_mul(b[3],c[3])是点积a = (b.c)
vector_one(a[3],b[3])是单位向量a = b/|b|
vector_copy(a[3],b[3])只是副本a = b
vector_add(a[3],b[3],c[3])正在添加a = b + c
vector_sub(a[3],b[3],c[3])正在减去a = b - c
vector_neg(a[3],b[3])是负数a = -b
vector_ld(a[3],x,y,z)正在加载a = (x,y,z)


vector_mul(a[3],b[3],c[3]) is cross product a = b x c
a = vector_mul(b[3],c[3]) is dot product a = (b.c)
vector_one(a[3],b[3]) is unit vector a = b/|b|
vector_copy(a[3],b[3]) is just copy a = b
vector_add(a[3],b[3],c[3]) is adding a = b + c
vector_sub(a[3],b[3],c[3]) is substracting a = b - c
vector_neg(a[3],b[3]) is negation a = -b
vector_ld(a[3],x,y,z) is just loading a = (x,y,z)

也可以在这里找到一些(如果不是全部)使用的向量数学:

Also some (if not all the) Vector math used can be found here:

我还使用了我的动态列表模板,所以:

I also use mine dynamic list template so:


List<double> xxx;double xxx[];相同
xxx.add(5);5添加到列表的末尾
xxx[7]访问数组元素(安全)
xxx.dat[7]访问数组元素(不安全但快速的直接访问)
xxx.num是数组的实际使用大小
xxx.reset()清除数组并设置xxx.num=0
xxx.allocate(100)100个项目预分配空间


List<double> xxx; is the same as double xxx[];
xxx.add(5); adds 5 to end of the list
xxx[7] access array element (safe)
xxx.dat[7] access array element (unsafe but fast direct access)
xxx.num is the actual used size of the array
xxx.reset() clears the array and set xxx.num=0
xxx.allocate(100) preallocate space for 100 items

这篇关于在OpenGL中编写特定的3d(星形)模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆