2016-01-27 2 views
3

Я попытался трансформироваться тонкий прямоугольный куб для катушки по three.js и tween.js. Я искал вопросы, которые уже задавались, но ни один из них не ведет меня.Morph куб с катушкой в ​​трех JS

Какую функцию морфинга я должен использовать, и как я могу создать форму катушки?

cube to coil

+1

Можете ли вы представить, как вы хотите, чтобы результат выглядел? –

+0

Добавлен пример C++ OpenGL – Spektre

+0

Случайно вернулся сюда, и я вижу, что у вас есть 'Cube-> Coil' вместо' Tube-> Coil', который я, очевидно, забыл) И поскольку это все еще не принято. Вам действительно нужен куб? (ваше изображение предложит трубку), если да, катушка должна иметь круговую вырезку или квадратный разрез провода? – Spektre

ответ

0
  1. ваша труба хранится в виде набора N ломтиков

    Вы должны центральная точка и нормальный вектор для каждого (круга) среза.

    const int N=128; 
    struct slice { float p[3],n[3]; }; 
    slice mesh[N]; 
    

    Иниц него к трубе при запуске (выравнивается по оси у)

    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; 
    } 
    
  2. написать код визуализации для представления таких сеток

    Вы должны получить точки окружности каждого среза и присоединяйтесь к ним с помощью QUAD_STRIP или того примитивного, который вы используете для поверхности трубки. Верх и низ лучше всего с TRIANGLE_FAN вокруг центральной точки.

    Вы можете получить очки с моей glCircle3D in C++ только вместо того, чтобы рисовать их магазин/использовать их, как вам нужно ...

  3. интерполировать между трубой и спиралью

    Если выше workung вы можете повернуть положение центров и нормалей в спираль с переменным радиусом r и фиксированными винтами m. Так что я хотел бы попробовать:

    float a=6.283185307179586476925286766559*float(i*m)/float(N-1); 
    mesh[i].p[0] = r*cos(a); 
    mesh[i].p[2] = r*sin(a); 
    

    Нормальным может быть вычислена точно также, но у меня нет времени для тестирования его прямо сейчас, и мое воображение не то, что хорошо, так что я бы вместо этого:

    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 to unit vector 
    

    Просто скопируйте нормаль с ломтика 1 на срез 0, и все будет хорошо.

  4. одушевленные

    Просто анимировать сетку с изменением r от нуля до некоторой R. Если вы хотите непрерывный эффект, вы можете сделать r=R*sin(t), где t увеличивается с некоторым шагом ...

[edit1] C++ OpenGL пример

Если поставить все выше вместе, вы должны получить что-то вроде этого:

//--------------------------------------------------------------------------- 
//   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 
    for (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]); 
     // get the slice points (remember 2 slices for QUAD STRIP) to actual point buffer p1 
     for (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 the slice between last slice p0 and actual slice p1 
     glBegin(GL_QUAD_STRIP); 
     if (i) for (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; 
     } 
    } 
//--------------------------------------------------------------------------- 

, который делает спиралью в OpenGL. он начинается с (0,0,0) и заканчивается в (0,h,0) где:

  • r является радиусом трубки
  • R радиус винтов
  • h является спиралью высоты/размером
  • N этого число винтов за h

Он генерирует информацию о вершинах и нормалях, поэтому вы можете использовать освещение. для анимации я использую это:

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); 

Как вы можете видеть половину греха волны пренебречь, так что вы можете иметь время, чтобы действительно увидеть трубку без винтов. Здесь выход с подсветкой:

helix

Слева является отвинтил трубка (R=0). Справа - полностью вибрирующий винт, а посредине - нечто среднее между ними.

PS если вы хотите, чтобы сделать морфинг более интересным вы можете также анимировать параметр N из 0 некоторых постоянная.

 Смежные вопросы

  • Нет связанных вопросов^_^