如何在three.js中弧形或弯曲具有变形的圆柱型几何体?
Id要指定以下参数:
我将使用滑块控制它们。我的圆柱形状是由用户绘制的贝塞尔曲线的拉伸创建的(在three.js中扩展了几何类)。
我还希望能够在彼此之上叠加多个弯曲效果。因此,弯曲可能会影响第一部分,然后第二弯曲可能会使圆柱体向后弯曲。
我不是最擅长数学的人,所以这就是为什么我要求在three.js中可以做到这一点的提示或公式。我在想,也许我可以在中心轴上画一条线,然后用贝塞尔曲线弯曲它。从那里,我可以使用线条的位置来影响圆柱体的顶点。听起来像个好主意吗?
答案 0 :(得分:2)
您需要做的就是将您的网格物体切成薄片,然后按照与我在此处做圆的相同方式来转换每个薄片:
就是这样完成的:
直线坐标系
创建位置P0
和3个基向量X0,Y0,Z0
,它们以直线形式表示网格的坐标。假设Z0
是您要弯曲的轴。
将每个顶点转换为P0,X0,Y0,Z0
个局部坐标
因此任何点P
都将转换为:
P.x' = dot( P-P0 , X0 )
P.y' = dot( P-P0 , Y0 )
P.z' = dot( P-P0 , Z0 )
创建折弯形状坐标系P1,X1,Y1,Z1
如此简单地根据用作参数的P.z'
(弯曲形状上的弧长)计算弯曲弧的角度,然后将X0,Y0,Z0
旋转到X1,Y1,Z1
(如果弯曲围绕{ {1}},然后X
,您只需要旋转其他两个向量。
将P'转换为弯曲形式P''
只需执行以下操作:
X1 = X0
现在P'' = P1 + P.x'*X1 + P.y'*Y1
是形状的最终顶点。因此,您可以在转换所有点后渲染网格。如您所见,我们不需要P''
...,因为它已经在P.z
位置编码了。因此,也不需要真正计算P1
基向量。
[注释]
请注意,弯曲太大会破坏网格拓扑。如果弯曲太多,则可以使切片彼此相交。
所有相应的基向量也应具有相同的大小(理想单位)。
Z1
的旋转是一个简单的2D问题,如果Y0 -> Y1
更简单,则只需指向圆Y0=(0,1,0)
...,因此您甚至不需要2D旋转公式。
[Edit1] C ++ / GL示例
我很好奇,所以我拿了一根用窦螺钉固定的管子并将其弯曲...这就是结果:
我同时渲染了笔直和弯曲的网格,以进行视觉比较。红点是折弯中心,线将其连接到Y1=(cos(a),sin(a),0)
。我选择了P0
来匹配单位矩阵。对示例进行了转换,以使其与该问题中的图像匹配(处于非动画状态)。这是我使用的 C ++ / GL 代码:
网格和弯曲 zavit.h :
P0,X0,Y0,Z0
以及主要的 VCL 应用代码(忽略 VCL 只是移植/使用所需的内容):
//---------------------------------------------------------------------------
//--- 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();
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
对于 OpenGL ,我使用的是 GLEW 并挖掘了 gl_simple.h ,可在此处找到:
GLSL_math.h 是我的矢量数学,模仿了 GLSL 数学,但是您可以使用任何矢量数学...您只需要//---------------------------------------------------------------------------
#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();
}
//---------------------------------------------------------------------------
,它们都是基本的操作,您也可以自己编写代码,也可以使用 GLM 或其他任何方法
[Edit2]更多简化和可重复性
根据您的草图和后期注释,这将无法正常运行。而是使用弧长(直线网格中的高度)作为参数。经过更多的教I之后,我得出以下结论:
为简化起见,我为每个切片添加了一个中心点,主轴方向和切片长度。这样可以进行更简单的计算。在此预览两次45度弯曲(+45和-45):
RGB线是弯曲的网格渲染的全局坐标系,淡黄色是网格中心轴+用于调试的最后一个弯曲的弯曲范围,红色是最后一个弯曲中心。
此处为新的C ++代码+,-,dot,cross,normalize,length
:
zavit.h
以及VCL窗口代码:
//---------------------------------------------------------------------------
//--- 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();
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
架构是一样的,只是用法有所改变,现在将弯曲直接应用到mesh1上,因此不再使用mesh0。因此,您需要在使用前将mesh0复制到mesh1。
我还利用了这样一个事实,即我的网格是按弧长(//---------------------------------------------------------------------------
#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();
}
//---------------------------------------------------------------------------
)排序的,因此我可以处理切片而不是原始点。
您可以类推地编写pnt1[angle][arclength]
和bendy
函数,只需对数学进行一些更改即可匹配交换的轴...如果您不需要原始网格,则可以立即将其删除... < / p>
[Edit3]与您的code的视觉比较
它对我来说是外语,但类似于C / C ++,所以从快速的角度来看:
bendz
,这可以防止您多次弯曲。 第155行
P0X0Y0Z0
它与我的不符
var PC = new THREE.Vector3().copy(P0).sub(PC_X);
您有不同的轴并且没有半径比例!!!如果您的轴的含义与我的不同,则只需相应地交换PC=P0-(Y0*r);
,但仍需要使用半径。该位置是弯曲中心,因此如果错误地计算出弯曲也将是错误的位置。...使用的轴必须不是围绕其旋转的轴,而不是圆柱体的高度。
第173行
X,Y,Z
我知道了
var p = new THREE.Vector3().copy(X0);
p.multiplyScalar(slice_arc_length[j]-l0);
因此再次明显不同的轴。您应该使用圆柱轴的高度...在180行的else中也是如此。
所以,如果我看对了,这就是轴对应关系
p=Z0*(len1[j]-l0);
182行
您得到了:
mine yours meaning
X0 Z0 bending rotation axis
Y0 X0
Z0 Y0 cylinder height
我知道了
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); }
如果您的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);
为零,那么仍然需要使用mid[]
。同样,您正在绕-p
旋转,但是从先前代码中使用的轴对应关系来看,您应该绕着y
旋转!!!
因此,您错误地设置了旋转中心,绕了错误的轴旋转。还要检查是否正确选择了轴(它们在网格中需要具有相同的含义)。
[Edit4]另一个比较
第105行
z
应为:
var Z_Copy = new THREE.Vector3().copy(Z0);
Z_Copy.multiplyScalar(r);
var PC = new THREE.Vector3().copy(P0).sub(Z_Copy);
因为您绕着var X_Copy = new THREE.Vector3().copy(X0);
X_Copy.multiplyScalar(r);
var PC = new THREE.Vector3().copy(P0).sub(X_Copy);
旋转,所以中心Z
必须在其他轴上移动...因此PC
就是弯曲而不是旋转的原因。
看起来其余的代码应该没问题,但是要确保我还将呈现X
和mid
数组,以查看它们是否真的相对于网格应该位于此处(我的预览中网格的黄色中心线)。折弯工作后,还应该从dir
移植P0X0Y0Z0
计算,以便可以重复应用折弯...
如果我换到你的轴上,那就是:
mid,dir
[edit5]另一个比较
您一次又一次地犯同样的错误……错误地重写了方程式,因此没有头脑的人无法正常工作。这次:
在第186行:
P0=mid1[j0];
Y0=normalize(dir1[j0]);
Z0=vec3(0.0,0.0,1.0);
X0=cross(Y0,Z0);
Y0=cross(Z0,X0);
您忘记添加var point_temp = new THREE.Vector3().copy(slices[j][i]);
,这是形状变形的原因,而且很可能也是由于旋转不同所致。
您的point_temp.sub(p);
您得到的是错误的:
rotatez
我知道了
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;
但无论如何也可能是:
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;
尝试哪种方法可行,我对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;
的公式进行测试,而不对rotatex
进行测试...这两个版本只是朝相反的方向旋转,因此两者都是正确的,但是代码只能对其中一个起作用。
角度单位
中线的弯曲(即您在代码中“正确”的弯曲)与围绕rotatez
的旋转不同,这可能是由#2 引起的,但也可能是由于错误的角度单位。您的PC
和cos
函数是否需要sin
或[deg]
?当前所有计算的角度都在[rad]
中。