How to bend a cylinder in three.js?
如何在three.js中弧形或弯曲具有变形的圆柱体几何形状?
Id要指定以下参数:
- 弯曲开始-弯曲在圆柱高度的百分之几处开始
- 弯头-弯头在圆柱体高度的百分之几处结束
-
angular-弯曲的强度
我将使用滑块控制它们。我的圆柱形状是由用户绘制的贝塞尔曲线的拉伸创建的(在three.js中扩展了几何类)。
我还希望能够在彼此之上叠加多个弯曲效果。因此,弯曲可能会影响第一部分,然后第二弯曲可能会使圆柱体向后弯曲。
我并不是最擅长数学的人,所以这就是为什么我要要求可以在three.js中做到这一点的技巧或公式。我在想,也许我可以在中心轴上画一条线,然后用贝塞尔曲线弯曲它。从那里,我可以使用线条的位置来影响圆柱体的顶点。这听起来是个好主意吗?
您需要做的是将您的网格物体切成薄片,并按照与我在此处的圆形相同的方式转换每个薄片:
- 平滑地连接圆心
这样做是这样的:
直角坐标系
创建位置
将每个顶点转换为
因此任何点
1 2 3 | P.x' = dot( P-P0 , X0 ) P.y' = dot( P-P0 , Y0 ) P.z' = dot( P-P0 , Z0 ) |
创建折弯形状坐标系
因此简单地基于用作参数的
将P \\'转换为弯曲形式P \\'\\'
只需执行以下操作:
1 | P'' = P1 + P.x'*X1 + P.y'*Y1 |
现在
[注释]
请注意,如果弯曲得太大,弯曲得太大会破坏网格拓扑,然后彼此之间会自动相交。
所有相应的基向量也应具有相同的大小理想单位。
[Edit1] C / GL示例
我很好奇,所以我拿了一根用窦螺钉固定的管子并将其弯曲...这就是结果:
我同时渲染了笔直和弯曲的网格,以进行视觉比较。红点是折弯中心,线将其连接到
网格和弯曲zavit.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | //--------------------------------------------------------------------------- //--- tube with sinus screw ------------------------------------------------- //--------------------------------------------------------------------------- const int ca=20; const int cb=50; const float r0=0.3; const float r1=0.35; const float l1=2.0; const float nz=5.0; vec3 pnt0[ca][cb]; // straight mesh vec3 nor0[ca][cb]; vec2 txr0[ca][cb]; //--------------------------------------------------------------------------- vec3 pnt1[ca][cb]; // bended mesh vec3 nor1[ca][cb]; vec2 txr1[ca][cb]; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void obj0_init() // sin screw { int i,j,i0,j0; float a,b,l,da,db,dl,r,s,c,tx,ty; float dtx=1.0/float(ca-1),dty=1.0/float(cb-1); vec3 u,v; // pnt,txr da=2.0*M_PI/float(ca-1); db=nz*2.0*M_PI/float(cb); dl=l1/float(cb); for (a=0.0,tx=0.0,i=0;i<ca;i++,a+=da,tx+=dtx) { s=sin(a); c=cos(a); for (l=-0.5*l1,b=0,ty=0.0,j=0;j<cb;j++,b+=db,l+=dl,ty+=dty) { r=r0+((r1-r0)*cos(a+b)); pnt0[i][j].x=r*c; pnt0[i][j].y=r*s; pnt0[i][j].z=l; txr0[i][j].x=tx; txr0[i][j].y=ty; } } // nor for (i0=ca-2,i=0;i<ca;i0=i,i++) for (j0=cb-1,j=0;j<cb;j0=j,j++) { u=pnt0[i][j]-pnt0[i0][j]; v=pnt0[i][j]-pnt0[i][j0]; nor0[i][j]=normalize(cross(v,u)); } } //--------------------------------------------------------------------------- void obj1_bend(vec3 center) // bend obj0 -> obj1 ... pc center, P0,X0,Y0,Z0 = unit matrix { int i,j,i0,j0; float a,r; vec3 p,p1,x1,y1,u,v; // bend pnt, copy txr r=length(center); for (i=0;i<ca;i++) for (j=0;j<cb;j++) { p=pnt0[i][j]; // p' = p a=p.z/r; // arc length -> angle [rad] p1=center; // p1 point on circleYZ (bending around X) p1.y-=r*cos(a); p1.z-=r*sin(a); x1=vec3(1.0,0.0,0.0); // basis vectors y1=vec3(0.0,cos(a),sin(a)); p=p1+(p.x*x1)+(p.y*y1); // p'' pnt1[i][j]=p; txr1[i][j]=txr0[i][j]; } // nor for (i0=ca-2,i=0;i<ca;i0=i,i++) for (j0=cb-1,j=0;j<cb;j0=j,j++) { u=pnt1[i][j]-pnt1[i0][j]; v=pnt1[i][j]-pnt1[i][j0]; nor1[i][j]=normalize(cross(v,u)); } } //--------------------------------------------------------------------------- void obj0_draw() { int i,j; glColor3f(1.0,1.0,1.0); glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); for (i=0;i<ca-1;i++) { glBegin(GL_QUAD_STRIP); for (j=0;j<cb;j++) { glTexCoord2fv(txr0[i+1][j].dat); glNormal3fv (nor0[i+1][j].dat); glVertex3fv (pnt0[i+1][j].dat); glTexCoord2fv(txr0[i ][j].dat); glNormal3fv (nor0[i ][j].dat); glVertex3fv (pnt0[i ][j].dat); } glEnd(); } } //--------------------------------------------------------------------------- void obj1_draw() { int i,j; glColor3f(1.0,1.0,1.0); glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); for (i=0;i<ca-1;i++) { glBegin(GL_QUAD_STRIP); for (j=0;j<cb;j++) { glTexCoord2fv(txr1[i+1][j].dat); glNormal3fv (nor1[i+1][j].dat); glVertex3fv (pnt1[i+1][j].dat); glTexCoord2fv(txr1[i ][j].dat); glNormal3fv (nor1[i ][j].dat); glVertex3fv (pnt1[i ][j].dat); } glEnd(); } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- |
以及主要的VCL应用程序代码(忽略VCL内容,只是移植/使用您需要的内容):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | //--------------------------------------------------------------------------- #include <vcl.h> #include <math.h> #pragma hdrstop #include"Unit1.h" #include"gl_simple.h" double divide(double a,double b){ if (fabs(b)<1e-10) return 0.0; return a/b; } #include"GLSL_math.h" #include"zavit.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource"*.dfm" TForm1 *Form1; vec3 center=vec3(0.0,1.7,0.0); //--------------------------------------------------------------------------- void gl_draw() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); float aspect=float(xs)/float(ys); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0/aspect,aspect,0.1,100.0); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0,0.0,-5.5); glRotatef(80.0,1.0,0.0,0.0); // Z+ up slightly forw static float ang=0.0; ang+=5.0; glRotatef(45.0+ang,0.0,0.0,1.0); // X+ right forw, Y+ left forw, + animation rotation around up glEnable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // original mesh glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(-0.7,0.0,0.0); glColor3f(1.0,1.0,1.0); obj0_draw(); glPopMatrix(); // bended mesh glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(+0.7,0.0,0.0); glColor3f(1.0,1.0,1.0); obj1_draw(); glDisable(GL_LIGHTING); glColor3f(1.0,0.0,0.0); glPointSize(10.0); glBegin(GL_POINTS); glVertex3fv(center.dat); // bending center glVertex3f(0.0,0.0,0.0); // P0 glEnd(); glPointSize(1.0); glBegin(GL_LINES); glVertex3fv(center.dat); glVertex3f(0.0,0.0,0.0); glEnd(); /* glBegin(GL_LINES); glColor3f(1.0,0.0,0.0); glVertex3f(0.0,0.0,0.0); glVertex3f(1.0,0.0,0.0); glColor3f(0.0,1.0,0.0); glVertex3f(0.0,0.0,0.0); glVertex3f(0.0,1.0,0.0); glColor3f(0.0,0.0,1.0); glVertex3f(0.0,0.0,0.0); glVertex3f(0.0,0.0,1.0); glEnd(); */ glMatrixMode(GL_MODELVIEW); glPopMatrix(); glFlush(); SwapBuffers(hdc); } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner) { gl_init(Handle); obj0_init(); obj1_bend(center); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormDestroy(TObject *Sender) { gl_exit(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormPaint(TObject *Sender) { gl_draw(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { gl_draw(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormResize(TObject *Sender) { gl_resize(ClientWidth,ClientHeight); gl_draw(); } //--------------------------------------------------------------------------- |
对于OpenGL,我使用的是GLEW和我的gl_simple.h,可在此处找到:
- 完整的GL GLSL VAO / VBO C示例
GLSL_math.h是模仿GLSL数学的我的向量数学,但是您可以使用任何向量数学...您只需要
[Edit2]更多简化和可重复性
根据您的草图和最新评论进行调整,它将不能正常运行。而是使用弧长(直线网格中的高度)作为参数。经过更多的教I之后,我得出以下结论:
为简化起见,我为每个切片添加了一个中心点,主轴方向和切片长度。这样可以简化计算...在此预览两次45度弯曲(45和-45):
RGB线是弯曲的网格渲染的全局坐标系,淡黄色是用于调试的最后一个弯曲的网格中心轴弯曲范围,红色是最后的弯曲中心。
此处为新的C代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | //--------------------------------------------------------------------------- //--- tube with sinus screw ------------------------------------------------- //--------------------------------------------------------------------------- // https://stackoverflow.com/a/54050883/2521214 //--------------------------------------------------------------------------- const int ca= 20; // points per slice const int cb=100; // slices const float r0= 0.3; // minor screw radius const float r1= 0.35; // major screw radius const float l1= 4.0; // tube length const float nz= 10.0; // screws //--------------------------------------------------------------------------- vec3 bend_pc; int bend_j0,bend_j1; // just for debug draw //--------------------------------------------------------------------------- // straight mesh vec3 pnt0[ca][cb]; // vertex vec3 nor0[ca][cb]; // normal vec2 txr0[ca][cb]; // texcoord vec3 mid0[cb]; // slice center vec3 dir0[cb]; // slice central axis (normalized) float len0[cb]; // slice arclength position //--------------------------------------------------------------------------- // bended mesh vec3 pnt1[ca][cb]; // vertex vec3 nor1[ca][cb]; // normal vec2 txr1[ca][cb]; // texcoord vec3 mid1[cb]; // slice center vec3 dir1[cb]; // slice central axis (normalized) float len1[cb]; // slice arclength position //--------------------------------------------------------------------------- void obj0_init() // sin screw { int i,j,i0,j0; float a,b,l,da,db,dl,r,s,c,tx,ty; float dtx=1.0/float(ca-1),dty=1.0/float(cb-1); vec3 u,v; // pnt,txr da=2.0*M_PI/float(ca-1); db=nz*2.0*M_PI/float(cb); dl=l1/float(cb); for (a=0.0,tx=0.0,i=0;i<ca;i++,a+=da,tx+=dtx) { s=sin(a); c=cos(a); for (l=-0.5*l1,b=0,ty=0.0,j=0;j<cb;j++,b+=db,l+=dl,ty+=dty) { r=r0+((r1-r0)*cos(a+b)); pnt0[i][j].x=r*c; pnt0[i][j].y=r*s; pnt0[i][j].z=l; txr0[i][j].x=tx; txr0[i][j].y=ty; } } // mid,dir for (l=0.0,j=0;j<cb;j++,l+=dl) { mid0[j]=vec3(0.0,0.0, l-(0.5*l1)); dir0[j]=vec3(0.0,0.0,dl); len0[j]=l; } // nor for (i0=ca-2,i=0;i<ca;i0=i,i++) for (j0=cb-1,j=0;j<cb;j0=j,j++) { u=pnt0[i][j]-pnt0[i0][j]; v=pnt0[i][j]-pnt0[i][j0]; nor0[i][j]=normalize(cross(u,v)); } } //--------------------------------------------------------------------------- void obj1_copy() // obj1 = obj0 { int i,j; for (i=0;i<ca;i++) for (j=0;j<cb;j++) { pnt1[i][j]=pnt0[i][j]; txr1[i][j]=txr0[i][j]; nor1[i][j]=nor0[i][j]; } for (j=0;j<cb;j++) { mid1[j]=mid0[j]; dir1[j]=dir0[j]; len1[j]=len0[j]; } } //--------------------------------------------------------------------------- vec3 rotatex(vec3 p,vec3 p0,float a) { vec3 q; p-=p0; q.z=+(p.z*cos(a))+(p.y*sin(a)); q.y=-(p.z*sin(a))+(p.y*cos(a)); q.x=p.x; return q+p0; } //--------------------------------------------------------------------------- vec3 rotatey(vec3 p,vec3 p0,float a) { vec3 q; p-=p0; q.x=+(p.x*cos(a))+(p.z*sin(a)); q.z=-(p.x*sin(a))+(p.z*cos(a)); q.y=p.y; return q+p0; } //--------------------------------------------------------------------------- vec3 rotatez(vec3 p,vec3 p0,float a) { vec3 q; p-=p0; q.x=+(p.x*cos(a))+(p.y*sin(a)); q.y=-(p.x*sin(a))+(p.y*cos(a)); q.z=p.z; return q+p0; } //--------------------------------------------------------------------------- void obj1_bendx(float l0,float l1,float ang) // [units],[units],[rad] bend obj1 around x axis { int i,j,i0,j0,j1; float a,r,l; vec3 PC,p,u,v; vec3 P0,X0,Y0,Z0; // find start and end of bend for (j0= 0;(j0<cb)&&(len1[j0]<l0);j0++); for (j1=j0;(j1<cb)&&(len1[j1]<l1);j1++); if (j0>cb) return; // no bend // coordinate system0 P0=mid1[j0]; Z0=normalize(dir1[j0]); X0=vec3(1.0,0.0,0.0); Y0=cross(Z0,X0); X0=cross(Y0,Z0); // bend center r=(l1-l0)/ang; PC=P0-(Y0*r); r=fabs(r); // just for debug draw bend_pc=PC; bend_j0=j0; bend_j1=j1; // bend <l0,l1) for (j=j0;j<cb;j++) { // arc length -> angle [rad] and length correction if (j<j1) { a=ang*(len1[j]-l0)/(l1-l0); p=Z0*(len1[j]-l0); } else{ a=ang; p=Z0*(l1-l0); } // transform system0 -> system1 mid1[j]=rotatex(mid1[j]-p,PC,a); dir1[j]=rotatex(dir1[j],vec3(0.0,0.0,0.0),a); for (i=0;i<ca;i++) pnt1[i][j]=rotatex(pnt1[i][j]-p,PC,a); } // nor for (i0=ca-2,i=0;i<ca;i0=i,i++) for (j0=cb-1,j=0;j<cb;j0=j,j++) { u=pnt1[i][j]-pnt1[i0][j]; v=pnt1[i][j]-pnt1[i][j0]; nor1[i][j]=normalize(cross(u,v)); } } //--------------------------------------------------------------------------- void obj0_draw() { int i,j; glColor3f(1.0,1.0,1.0); glEnable(GL_CULL_FACE); glFrontFace(GL_CW); for (i=0;i<ca-1;i++) { glBegin(GL_QUAD_STRIP); for (j=0;j<cb;j++) { glTexCoord2fv(txr0[i+1][j].dat); glNormal3fv (nor0[i+1][j].dat); glVertex3fv (pnt0[i+1][j].dat); glTexCoord2fv(txr0[i ][j].dat); glNormal3fv (nor0[i ][j].dat); glVertex3fv (pnt0[i ][j].dat); } glEnd(); } } //--------------------------------------------------------------------------- void obj1_draw() { int i,j; glColor3f(1.0,1.0,1.0); glEnable(GL_CULL_FACE); glFrontFace(GL_CW); for (i=0;i<ca-1;i++) { glBegin(GL_QUAD_STRIP); for (j=0;j<cb;j++) { glTexCoord2fv(txr1[i+1][j].dat); glNormal3fv (nor1[i+1][j].dat); glVertex3fv (pnt1[i+1][j].dat); glTexCoord2fv(txr1[i ][j].dat); glNormal3fv (nor1[i ][j].dat); glVertex3fv (pnt1[i ][j].dat); } glEnd(); } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- |
以及VCL窗口代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | //--------------------------------------------------------------------------- #include <vcl.h> #include <math.h> #pragma hdrstop #include"Unit1.h" #include"gl_simple.h" double divide(double a,double b){ if (fabs(b)<1e-10) return 0.0; return a/b; } #include"GLSL_math.h" #include"zavit.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource"*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- void gl_draw() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); float aspect=float(xs)/float(ys); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0/aspect,aspect,0.1,100.0); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0,0.0,-5.5); glRotatef(-80.0,1.0,0.0,0.0); // Z+ up slightly forw static float ang=0.0; ang+=5.0; glRotatef(45.0+ang,0.0,0.0,1.0); // X+ right forw, Y+ left forw, + animation rotation around up glEnable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // [original mesh] glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(-0.7,0.0,0.0); glColor3f(1.0,1.0,1.0); obj0_draw(); glPopMatrix(); // [bended mesh] glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(+0.7,0.0,0.0); glColor3f(1.0,1.0,1.0); obj1_draw(); // debug draws int j; glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); // global coordinates glBegin(GL_LINES); glColor3f(1.0,0.0,0.0); glVertex3f(0.0,0.0,0.0); glVertex3f(1.0,0.0,0.0); glColor3f(0.0,1.0,0.0); glVertex3f(0.0,0.0,0.0); glVertex3f(0.0,1.0,0.0); glColor3f(0.0,0.0,1.0); glVertex3f(0.0,0.0,0.0); glVertex3f(0.0,0.0,1.0); glEnd(); // mesh axis glLineWidth(2.0); glColor3f(0.9,0.6,0.1); glBegin(GL_LINE_STRIP); for (j=0;j<bend_j0;j++) glVertex3fv(mid1[j].dat); if (j<cb){ glVertex3fv(mid1[j].dat); glVertex3fv(bend_pc.dat); } for ( ;j<bend_j1;j++) glVertex3fv(mid1[j].dat); if (j<cb){ glVertex3fv(mid1[j].dat); glVertex3fv(bend_pc.dat); } for ( ;j<cb ;j++) glVertex3fv(mid1[j].dat); glEnd(); glLineWidth(1.0); // bending center glColor3f(1.0,0.0,0.0); glPointSize(10.0); glBegin(GL_POINTS); glVertex3fv(bend_pc.dat); glEnd(); glPointSize(1.0); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glFlush(); SwapBuffers(hdc); } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner) { gl_init(Handle); obj0_init(); obj1_copy(); obj1_bendx(1.0,1.5,+45.0*M_PI/180.0); obj1_bendx(2.5,3.0,-45.0*M_PI/180.0); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormDestroy(TObject *Sender) { gl_exit(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormPaint(TObject *Sender) { gl_draw(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { gl_draw(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormResize(TObject *Sender) { gl_resize(ClientWidth,ClientHeight); gl_draw(); } //--------------------------------------------------------------------------- |
架构是一样的,只是用法有所改变,现在将折弯直接应用到mesh1上,因此不再使用mesh0。因此,您需要在使用之前将mesh0复制到mesh1。
我还利用了这样一个事实,即我的网格是按弧长(
您可以类推地编写
[Edit3]与您的代码的视觉比较
对我来说是外语,但与C / C类似,所以从快速的angular来看:
第155行
1 | var PC = new THREE.Vector3().copy(P0).sub(PC_X); |
它不对应我的
1 | PC=P0-(Y0*r); |
您有不同的轴并且没有半径比例!!!如果您的轴具有不同的含义,然后再挖掘,则您只需相应地交换
第173行
1 2 | var p = new THREE.Vector3().copy(X0); p.multiplyScalar(slice_arc_length[j]-l0); |
我知道了:
1 | p=Z0*(len1[j]-l0); |
因此再次明显不同的轴。您应该使用圆柱轴的高度...在180行的else中也是如此。
所以,如果我看对的话,这是轴对应关系
1 2 3 4 | mine yours meaning X0 Z0 bending rotation axis Y0 X0 Z0 Y0 cylinder height |
第182行
您得到了:
1 2 3 | center_points[j] = rotatey(p,PC,a); center_vector[j] = rotatey(center_vector[j], new THREE.Vector3(0,0,0),a); for (var i=0; i<20; i++){ slices[i][j]= rotatey(slices[i][j].sub(p),PC,a); } |
我知道了:
1 2 3 | mid1[j]=rotatex(mid1[j]-p,PC,a); dir1[j]=rotatex(dir1[j],vec3(0.0,0.0,0.0),a); for (i=0;i<ca;i++) pnt1[i][j]=rotatex(pnt1[i][j]-p,PC,a); |
如果
因此,您错误地设置了旋转中心,绕了错误的轴旋转。还要检查是否正确选择了轴(它们在网格中需要具有相同的含义)。
[Edit4]另一个比较
第105行
1 2 3 | var Z_Copy = new THREE.Vector3().copy(Z0); Z_Copy.multiplyScalar(r); var PC = new THREE.Vector3().copy(P0).sub(Z_Copy); |
应为:
1 2 3 | var X_Copy = new THREE.Vector3().copy(X0); X_Copy.multiplyScalar(r); var PC = new THREE.Vector3().copy(P0).sub(X_Copy); |
当您围绕
看起来其余的代码应该没问题,但是要确保我还会渲染
如果我换到你的轴上,那就是:
1 2 3 4 5 | P0=mid1[j0]; Y0=normalize(dir1[j0]); Z0=vec3(0.0,0.0,1.0); X0=cross(Y0,Z0); Y0=cross(Z0,X0); |
[edit5]另一个比较
您一次又一次地犯了同样的错误……错误地重写了方程式,所以没有人动脑筋了。这次:
第186行:
1 | var point_temp = new THREE.Vector3().copy(slices[j][i]); |
您忘记添加
您的
您输入的是错误的:
1 2 3 | p.x=+(p.x*Math.cos(a))+(p.y*Math.sin(a)); p.y=+(p.x*Math.sin(a))+(p.y*Math.cos(a)); p.z=p.z; |
我得到了
1 2 3 | p.x=+(p.x*Math.cos(a))+(p.y*Math.sin(a)); p.y=-(p.x*Math.sin(a))+(p.y*Math.cos(a)); p.z=p.z; |
但无论如何也可能是:
1 2 3 | p.x=+(p.x*Math.cos(a))-(p.y*Math.sin(a)); p.y=+(p.x*Math.sin(a))+(p.y*Math.cos(a)); p.z=p.z; |
尝试哪种方法能使我对
angular单位
中线的弯曲(在代码中您获得了"正确"的弯曲)与围绕
中