gpt4 book ai didi

javascript - 如何在three.js中弯曲圆柱体?

转载 作者:行者123 更新时间:2023-11-29 20:47:03 25 4
gpt4 key购买 nike

您如何在three.js中弧形或弯曲具有变形的圆柱型几何体?

我想指定以下参数:

  • 弯曲开始-折弯在圆柱体高度的多少百分比处开始
  • 折弯结束-折弯终止于圆柱体高度的百分比
  • Angular -弯曲的强度

    parameters

  • 我将使用滑块控制它们。我的圆柱形状是由用户绘制的贝塞尔曲线的拉伸(stretch)创建的(Three.js中的几何类的扩展)。

    我还希望能够在彼此之上叠加多个弯曲效果。因此,弯曲可能会影响第一部分,然后第二弯曲可能会使圆柱体向后弯曲。

    我不是数学能力最好的人,所以这就是为什么我要求可以在three.js中做到这一点的技巧或公式。我在想,也许我可以在中心轴上画一条线,然后用贝塞尔曲线弯曲它。从那里,我可以使用线条的位置来影响圆柱体的顶点。听起来像个好主意吗?

    最佳答案

    您需要做的就是将您的网格划分为多个 slice ,并按照与我在此处的圆形相同的方式转换每个 slice :

  • Smoothly connecting circle centers

  • 这样完成:
  • 直线形式坐标系

    创建位置P0和3个基本 vector X0,Y0,Z0,它们以直线形式表示网格的坐标。假设Z0是您要弯曲的轴。

    P0X0Y0Z0
  • 将每个顶点转换为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'(弯曲形状上的弧长)计算弯曲弧的 Angular ,然后将X0,Y0,Z0旋转为X1,Y1,Z1(如果弯曲位置围绕X,然后将X1 = X0旋转,则只需旋转其他两个 vector 即可)。

    P1X1Y1Z1
  • 将P'转换为弯曲形式P''

    只需这样做:
    P'' = P1 + P.x'*X1 + P.y'*Y1

    现在P''是形状的最终顶点。因此,您可以在转换所有点后渲染网格。如您所见,我们不需要P.z ...,因为它已经在P1位置中进行了编码。因此,也无需真正计算Z1基 vector 。

  • [说明]

    请注意,如果折弯太大,折弯太 Assembly 破坏网格拓 flutter ,这样您就可以使 slice 彼此相交。

    同样,所有相应的基 vector 应具有相同的大小(理想单位)。
    Y0 -> Y1的旋转是一个简单的2D问题,如果 Y0=(0,1,0)甚至更简单,只需将其指向圆 Y1=(cos(a),sin(a),0) ...,因此您甚至不需要2D旋转公式。

    [Edit1] C++ / GL示例

    我很好奇,所以我拿了一根带有鼻窦螺钉的管子并将其弯曲...这是结果:

    preview

    我同时渲染了直线和弯曲网格,以进行视觉比较。红点是折弯中心,直线将其连接到 P0。我选择了 P0,X0,Y0,Z0来匹配单位矩阵。对示例进行了转换,以使其与该问题中的图像匹配(处于非动画状态)。这是我使用的 C++ / GL 代码:

    网格和弯曲 zavit.h :

    //---------------------------------------------------------------------------
    //--- 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 东西,只是移植/使用您需要的内容):

    //---------------------------------------------------------------------------
    #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 ,可在以下位置找到:
  • complete GL+GLSL+VAO/VBO C++ example

  • GLSL_math.h 是我的 vector 数学,模仿 GLSL 数学,但是您可以使用任何 vector 数学...您只需要 +,-,dot,cross,normalize,length,它们都是基本操作,您也可以自己编码,也可以使用 GLM 或其他任何方法...

    [Edit2]更多简化和重复性

    好吧,根据您的草图和后期评论,它将无法正常运行。而是使用弧长(直线网格中的高度)作为参数。经过更多的教导后,我最终得出以下结论:

    new approach

    为简化起见,我为每个 slice 添加了中心点,主轴方向和 slice 长度。这使计算变得更加简单。在此预览两次45度弯曲(+45和-45):

    double bend

    RGB线是用于弯曲网格渲染的全局坐标系,淡黄色是网格中心轴+用于调试的最后弯曲的弯曲范围,红色是最后弯曲中心。

    这里是新的C++代码zavit.h:

    //---------------------------------------------------------------------------
    //--- 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窗口代码:

    //---------------------------------------------------------------------------
    #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。

    我还利用了这样一个事实,即我的网格是按弧长( pnt1[angle][arclength])排序的,因此我可以处理 slice 而不是原始点。

    您可以类推地编写 bendybendz函数,只需稍微更改数学以匹配交换的轴即可...如果不需要原始网格,则可以立即将其删除...

    [Edit3]与您的code 的视觉比较

    它对我来说是外语,但类似于C / C++,所以从快速的 Angular 来看:
  • 使用固定的P0X0Y0Z0,可防止您多次应用折弯。
  • 155行

  • var PC = new THREE.Vector3().copy(P0).sub(PC_X);

    它不符合我的
    PC=P0-(Y0*r);

    您有不同的轴并且没有半径比例!万一你的轴有不同的意思,然后我的,那么你就相应地交换X,Y,Z,但是你仍然需要使用半径。该位置是弯曲中心,如果弯曲计算错误,弯曲位置也是错误的。...使用的轴必须不是围绕其旋转的轴,而不是圆柱体的高度。
  • 第173行的

  • var p = new THREE.Vector3().copy(X0);
    p.multiplyScalar(slice_arc_length[j]-l0);

    我有:
    p=Z0*(len1[j]-l0);

    如此显然又是不同的轴。您应该使用圆柱轴的高度...在180行的else中也是如此。
  • 所以,如果我没看错,这是轴对应关系
    mine    yours   meaning
    X0 Z0 bending rotation axis
    Y0 X0
    Z0 Y0 cylinder height
  • 第182行

    你得到了:
    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旋转,但是从您在先前代码中使用的轴对应关系来看,您应该围绕z旋转!

  • 因此,您错误地设置了旋转中心,绕了错误的轴旋转。还要检查您是否正确选择了轴(它们在网格中需要具有相同的含义)。

    [Edit4]另一个比较
  • 第105行
    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就是为什么您的弯头只是移动而不是旋转。

  • 看起来其余的代码应该没问题,但是要确保我还会渲染 middir数组,以查看它们是否真的相对于网格(在我的预览中为网格的黄色中心线)。折弯工作后,还应该从 P0X0Y0Z0移植 mid,dir计算,以便可以重复应用折弯...

    如果我切换到您的轴,它将是:
    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行:
    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进行了测试...这两个版本只是朝相反的方向旋转,因此两者都是正确的,但是代码只能与其中之一一起正常工作。
  • Angular 单位

    中线的弯曲(代码中正确的弯曲)与PC周围的旋转不同,它可能是由#2 引起的,但也可能是由错误的 Angular 单位引起的。您的cossin函数需要[deg]还是[rad]吗?当前所有计算的 Angular 都在[rad]中。
  • 关于javascript - 如何在three.js中弯曲圆柱体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54029401/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com