pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

    <bdo id='qmTOi'></bdo><ul id='qmTOi'></ul>
    1. <tfoot id='qmTOi'></tfoot>
      <legend id='qmTOi'><style id='qmTOi'><dir id='qmTOi'><q id='qmTOi'></q></dir></style></legend>

    2. <i id='qmTOi'><tr id='qmTOi'><dt id='qmTOi'><q id='qmTOi'><span id='qmTOi'><b id='qmTOi'><form id='qmTOi'><ins id='qmTOi'></ins><ul id='qmTOi'></ul><sub id='qmTOi'></sub></form><legend id='qmTOi'></legend><bdo id='qmTOi'><pre id='qmTOi'><center id='qmTOi'></center></pre></bdo></b><th id='qmTOi'></th></span></q></dt></tr></i><div class="hl3dxbd" id='qmTOi'><tfoot id='qmTOi'></tfoot><dl id='qmTOi'><fieldset id='qmTOi'></fieldset></dl></div>
    3. <small id='qmTOi'></small><noframes id='qmTOi'>

        根據管端法線向圓柱體應用旋轉

        Apply Rotation to Cylinder based on Tube Ending Normal(根據管端法線向圓柱體應用旋轉)
        1. <tfoot id='QGjmw'></tfoot>
        2. <small id='QGjmw'></small><noframes id='QGjmw'>

            <bdo id='QGjmw'></bdo><ul id='QGjmw'></ul>

            <i id='QGjmw'><tr id='QGjmw'><dt id='QGjmw'><q id='QGjmw'><span id='QGjmw'><b id='QGjmw'><form id='QGjmw'><ins id='QGjmw'></ins><ul id='QGjmw'></ul><sub id='QGjmw'></sub></form><legend id='QGjmw'></legend><bdo id='QGjmw'><pre id='QGjmw'><center id='QGjmw'></center></pre></bdo></b><th id='QGjmw'></th></span></q></dt></tr></i><div class="ljb57tn" id='QGjmw'><tfoot id='QGjmw'></tfoot><dl id='QGjmw'><fieldset id='QGjmw'></fieldset></dl></div>
                <tbody id='QGjmw'></tbody>

                <legend id='QGjmw'><style id='QGjmw'><dir id='QGjmw'><q id='QGjmw'></q></dir></style></legend>

                • 本文介紹了根據管端法線向圓柱體應用旋轉的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

                  問題描述

                  我正在嘗試在 three.js 中制作一個彎曲的 3D 箭頭.為了完成這項任務,我創建了一個

                  我正在嘗試將箭頭(圓柱形狀為錐形)定位在管的末端,如下所示:(Photoshopped)

                  我的數學不是特別強,而且對 three.js 很陌生.有人可以幫助我了解如何將兩者聯系起來嗎?

                  這是我當前的代碼:

                   import T from 'three';var findY = 函數(r,x){返回 Math.sqrt((r * r) - (x * x));}變量半徑 = 25;變量 x = 0;變量 z = 0;var numberOfPoints = 10;var 間隔 = (半徑/numberOfPoints);變量點 = [];for (var i = numberOfPoints; i >= 0; i--){var y = findY(半徑, x);points.push(new T.Vector3(x, y, z))x = x + 區間;}x = x - 間隔;for (var i = numberOfPoints - 1 ; i >= 0; i--){y = findY(半徑, x) * -1;points.push(new T.Vector3(x, y, z));x = x - 間隔;}var path = new T.CatmullRomCurve3(points);var tubeGeometry = new T.TubeGeometry(路徑,//路徑10,//段radius/10,//半徑8,//radiusSegmentsfalse//關閉);var coneGeometry = new T.CylinderGeometry(半徑頂部 = 0.1,radiusBottom = 半徑/5,高度 = 10,徑向段 = 10,高度段 = 10,開放式 = 1);var 材料 = 新 T.MeshBasicMaterial( { 顏色: 0x00ff00 } );var tube = new T.Mesh(tubeGeometry, material);var cone = new T.Mesh(coneGeometry, material);//平移和旋轉圓錐?

                  如果有人可以嘗試簡單地解釋一下數學和編程完成的必要條件,我將不勝感激

                  • 找到位于管末端的法線
                  • 將圓錐體移動到正確的位置

                  感謝任何幫助!

                  解決方案

                  當您可以直接在原地創建箭頭時,不要為此使用旋轉.同樣,彎管也可以這樣做.您唯一需要的是由 A,B 端點定義的最后一條線段.

                  A為尖點,B為圓盤基中心.要創建箭頭,您需要 2 個額外的基礎向量,讓它們稱為基礎圓盤的 U,V 和半徑 r.從它們中,您可以使用如下簡單的圓形公式創建圓盤點:

                  1. 獲取AB端點

                  2. 計算U,V基向量

                    U,V應位于箭頭的圓盤底部,且相互垂直.箭頭的方向(行 |BA|)是圓盤基法線,因此利用叉積將垂直向量返回到相乘的向量,因此:

                    W = B-A;W/= |W|;//單位向量T = (1,0,0);//temp 任何不平行于 W 的非零向量如果 ( |(W.T)|>0.75 ) T = (0,1,0);//如果 T 和 W 的絕對點積接近 1,則表示它們接近平行,因此選擇不同的 TU = (T x W)//U 垂直于 T,WV = (U x W)//V 垂直于 U,W

                  3. 創建/渲染箭頭幾何

                    即簡單攤位A,B是三角扇的中心(需要2個),圓盤基點計算如下:

                    P(ang) = B + U.r.cos(ang) + V.r.sin(ang)

                    因此,只需將 ang 循環遍歷整個圓圈,然后您就可以獲得足夠的點數(通常 36 點就足夠了)并從它們中進行兩個三角形扇形.不要忘記最后一個圓盤點必須與第一個圓盤點相同,否則您會在 ang = 0360 度數上出現丑陋的外觀或孔.

                  如果您仍想進行輪換,則可以這樣做.以與上述相同的方式計算 U,V,W 并從中構造變換矩陣.原點 O 將是點 BX,Y,Z 將是 U,V,W順序取決于您的箭頭型號.W 應該與模型軸匹配.U,V 可以是任意順序.所以只需將所有向量復制到它們的位置并使用此矩陣進行渲染.欲了解更多信息,請參閱:

                  • void glArrowRoundxy(GLfloat x0,GLfloat y0,GLfloat z0,GLfloat r,GLfloat r0,GLfloat r1,GLfloat a0,GLfloat a1,GLfloat a2){常量 int _glCircleN=50;//每圈點數常量 int n=3*_glCircleN;整數 i,j,ix,e;浮動 x,y,z,x1,y1,z1,a,b,da,db=pi2/(_glCircleN-1);浮動 ux,uy,uz,vx,vy,vz,u,v;//緩沖區GLfloat ptab[6*_glCircleN],*p0,*p1,*n0,*n1,*p;p0=ptab+(0*_glCircleN);//上一個管段圓點p1=ptab+(3*_glCircleN);//實際管段圓點大=+分貝;如果(a0>a1)da=-db;//主角度步長方向ux=0.0;//U 垂直于箭頭平面uy=0.0;uz=1.0;//圓弧插值 a=<a0,a1>對于 (e=1,j=0,a=a0;e;j++,a+=da){//結束條件如果 ((da>0.0)&&(a>=a1)) { a=a1;e=0;}if ((da<0.0)&&(a<=a1)) { a=a1;e=0;}//計算實際的管中心x1=x0+(r*cos(a));y1=y0+(r*sin(a));z1=z0;//V 是從 (x0,y0,z0) 到 (x1,y1,z1) 的方向vx=x1-x0;vy=y1-y0;vz=z1-z0;//和粗略的單位b=sqrt((vx*vx)+(vy*vy)+(vz*vz));如果(b>1e-6)b=1.0/b;否則 b=0.0;vx*=b;vy*=b;vz*=b;//管段對于 (ix=0,b=0.0,i=0;i<_glCircleN;i++,b+=db){u=r0*cos(b);v=r0*sin(b);p1[ix]=x1+(ux*u)+(vx*v);九++;p1[ix]=y1+(uy*u)+(vy*v);九++;p1[ix]=z1+(uz*u)+(vz*v);九++;}如果 (!j){glBegin(GL_TRIANGLE_FAN);glVertex3f(x1,y1,z1);對于 (ix=0;ix

                    這會在 XY 平面上渲染彎曲的箭頭,其中心為 x,y,z,半徑為 r.r0 是管半徑,r1 是箭頭基部半徑.因為我沒有你的曲線定義,所以我選擇 XY 平面中的圓.a0,a1,a2 是箭頭開始 (a0)、箭頭開始 (a1) 和結束 (a2).pi2 只是常量 pi2=6.283185307179586476925286766559.

                    這個想法是記住實際和之前的管段圓點,以便 ptab,p0,p1 存在,否則您需要計算所有內容兩次.

                    當我直接選擇 XY 平面時,我知道一個基向量是垂直于它的.第二個是垂直于它和箭頭方向幸運的是圓形屬性提供了它自己,因此在這種情況下不需要叉積.

                    如果不評論我,希望它足夠清楚.

                    我需要將它添加到我的引擎中,所以這里是 3D 版本(不僅綁定到軸對齊的箭頭,而且圓錐體也彎曲了).除了基礎向量計算之外它是相同的,我還在標題中稍微改變了角度 <a0,a1> 是整個間隔,aa 是箭頭大小但后者在代碼中被轉換為原始約定.我還添加了用于照明計算的法線.我還添加了線性箭頭,其中基向量的計算沒有利用圓屬性,以防你得到不同的曲線.這里的結果:

                    //---------------------------------------------------------------------------常量 int _glCircleN=50;//每圈點數//--------------------------------------------------------------------------void glCircleArrowxy(GLfloat x0,GLfloat y0,GLfloat z0,GLfloat r,GLfloat r0,GLfloat r1,GLfloat a0,GLfloat a1,GLfloat aa){雙 pos[3]={ x0, y0, z0};雙倍nor[3]={0.0,0.0,1.0};雙 bin[3]={1.0,0.0,0.0};glCircleArrow3D(pos,nor,bin,r,r0,r1,a0,a1,aa);}//--------------------------------------------------------------------------void glCircleArrowyz(GLfloat x0,GLfloat y0,GLfloat z0,GLfloat r,GLfloat r0,GLfloat r1,GLfloat a0,GLfloat a1,GLfloat aa){雙 pos[3]={ x0, y0, z0};雙nor[3]={1.0,0.0,0.0};雙倉[3]={0.0,1.0,0.0};glCircleArrow3D(pos,nor,bin,r,r0,r1,a0,a1,aa);}//--------------------------------------------------------------------------void glCircleArrowxz(GLfloat x0,GLfloat y0,GLfloat z0,GLfloat r,GLfloat r0,GLfloat r1,GLfloat a0,GLfloat a1,GLfloat aa){雙 pos[3]={ x0, y0, z0};雙倍nor[3]={0.0,1.0,0.0};雙倉[3]={0.0,0.0,1.0};glCircleArrow3D(pos,nor,bin,r,r0,r1,a0,a1,aa);}//--------------------------------------------------------------------------void glCircleArrow3D(double *pos,double *nor,double *bin,double r,double r0,double r1,double a0,double a1,double aa){//常量 int _glCircleN=20;//每圈點數整數 e,i,j,N=3*_glCircleN;雙 U[3],V[3],u,v;雙a,b,da,db=pi2/double(_glCircleN-1),a2,rr;雙 *ptab,*p0,*p1,*n0,*n1,*pp,p[3],q[3],c[3],n[3],tan[3];//緩沖區ptab=新雙 [12*_glCircleN];如果 (ptab==NULL) 返回;p0=ptab+(0*_glCircleN);n0=ptab+(3*_glCircleN);p1=ptab+(6*_glCircleN);n1=ptab+(9*_glCircleN);//準備角度a2=a1;大=分貝;aa=晶圓廠(aa);如果(a0>a1){da=-da;aa=-aa;}a1-=aa;//計算缺失的基向量vector_copy(U,nor);//U 垂直于箭頭平面vector_mul(tan,nor,bin);//切線垂直于法線和副法線//圓弧插值 a=<a0,a2>對于 (e=0,j=0,a=a0;e<5;j++,a+=da){//結束條件if (e==0)//e=0{如果 ((da>0.0)&&(a>=a1)) { a=a1;e++;}if ((da<0.0)&&(a<=a1)) { a=a1;e++;}rr=r0;}else{//e=1,2,3,4如果 ((da>0.0)&&(a>=a2)) { a=a2;e++;}if ((da<0.0)&&(a<=a2)) { a=a2;e++;}rr=r1*fabs(除法(a-a2,a2-a1));}//計算實際管段中心 c[3]u=r*cos(a);v=r*sin(a);vector_mul(p,bin,u);矢量_mul(q,tan,v);vector_add(c,p,q);vector_add(c,c,pos);//V是從箭頭中心到管段中心的單位方向vector_sub(V,c,pos);矢量_一個(V,V);//管段插值對于 (b=0.0,i=0;i1)//重新計算圓錐的法線{對于 (i=3;i0.0) for (i=0;i=0;i-=3) glVertex3dv(p1+i);else for (i= 0;ir1 邊緣如果 (e==1) a-=da;如果 ((e==1)||(e==2)||(e==3)) e++;}//釋放緩沖區刪除[] ptab;}//--------------------------------------------------------------------------void glLinearArrow3D(double *pos,double *dir,double r0,double r1,double l,double al){//常量 int _glCircleN=20;//每圈點數int e,i,N=3*_glCircleN;雙 U[3],V[3],W[3],u,v;雙a,da=pi2/double(_glCircleN-1),r,t;雙 *ptab,*p0,*p1,*n1,*pp,p[3],q[3],c[3],n[3];//緩沖區ptab=新雙 [9*_glCircleN];如果 (ptab==NULL) 返回;p0=ptab+(0*_glCircleN);p1=ptab+(3*_glCircleN);n1=ptab+(6*_glCircleN);//計算基向量vector_one(W,dir);vector_ld(p,1.0,0.0,0.0);vector_ld(q,0.0,1.0,0.0);vector_ld(n,0.0,0.0,1.0);a=fabs(vector_mul(W,p));pp=p;t=a;a=fabs(vector_mul(W,q));如果 (t>a) { pp=q;t=a;}a=fabs(vector_mul(W,n));如果 (t>a) { pp=n;t=a;}vector_mul(U,W,pp);vector_mul(V,U,W);vector_mul(U,V,W);對于 (e=0;e<4;e++){//分段中心如果 (e==0) { t=0.0;r=r0;}如果 (e==1) { t=l-al;r=r0;}如果 (e==2) { t=l-al;r=r1;}如果 (e==3) { t=l;r=0.0;}vector_mul(c,W,t);vector_add(c,c,pos);//管段插值對于 (a=0.0,i=0;i2)//重新計算圓錐的法線{對于 (i=3;i

                    用法:

                    glColor3f(0.5,0.5,0.5);glCircleArrowyz(+3.5,0.0,0.0,0.5,0.1,0.2,0.0*deg,+270.0*deg,45.0*deg);glCircleArrowyz(-3.5,0.0,0.0,0.5,0.1,0.2,0.0*deg,-270.0*deg,45.0*deg);glCircleArrowxz(0.0,+3.5,0.0,0.5,0.1,0.2,0.0*deg,+270.0*deg,45.0*deg);glCircleArrowxz(0.0,-3.5,0.0,0.5,0.1,0.2,0.0*deg,-270.0*deg,45.0*deg);glCircleArrowxy(0.0,0.0,+3.5,0.5,0.1,0.2,0.0*deg,+270.0*deg,45.0*deg);glCircleArrowxy(0.0,0.0,-3.5,0.5,0.1,0.2,0.0*deg,-270.0*deg,45.0*deg);glColor3f(0.2,0.2,0.2);glLinearArrow3D(vector_ld(+2.0,0.0,0.0),vector_ld(+1.0,0.0,0.0),0.1,0.2,2.0,0.5);glLinearArrow3D(vector_ld(-2.0,0.0,0.0),vector_ld(-1.0,0.0,0.0),0.1,0.2,2.0,0.5);glLinearArrow3D(vector_ld(0.0,+2.0,0.0),vector_ld(0.0,+1.0,0.0),0.1,0.2,2.0,0.5);glLinearArrow3D(vector_ld(0.0,-2.0,0.0),vector_ld(0.0,-1.0,0.0),0.1,0.2,2.0,0.5);glLinearArrow3D(vector_ld(0.0,0.0,+2.0),vector_ld(0.0,0.0,+1.0),0.1,0.2,2.0,0.5);glLinearArrow3D(vector_ld(0.0,0.0,-2.0),vector_ld(0.0,0.0,-1.0),0.1,0.2,2.0,0.5);

                    和箭頭的概述(在圖像的右側):

                    我正在使用我的矢量庫,所以這里有一些解釋:


                    vector_mul(a[3],b[3],c[3]) 是叉積 a = b x c
                    vector_mul(a[3],b[3],c) 是簡單的標量乘法 a = b.c
                    a = vector_mul(b[3],c[3]) 是點積 a = (b.c)
                    vector_one(a[3],b[3])是單位向量a = b/|b|
                    vector_copy(a[3],b[3]) 只是復制 a = b
                    vector_add(a[3],b[3],c[3]) 正在添加 a = b + c
                    vector_sub(a[3],b[3],c[3]) 正在減去 a = b - c
                    vector_neg(a[3],b[3]) 是否定a = -b
                    vector_ld(a[3],x,y,z) 正在加載 a = (x,y,z)

                    pos 是圓箭頭的中心位置,nor 是箭頭所在平面的法線.bin 是雙法線,角度從這個軸開始.應該垂直于nor.r,r0,r1 是箭頭的半徑(彎、管、錐)

                    線性箭頭類似于 dir 是箭頭的方向,l 是箭頭大小,al 是箭頭大小.

                    I am attempting to make a curved 3D arrow in three.js. To accomplish this task, I have created a Tube that follows a curved path and a Cylinder shaped as a cone (by setting radiusTop to be tiny). They currently look like so:

                    I am attempting to position the Arrow Head (Cylinder shaped as a cone) at the end of the Tube like so: (Photoshopped)

                    I am not terribly strong in math and pretty new to three.js. Could someone help me understand how to connect the two?

                    Here is my current code:

                            import T from 'three';
                    
                            var findY = function(r, x)
                            {
                               return Math.sqrt((r * r) - (x * x));
                            }
                    
                            var radius = 25;
                            var x = 0;
                            var z = 0;
                            var numberOfPoints = 10;
                            var interval =  (radius/numberOfPoints);
                            var points = [];
                    
                            for (var i = numberOfPoints; i >= 0; i--) 
                            {
                               var y = findY(radius, x);
                               points.push(new T.Vector3(x, y, z))
                               x = x + interval;
                            }
                    
                            x = x - interval;
                    
                            for (var i = numberOfPoints - 1 ; i >= 0; i--) 
                            {
                               y = findY(radius, x) * -1;
                               points.push(new T.Vector3(x, y, z));
                               x = x - interval;
                            }
                    
                            var path = new T.CatmullRomCurve3(points);
                    
                            var tubeGeometry = new T.TubeGeometry(
                                path,  //path
                                10,    //segments
                                radius / 10,     //radius
                                8,     //radiusSegments
                                false  //closed
                            );
                    
                            var coneGeometry = new T.CylinderGeometry(
                                radiusTop = 0.1,
                                radiusBottom = radius/5,
                                height = 10,
                                radialSegments = 10,
                                heightSegments = 10,
                                openEnded = 1
                            );
                    
                            var material = new T.MeshBasicMaterial( { color: 0x00ff00 } );
                    
                            var tube = new T.Mesh( tubeGeometry, material );
                            var cone = new T.Mesh( coneGeometry, material );
                    
                            // Translate and Rotate cone?
                    

                    I would greatly appreciate if someone could attempt a simple explanation of what is necessary mathematically and programmatically accomplish

                    • Finding the normal located at the end of the tube
                    • Shifting the Cone to the correct location

                    Any help is appreciated!

                    解決方案

                    Do not use rotation for this when you can create the arrowhead directly in place. Similarly the bended tube can be done this way too. Only thing you need for it is the last line segment defined by A,B endpoints.

                    Let A be the sharp point and B the disc base center. To create arrowhead you need 2 additional basis vectors let call them U,V and radius r of base disc. From them you can create disc points with simple circle formula like this:

                    1. obtain AB endpoints

                    2. compute U,V basis vectors

                      The U,V should lie in the disc base of arrowhead and should be perpendicular to each other. direction of the arrowhead (line |BA|) is the disc base normal so exploit cross product which returns perpendicular vector to the multiplied ones so:

                      W = B-A;
                      W /= |W|;    // unit vector
                      T = (1,0,0); // temp any non zero vector not parallel to W
                      if ( |(W.T)|>0.75 ) T = (0,1,0); // if abs dot product of T and W is close to 1 it means they are close to parallel so chose different T
                      U = (T x W) // U is perpendicular to T,W
                      V = (U x W) // V is perpendicular to U,W
                      

                    3. create/render arrowhead geometry

                      That is easy booth A,B are centers of triangle fan (need 2) and the disc base points are computed like this:

                      P(ang) = B + U.r.cos(ang) + V.r.sin(ang)
                      

                      So just loop ang through the whole circle with some step so you got enough points (usually 36 is enough) and do both triangle fans from them. Do not forget the last disc point must be the same as the first one otherwise you will got ugly seems or hole on the ang = 0 or 360 deg.

                    If you still want to go for rotations instead then this is doable like this. compute U,V,W in the same way as above and construct transformation matrix from them. the origin O will be point B and axises X,Y,Z will be U,V,W the order depends on your arrowhead model. W should match the model axis. U,V can be in any order. So just copy all the vectors to their places and use this matrix for rendering. For more info see:

                    • Understanding 4x4 homogenous transform matrices

                    [Notes]

                    If you do not know how to compute vector operations like cross/dot products or absolute value see:

                    // cross product: W = U x V
                    W.x=(U.y*V.z)-(U.z*V.y)
                    W.y=(U.z*V.x)-(U.x*V.z)
                    W.z=(U.x*V.y)-(U.y*V.x)
                    // dot product: a = (U.V)
                    a=U.x*V.x+U.y*V.y+U.z*V.z
                    // abs of vector a = |U|
                    a=sqrt((U.x*U.x)+(U.y*U.y)+(U.z*U.z))
                    

                    [Edit1] simple GL implementation

                    I do not code in your environment but as downvote and comment suggest you guys are not able to put this together on your own which is odd considering you got this far so here simple C++/GL exmaple of how to do this (you can port this to your environment):

                    void glArrowRoundxy(GLfloat x0,GLfloat y0,GLfloat z0,GLfloat r,GLfloat r0,GLfloat r1,GLfloat a0,GLfloat a1,GLfloat a2)
                        {
                        const int _glCircleN=50;    // points per circle
                        const int n=3*_glCircleN;
                        int i,j,ix,e;
                        float x,y,z,x1,y1,z1,a,b,da,db=pi2/(_glCircleN-1);
                        float ux,uy,uz,vx,vy,vz,u,v;
                        // buffers
                        GLfloat ptab[6*_glCircleN],*p0,*p1,*n0,*n1,*p;
                        p0=ptab+(0*_glCircleN);     // previous tube segment circle points
                        p1=ptab+(3*_glCircleN);     // actual tube segment circle points
                        da=+db; if (a0>a1) da=-db;  // main angle step direction
                        ux=0.0;                     // U is normal to arrow plane
                        uy=0.0;
                        uz=1.0;
                        // arc interpolation a=<a0,a1>
                        for (e=1,j=0,a=a0;e;j++,a+=da)
                            {
                            // end conditions
                            if ((da>0.0)&&(a>=a1)) { a=a1; e=0; }
                            if ((da<0.0)&&(a<=a1)) { a=a1; e=0; }
                            // compute actual tube ceneter
                            x1=x0+(r*cos(a));
                            y1=y0+(r*sin(a));
                            z1=z0;
                            // V is direction from (x0,y0,z0) to (x1,y1,z1)
                            vx=x1-x0;
                            vy=y1-y0;
                            vz=z1-z0;
                            // and unit of coarse
                            b=sqrt((vx*vx)+(vy*vy)+(vz*vz));
                            if (b>1e-6) b=1.0/b; else b=0.0;
                            vx*=b;
                            vy*=b;
                            vz*=b;
                            // tube segment
                            for (ix=0,b=0.0,i=0;i<_glCircleN;i++,b+=db)
                                {
                                u=r0*cos(b);
                                v=r0*sin(b);
                                p1[ix]=x1+(ux*u)+(vx*v); ix++;
                                p1[ix]=y1+(uy*u)+(vy*v); ix++;
                                p1[ix]=z1+(uz*u)+(vz*v); ix++;
                                }
                            if (!j)
                                {
                                glBegin(GL_TRIANGLE_FAN);
                                glVertex3f(x1,y1,z1);
                                for (ix=0;ix<n;ix+=3) glVertex3fv(p1+ix);
                                glEnd();
                                }
                            else{
                                glBegin(GL_QUAD_STRIP);
                                for (ix=0;ix<n;ix+=3)
                                    {
                                    glVertex3fv(p0+ix);
                                    glVertex3fv(p1+ix);
                                    }
                                glEnd();
                                }
                            // swap buffers
                            p=p0; p0=p1; p1=p;
                            p=n0; n0=n1; n1=p;
                            }
                        // arrowhead a=<a1,a2>
                        for (ix=0,b=0.0,i=0;i<_glCircleN;i++,b+=db)
                            {
                            u=r1*cos(b);
                            v=r1*sin(b);
                            p1[ix]=x1+(ux*u)+(vx*v); ix++;
                            p1[ix]=y1+(uy*u)+(vy*v); ix++;
                            p1[ix]=z1+(uz*u)+(vz*v); ix++;
                            }
                        glBegin(GL_TRIANGLE_FAN);
                        glVertex3f(x1,y1,z1);
                        for (ix=0;ix<n;ix+=3) glVertex3fv(p1+ix);
                        glEnd();
                        x1=x0+(r*cos(a2));
                        y1=y0+(r*sin(a2));
                        z1=z0;
                        glBegin(GL_TRIANGLE_FAN);
                        glVertex3f(x1,y1,z1);
                        for (ix=n-3;ix>=0;ix-=3) glVertex3fv(p1+ix);
                        glEnd();
                        }
                    

                    This renders bended arrow in XY plane with center x,y,z and big radius r. The r0 is tube radius and r1 is arrowhead base radius. As I do not have your curve definition I choose circle in XY plane. The a0,a1,a2 are angles where arrow starts (a0), arrowhead starts (a1) and ends (a2). The pi2 is just constant pi2=6.283185307179586476925286766559.

                    The idea is to remember actual and previous tube segment circle points so there for the ptab,p0,p1 otherwise you would need to compute everything twice.

                    As I chose XY plane directly then I know that one base vector is normal to it. and second is perpendicular to it and to arrow direction luckily circle properties provides this on its own therefore no need for cross products in this case.

                    Hope it is clear enough if not comment me.

                    [Edit2]

                    I needed to add this to my engine so here is the 3D version (not bound just to axis aligned arrows and the cone is bended too). It is the same except the basis vector computation and I also change the angles a bit in the header <a0,a1> is the whole interval and aa is the arrowhead size but latter in code it is converted to the original convention. I added also normals for lighting computations. I added also linear Arrow where the computation of basis vectors is not taking advantage of circle properties in case you got different curve. Here result:

                    //---------------------------------------------------------------------------
                    const int _glCircleN=50;    // points per circle
                    //---------------------------------------------------------------------------
                    void glCircleArrowxy(GLfloat x0,GLfloat y0,GLfloat z0,GLfloat r,GLfloat r0,GLfloat r1,GLfloat a0,GLfloat a1,GLfloat aa)
                        {
                        double pos[3]={ x0, y0, z0};
                        double nor[3]={0.0,0.0,1.0};
                        double bin[3]={1.0,0.0,0.0};
                        glCircleArrow3D(pos,nor,bin,r,r0,r1,a0,a1,aa);
                        }
                    //---------------------------------------------------------------------------
                    void glCircleArrowyz(GLfloat x0,GLfloat y0,GLfloat z0,GLfloat r,GLfloat r0,GLfloat r1,GLfloat a0,GLfloat a1,GLfloat aa)
                        {
                        double pos[3]={ x0, y0, z0};
                        double nor[3]={1.0,0.0,0.0};
                        double bin[3]={0.0,1.0,0.0};
                        glCircleArrow3D(pos,nor,bin,r,r0,r1,a0,a1,aa);
                        }
                    //---------------------------------------------------------------------------
                    void glCircleArrowxz(GLfloat x0,GLfloat y0,GLfloat z0,GLfloat r,GLfloat r0,GLfloat r1,GLfloat a0,GLfloat a1,GLfloat aa)
                        {
                        double pos[3]={ x0, y0, z0};
                        double nor[3]={0.0,1.0,0.0};
                        double bin[3]={0.0,0.0,1.0};
                        glCircleArrow3D(pos,nor,bin,r,r0,r1,a0,a1,aa);
                        }
                    //---------------------------------------------------------------------------
                    void glCircleArrow3D(double *pos,double *nor,double *bin,double r,double r0,double r1,double a0,double a1,double aa)
                        {
                    //  const int _glCircleN=20;    // points per circle
                        int e,i,j,N=3*_glCircleN;
                        double U[3],V[3],u,v;
                        double a,b,da,db=pi2/double(_glCircleN-1),a2,rr;
                        double *ptab,*p0,*p1,*n0,*n1,*pp,p[3],q[3],c[3],n[3],tan[3];
                        // buffers
                        ptab=new double [12*_glCircleN]; if (ptab==NULL) return;
                        p0=ptab+(0*_glCircleN);
                        n0=ptab+(3*_glCircleN);
                        p1=ptab+(6*_glCircleN);
                        n1=ptab+(9*_glCircleN);
                        // prepare angles
                        a2=a1; da=db; aa=fabs(aa);
                        if (a0>a1) { da=-da; aa=-aa; }
                        a1-=aa;
                        // compute missing basis vectors
                        vector_copy(U,nor);         // U is normal to arrow plane
                        vector_mul(tan,nor,bin);    // tangent is perpendicular to normal and binormal
                        // arc interpolation a=<a0,a2>
                        for (e=0,j=0,a=a0;e<5;j++,a+=da)
                            {
                            // end conditions
                            if (e==0)   // e=0
                                {
                                if ((da>0.0)&&(a>=a1)) { a=a1; e++; }
                                if ((da<0.0)&&(a<=a1)) { a=a1; e++; }
                                rr=r0;
                                }
                            else{       // e=1,2,3,4
                                if ((da>0.0)&&(a>=a2)) { a=a2; e++; }
                                if ((da<0.0)&&(a<=a2)) { a=a2; e++; }
                                rr=r1*fabs(divide(a-a2,a2-a1));
                                }
                            // compute actual tube segment center c[3]
                            u=r*cos(a);
                            v=r*sin(a);
                            vector_mul(p,bin,u);
                            vector_mul(q,tan,v);
                            vector_add(c,p,  q);
                            vector_add(c,c,pos);
                            // V is unit direction from arrow center to tube segment center
                            vector_sub(V,c,pos);
                            vector_one(V,V);
                            // tube segment interpolation
                            for (b=0.0,i=0;i<N;i+=3,b+=db)
                                {
                                u=cos(b);
                                v=sin(b);
                                vector_mul(p,U,u);      // normal
                                vector_mul(q,V,v);
                                vector_add(n1+i,p,q);
                                vector_mul(p,n1+i,rr);  // vertex
                                vector_add(p1+i,p,c);
                                }
                            if (e>1)                    // recompute normals for cone
                                {
                                for (i=3;i<N;i+=3)
                                    {
                                    vector_sub(p,p0+i  ,p1+i);
                                    vector_sub(q,p1+i-3,p1+i);
                                    vector_mul(p,p,q);
                                    vector_one(n1+i,p);
                                    }
                                vector_sub(p,p0    ,p1);
                                vector_sub(q,p1+N-3,p1);
                                vector_mul(p,q,p);
                                vector_one(n1,p);
                                if (da>0.0) for (i=0;i<N;i+=3) vector_neg(n1+i,n1+i);
                                if (e==  3) for (i=0;i<N;i+=3) vector_copy(n0+i,n1+i);
                                }
                            // render base disc
                            if (!j)
                                {
                                vector_mul(n,U,V);
                                glBegin(GL_TRIANGLE_FAN);
                                glNormal3dv(n);
                                glVertex3dv(c);
                                if (da<0.0) for (i=N-3;i>=0;i-=3) glVertex3dv(p1+i);
                                else        for (i=  0;i< N;i+=3) glVertex3dv(p1+i);
                                glEnd();
                                }
                            // render tube
                            else{
                                glBegin(GL_QUAD_STRIP);
                                if (da<0.0) for (i=0;i<N;i+=3)
                                    {
                                    glNormal3dv(n1+i); glVertex3dv(p1+i);
                                    glNormal3dv(n0+i); glVertex3dv(p0+i);
                                    }
                                else for (i=0;i<N;i+=3)
                                    {
                                    glNormal3dv(n0+i); glVertex3dv(p0+i);
                                    glNormal3dv(n1+i); glVertex3dv(p1+i);
                                    }
                                glEnd();
                                }
                            // swap buffers
                            pp=p0; p0=p1; p1=pp;
                            pp=n0; n0=n1; n1=pp;
                            // handle r0 -> r1 edge
                            if (e==1) a-=da;
                            if ((e==1)||(e==2)||(e==3)) e++;
                            }
                        // release buffers
                        delete[] ptab;
                        }
                    //---------------------------------------------------------------------------
                    void glLinearArrow3D(double *pos,double *dir,double r0,double r1,double l,double al)
                        {
                    //  const int _glCircleN=20;    // points per circle
                        int e,i,N=3*_glCircleN;
                        double U[3],V[3],W[3],u,v;
                        double a,da=pi2/double(_glCircleN-1),r,t;
                        double *ptab,*p0,*p1,*n1,*pp,p[3],q[3],c[3],n[3];
                        // buffers
                        ptab=new double [9*_glCircleN]; if (ptab==NULL) return;
                        p0=ptab+(0*_glCircleN);
                        p1=ptab+(3*_glCircleN);
                        n1=ptab+(6*_glCircleN);
                        // compute basis vectors
                        vector_one(W,dir);
                        vector_ld(p,1.0,0.0,0.0);
                        vector_ld(q,0.0,1.0,0.0);
                        vector_ld(n,0.0,0.0,1.0);
                        a=fabs(vector_mul(W,p));            pp=p; t=a;
                        a=fabs(vector_mul(W,q)); if (t>a) { pp=q; t=a; }
                        a=fabs(vector_mul(W,n)); if (t>a) { pp=n; t=a; }
                        vector_mul(U,W,pp);
                        vector_mul(V,U,W);
                        vector_mul(U,V,W);
                        for (e=0;e<4;e++)
                            {
                            // segment center
                            if (e==0) { t=0.0;  r= r0; }
                            if (e==1) { t=l-al; r= r0; }
                            if (e==2) { t=l-al; r= r1; }
                            if (e==3) { t=l;    r=0.0; }
                            vector_mul(c,W,t);
                            vector_add(c,c,pos);
                            // tube segment interpolation
                            for (a=0.0,i=0;i<N;i+=3,a+=da)
                                {
                                u=cos(a);
                                v=sin(a);
                                vector_mul(p,U,u);      // normal
                                vector_mul(q,V,v);
                                vector_add(n1+i,p,q);
                                vector_mul(p,n1+i,r);   // vertex
                                vector_add(p1+i,p,c);
                                }
                            if (e>2)                    // recompute normals for cone
                                {
                                for (i=3;i<N;i+=3)
                                    {
                                    vector_sub(p,p0+i  ,p1+i);
                                    vector_sub(q,p1+i-3,p1+i);
                                    vector_mul(p,p,q);
                                    vector_one(n1+i,p);
                                    }
                                vector_sub(p,p0    ,p1);
                                vector_sub(q,p1+N-3,p1);
                                vector_mul(p,q,p);
                                vector_one(n1,p);
                                }
                            // render base disc
                            if (!e)
                                {
                                vector_neg(n,W);
                                glBegin(GL_TRIANGLE_FAN);
                                glNormal3dv(n);
                                glVertex3dv(c);
                                for (i=0;i<N;i+=3) glVertex3dv(p1+i);
                                glEnd();
                                }
                            // render tube
                            else{
                                glBegin(GL_QUAD_STRIP);
                                for (i=0;i<N;i+=3)
                                    {
                                    glNormal3dv(n1+i);
                                    glVertex3dv(p0+i);
                                    glVertex3dv(p1+i);
                                    }
                                glEnd();
                                }
                            // swap buffers
                            pp=p0; p0=p1; p1=pp;
                            }
                        // release buffers
                        delete[] ptab;
                        }
                    //---------------------------------------------------------------------------
                    

                    usage:

                    glColor3f(0.5,0.5,0.5);
                    
                    glCircleArrowyz(+3.5,0.0,0.0,0.5,0.1,0.2,0.0*deg,+270.0*deg,45.0*deg);
                    
                    glCircleArrowyz(-3.5,0.0,0.0,0.5,0.1,0.2,0.0*deg,-270.0*deg,45.0*deg);
                    glCircleArrowxz(0.0,+3.5,0.0,0.5,0.1,0.2,0.0*deg,+270.0*deg,45.0*deg);
                    glCircleArrowxz(0.0,-3.5,0.0,0.5,0.1,0.2,0.0*deg,-270.0*deg,45.0*deg);
                    glCircleArrowxy(0.0,0.0,+3.5,0.5,0.1,0.2,0.0*deg,+270.0*deg,45.0*deg);
                    glCircleArrowxy(0.0,0.0,-3.5,0.5,0.1,0.2,0.0*deg,-270.0*deg,45.0*deg);
                    glColor3f(0.2,0.2,0.2);
                    glLinearArrow3D(vector_ld(+2.0,0.0,0.0),vector_ld(+1.0,0.0,0.0),0.1,0.2,2.0,0.5);
                    glLinearArrow3D(vector_ld(-2.0,0.0,0.0),vector_ld(-1.0,0.0,0.0),0.1,0.2,2.0,0.5);
                    glLinearArrow3D(vector_ld(0.0,+2.0,0.0),vector_ld(0.0,+1.0,0.0),0.1,0.2,2.0,0.5);
                    glLinearArrow3D(vector_ld(0.0,-2.0,0.0),vector_ld(0.0,-1.0,0.0),0.1,0.2,2.0,0.5);
                    glLinearArrow3D(vector_ld(0.0,0.0,+2.0),vector_ld(0.0,0.0,+1.0),0.1,0.2,2.0,0.5);
                    glLinearArrow3D(vector_ld(0.0,0.0,-2.0),vector_ld(0.0,0.0,-1.0),0.1,0.2,2.0,0.5);
                    

                    and overview of the arows (on the right side of image):

                    I am using my vector lib so here are some explanations:


                    vector_mul(a[3],b[3],c[3]) is cross product a = b x c
                    vector_mul(a[3],b[3],c) is simple multiplication by scalar a = b.c
                    a = vector_mul(b[3],c[3]) is dot product a = (b.c)
                    vector_one(a[3],b[3]) is unit vector a = b/|b|
                    vector_copy(a[3],b[3]) is just copy a = b
                    vector_add(a[3],b[3],c[3]) is adding a = b + c
                    vector_sub(a[3],b[3],c[3]) is substracting a = b - c
                    vector_neg(a[3],b[3]) is negation a = -b
                    vector_ld(a[3],x,y,z) is just loading a = (x,y,z)

                    The pos is the center position of your circle arrow and nor is normal of the plane in which the arrow lies. bin is bi-normal and the angles are starting from this axis. should be perpendicular to nor. r,r0,r1 are the radiuses of the arrow (bend,tube,cone)

                    The linear arrow is similar the dir is direction of the arrow, l is arrow size and al is arrowhead size.

                    這篇關于根據管端法線向圓柱體應用旋轉的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

                    【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

                  相關文檔推薦

                  Use IScroll in Angular 2 / Typescript(在 Angular 2/Typescript 中使用 IScroll)
                  anime.js not working in Ionic 3 project(Anime.js 在 Ionic 3 項目中不起作用)
                  Ionic 3 - Update Observable with Asynchronous Data(Ionic 3 - 使用異步數據更新 Observable)
                  Angular 2: file not found on local .json file(Angular 2:在本地 .json 文件中找不到文件)
                  In Ionic 2, how do I create a custom directive that uses Ionic components?(在 Ionic 2 中,如何創建使用 Ionic 組件的自定義指令?)
                  Use ViewChild for dynamic elements - Angular 2 amp; ionic 2(將 ViewChild 用于動態元素 - Angular 2 amp;離子2)

                  <small id='dEUd5'></small><noframes id='dEUd5'>

                    <bdo id='dEUd5'></bdo><ul id='dEUd5'></ul>
                  • <i id='dEUd5'><tr id='dEUd5'><dt id='dEUd5'><q id='dEUd5'><span id='dEUd5'><b id='dEUd5'><form id='dEUd5'><ins id='dEUd5'></ins><ul id='dEUd5'></ul><sub id='dEUd5'></sub></form><legend id='dEUd5'></legend><bdo id='dEUd5'><pre id='dEUd5'><center id='dEUd5'></center></pre></bdo></b><th id='dEUd5'></th></span></q></dt></tr></i><div class="1zpndjv" id='dEUd5'><tfoot id='dEUd5'></tfoot><dl id='dEUd5'><fieldset id='dEUd5'></fieldset></dl></div>

                    <legend id='dEUd5'><style id='dEUd5'><dir id='dEUd5'><q id='dEUd5'></q></dir></style></legend>
                        <tbody id='dEUd5'></tbody>
                      1. <tfoot id='dEUd5'></tfoot>

                          • 主站蜘蛛池模板: 工控机-工业平板电脑-研华工控机-研越无风扇嵌入式box工控机 | 带式压滤机_污泥压滤机_污泥脱水机_带式过滤机_带式压滤机厂家-河南恒磊环保设备有限公司 | 耐热钢-耐磨钢-山东聚金合金钢铸造有限公司 | 膜结构_ETFE膜结构_膜结构厂家_膜结构设计-深圳市烨兴智能空间技术有限公司 | 水上浮桥-游艇码头-浮动码头-游船码头-码瑞纳游艇码头工程 | 西安展台设计搭建_西安活动策划公司_西安会议会场布置_西安展厅设计西安旭阳展览展示 | 博医通医疗器械互联网供应链服务平台_博医通 | 煤棒机_增碳剂颗粒机_活性炭颗粒机_木炭粉成型机-巩义市老城振华机械厂 | 纸塑分离机-纸塑分离清洗机设备-压力筛-碎浆机厂家金双联环保 | 智能监控-安防监控-监控系统安装-弱电工程公司_成都万全电子 | 智慧钢琴-电钢琴-便携钢琴-数码钢琴-深圳市特伦斯乐器有限公司 | 钢格板|热镀锌钢格板|钢格栅板|钢格栅|格栅板-安平县昊泽丝网制品有限公司 | 慈溪麦田广告公司,提供慈溪广告设计。 | 成都离婚律师|成都结婚律师|成都离婚财产分割律师|成都律师-成都离婚律师网 | 石膏基自流平砂浆厂家-高强石膏基保温隔声自流平-轻质抹灰石膏粉砂浆批发-永康市汇利建设有限公司 | 合肥汽车充电桩_安徽充电桩_电动交流充电桩厂家_安徽科帝新能源科技有限公司 | 小区健身器材_户外健身器材_室外健身器材_公园健身路径-沧州浩然体育器材有限公司 | 针焰试验仪,灼热丝试验仪,漏电起痕试验仪,水平垂直燃烧试验仪 - 苏州亚诺天下仪器有限公司 | 继电器模组-IO端子台-plc连接线-省配线模组厂家-世麦德 | 制样机-密封锤式破碎机-粉碎机-智能马弗炉-南昌科鑫制样 | 贝朗斯动力商城(BRCPOWER.COM) - 买叉车蓄电池上贝朗斯商城,价格更超值,品质有保障! | 双齿辊破碎机-大型狼牙破碎机视频-对辊破碎机价格/型号图片-金联机械设备生产厂家 | 海尔生物医疗四川代理商,海尔低温冰箱四川销售-成都壹科医疗器械有限公司 | 不锈钢复合板|钛复合板|金属复合板|南钢集团安徽金元素复合材料有限公司-官网 | 手持式浮游菌采样器-全排二级生物安全柜-浙江孚夏医疗科技有限公司 | 危废处理系统,水泥厂DCS集散控制系统,石灰窑设备自动化控制系统-淄博正展工控设备 | 压力控制器,差压控制器,温度控制器,防爆压力控制器,防爆温度控制器,防爆差压控制器-常州天利智能控制股份有限公司 | 安徽千住锡膏_安徽阿尔法锡膏锡条_安徽唯特偶锡膏_卡夫特胶水-芜湖荣亮电子科技有限公司 | 课件导航网_ppt课件_课件模板_课件下载_最新课件资源分享发布平台 | 小型高低温循环试验箱-可程式高低温湿热交变试验箱-东莞市拓德环境测试设备有限公司 | PE一体化污水处理设备_地埋式生活污水净化槽定制厂家-岩康塑业 | Jaeaiot捷易科技-英伟达AI显卡模组/GPU整机服务器供应商 | 高压管道冲洗清洗机_液压剪叉式升降机平台厂家-林君机电 | 深圳希玛林顺潮眼科医院(官网)│深圳眼科医院│医保定点│香港希玛林顺潮眼科中心连锁品牌 | 施工围挡-施工PVC围挡-工程围挡-深圳市旭东钢构技术开发有限公司 | 耐驰泵阀管件制造-耐驰泵阀科技(天津)有限公司 | 浙江寺庙设计-杭州寺院设计-宁波寺庙规划_汉匠| T恤衫定做,企业文化衫制作订做,广告T恤POLO衫定制厂家[源头工厂]-【汉诚T恤定制网】 | 知网论文检测系统入口_论文查重免费查重_中国知网论文查询_学术不端检测系统 | 冻干机(冷冻干燥机)_小型|实验型|食品真空冷冻干燥机-松源 | 深圳美安可自动化设备有限公司,喷码机,定制喷码机,二维码喷码机,深圳喷码机,纸箱喷码机,东莞喷码机 UV喷码机,日期喷码机,鸡蛋喷码机,管芯喷码机,管内壁喷码机,喷码机厂家 |