three.js - Morph a cube to coil in three js -
i have tried morph thin rectangular cube coil three.js
, tween.js
. i've searched questions has been ask none of them guide me.
which morph function should use, , how can create coil shape?
have tube stored set of
n
slicesyou need center point , normal vector each (circle) slice.
const int n=128; struct slice { float p[3],n[3]; }; slice mesh[n];
init tube @ start (aligned y axis)
for (int i=0;i<n;i++) { mesh[i].p[0]= 0.0; mesh[i].p[1]=-1.0+2.0*float(i)/float(n-1); mesh[i].p[2]= 0.0; mesh[i].n[0]= 0.0; mesh[i].n[1]=+1.0; mesh[i].n[2]= 0.0; }
write visualization code such mesh representation
you need obtain circumference points of each slice , join them quad_strip or ever primitive using tube surface. top , bottom best triangle_fan around center point.
you can obtain points glcircle3d in c++ instead of drawing them store/use them need ...
interpolate between tube , helix
if above workung can turn centers position , normals helix variable radius
r
, fixed screwsm
. try:float a=6.283185307179586476925286766559*float(i*m)/float(n-1); mesh[i].p[0] = r*cos(a); mesh[i].p[2] = r*sin(a);
the normal can computed similary not have time testing right , imagination not instead this:
mesh[i].n[0] = mesh[i].p[0] - mesh[i-1].p[0]; mesh[i].n[1] = mesh[i].p[1] - mesh[i-1].p[1]; mesh[i].n[2] = mesh[i].p[2] - mesh[i-1].p[2]; normalize(mesh[i].n); // set unit vector
just copy normal slice 1 slice 0 , should fine.
animate
just animate mesh changing
r
0r
. if want continuous effect canr=r*sin(t)
t
increasing step ...
[edit1] c++ opengl example
if put above should this:
//--------------------------------------------------------------------------- // height ,tube r ,screw r ,screws void helix(double h,double r,double r,double n) { int i,j,na; double pos[3]={ 0.0,0.0,0.0 },x[3],y[3], nor[3]={ 0.0,1.0,0.0 },ss,dy,a,da,b,db; na=double(n*36.0); // 36 slices per screw const int nb=36+1; // 36 points per circle slice dy=h/double(na); // y axis step da=2.0*m_pi*n/double(na); // screw angle step db=2.0*m_pi/double(nb-1); // slice circle angle step ss=1.0/sqrt((r*r)+(dy*dy)); // normalization scale double pnt[nb*12],*p0=pnt,*p1=pnt+(nb*6),*pp; // 2 slice point buffers (normal3d+vertex3d)*nb*2 = 12*nb (a=0.0,i=0;i<na;i++,a+=da) { if (a>2.0*m_pi) a-=2.0*m_pi; // slice center pos[0]=r*cos(a); pos[1]+=dy; pos[2]=r*sin(a); // slice normal nor[0]=-ss*r*sin(a); nor[1]=+ss*dy; nor[2]=+ss*r*cos(a); // slice basis vectors x,y x[0]=cos(a); x[1]=0.0; x[2]=sin(a); // y = cross(x,nor) y[0]= -(x[2]*nor[1]); y[1]=(x[2]*nor[0])-(x[0]*nor[2]); y[2]=(x[0]*nor[1]); // slice points (remember 2 slices quad strip) actual point buffer p1 (pp=p1,b=0.0,j=0;j<nb;j++,b+=db,pp+=6) { // normal pp[0]=(x[0]*cos(b))+(y[0]*sin(b)); pp[1]=(x[1]*cos(b))+(y[1]*sin(b)); pp[2]=(x[2]*cos(b))+(y[2]*sin(b)); // position pp[3]=pos[0]+(pp[0]*r); pp[4]=pos[1]+(pp[1]*r); pp[5]=pos[2]+(pp[2]*r); } // if 2 slices done render slice between last slice p0 , actual slice p1 glbegin(gl_quad_strip); if (i) (j=0;j<6*nb;j+=6) { glnormal3dv(p0+j+0); glvertex3dv(p0+j+3); glnormal3dv(p1+j+0); glvertex3dv(p1+j+3); } glend(); // swap last,actual slice point buffers p0 <-> p1 pp=p0; p0=p1; p1=pp; } } //---------------------------------------------------------------------------
which renders helix in opengl. starts (0,0,0)
, ends in (0,h,0)
where:
r
radius of tuber
radius of screwsh
helix height/sizen
number of screws perh
it generates vertex , normal info can use lighting. animation use this:
static double t=0.0; t+=0.1; if (t>=pi2) t-=pi2; double r=sin(t); if (r<0.0) r=0.0; glcolor3f(1.0,1.0,1.0); helix(1.0,0.05,0.3*r,6.0);
as can see half of sin wave neglected can have time see tube without screws. here output lighting:
on left unscrewed tube (r=0
). on right morphed screw , in middle in between.
ps if want make morph more interesting can animate n
parameter 0
constant.
Comments
Post a Comment