Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C OpenGL沿路径的管状体_C_Opengl - Fatal编程技术网

C OpenGL沿路径的管状体

C OpenGL沿路径的管状体,c,opengl,C,Opengl,所以我在玩OpenGL,试图找出如何画一些有趣的形状 现在,我在做一根管子。我可以画一个直管,只要: void tube(GLfloat radius, GLfloat segment_length) { glPolygonMode(GL_BACK, GL_NONE); glPolygonMode(GL_FRONT, GL_FILL); glPushMatrix(); { GLfloat z1 = 0.0; GLfloat z2 = se

所以我在玩OpenGL,试图找出如何画一些有趣的形状

现在,我在做一根管子。我可以画一个直管,只要:

void tube(GLfloat radius, GLfloat segment_length) {
    glPolygonMode(GL_BACK, GL_NONE);
    glPolygonMode(GL_FRONT, GL_FILL);

    glPushMatrix(); {
        GLfloat z1 = 0.0;
        GLfloat z2 = segment_length;

        GLfloat y_offset = 0.0;
        GLfloat y_change = 0.00;

        int i = 0;
        int j = 0;
        for (j = 0; j < 20; j++) {
            glPushMatrix(); {
                glBegin(GL_TRIANGLE_STRIP); {
                    for (i = 360; i >= 0; i--) {
                        GLfloat theta = i * pi/180;
                        GLfloat x = radius * cos(theta);
                        GLfloat y = radius * sin(theta) + y_offset;

                        glVertex3f(x, y, z1);
                        glVertex3f(x, y, z2);
                    }
                } glEnd();
            } glPopMatrix();

            // attach the front of the next segment to the back of the previous
            z1 = z2;
            z2 += segment_length;

            // make some other adjustments
            y_offset += y_change;
        }
    } glPopMatrix();
}
空心管(GLfloat半径、GLfloat段长度){
glPolygonMode(GL_BACK,GL_NONE);
glPolygonMode(GL_前端,GL_填充);
glPushMatrix(){
GLZ1=0.0;
GLfloat z2=段长度;
GLfloat y_偏移=0.0;
GLfloat y_变化=0.00;
int i=0;
int j=0;
对于(j=0;j<20;j++){
glPushMatrix(){
glBegin(GLU三角带){
对于(i=360;i>=0;i--){
GLfloatθ=i*pi/180;
glx=半径*cos(θ);
GLfloat y=半径*sin(θ)+y_偏移;
glVertex3f(x,y,z1);
glVertex3f(x,y,z2);
}
}格伦德();
}glPopMatrix();
//将下一段的前部连接到上一段的后部
z1=z2;
z2+=段长度;
//做一些其他的调整
y_偏移量+=y_变化;
}
}glPopMatrix();
}
然而,我还没有弄明白如何使管道沿着任何预定义的路径,比如螺旋线,甚至是一条简单的线。如果将y_change更改为类似于0.01的值,它将在y方向上额外绘制每个管段偏移0.01。那太好了,但是我怎样才能使每个片段指向那个方向呢?换言之,现在绘制的每个管段都面向相同的方向,并且该方向不是管的方向(因为y_change=0.01时,该方向略微“向上”)

我不知道如何进行。我通过获取上一段和当前段之间的向量来处理向量,但我不确定如何处理它。

这个想法被称为路径控制挤出,即,你有一个基本的n维形状,并沿着n+1维曲线挤出它。我能读懂你的脸:“哈,他在说什么?”

这是一个粗略的轮廓。首先,您需要一个函数,将一个值(通常称为t)映射到空间中的连续平滑曲线。例如,螺钉:

path(t): R → R³, t ↦ ( a·sin(k·t), b·cos(k·t), c·t )
其思想是,找到一个局部坐标基来定义顶点相对于该路径的位置-有意义的是,其中一个坐标与该路径平行对齐,因此您希望找到它的切线。这是通过查找其梯度来实现的:

tangent(t): R → R³, t ↦ ( k·a·cos(k·t), -k·b·sin(k·t), c ) = d/dt path(t)
这是指向曲线的局部基向量,局部坐标系的原点在曲线的点
t

但是我们需要另外两个向量,来形成一个完整的3d基础。通常,让第二个基点垂直于曲率是一个很好的选择,这是通过求切线的旋度得到的:

normal(t): R → R³, t ↦ ( -k²·a·sin(k·t), -k²·b·cos(k·t), 0 ) = d/dt tangent(t) = d²/dt² path(t)
这就是所谓的正常

可以得到第三个基向量,取法线和切线的叉积,得到副法线。我会让你把这件事作为练习来解决

现在,要沿曲线挤出形状,您必须将路径分割为段,只需在选定范围内迭代
t
,即可获得局部原点。拉伸形状的点相对于此原点路径(t)。假设你的形状由x-y平面上的点P_n组成,那么:

for t in [k..l]:
    for p in P_n:
        yield_vertex( path(t).x + binormal(t).x * p.x, 
                      path(t).y + normal(t).y * p.y, 
                      path(t).z )

我将把它留给你们,弄清楚如何将它应用到OpenGL,毕竟你们应该通过思考来学习一些东西。如果明天才能解决,我很乐意为您提供解决方案,但通常由您自己解决会更有趣。

将其简化为。

此api能够沿以下路径进行挤压:


物理解释对于挤压问题是很好的解释(从代数矢量的角度):

事实上,我们可以看到:

1) 路径(t)是r(α(t)),其中α(t)=kt,k=2PI/w r(t)-具有三维(欧几里德空间)坐标的位置向量:x(t)、y(t)、z(t) alpha-中心的角度 w-标量角速度=2PI/k=(rxv)/| | r^2 | | |这里x是向量积

  • 切向(t)是v(t)切向速度=dr/dt(梯度)

  • 法线(t)是(t)法线加速度=dv/dt

  • 副法线(b)是向量积b(t)=a(t)xv(t)的结果

  • 副法线(b)、法线(a)和切线(v)向量定义了沿空间曲线(r)的坐标正交局部系统-参见node24.html文章中的图2.6

    因此,如果我已经记住了计算出的b(=a x v)、n(=a=dv/dt)和v(=dr/dt)的局部值,我可以使用从BNV系统到XYZ(从一个坐标系统到另一个坐标系统的转换;两者都是正交系统)的一种转换来获得x,y,z坐标; 总之,XYZ中的任何点(x,y,z)将被写入BNV系统中其投影点的线性组合

    物理学见运动方程:

    您可以在本数学文档(幻灯片3和5)中看到这一点:

    备注

    -不要忘记,一些n-可导函数可以分解为函数的线性组合,如sin和cos(参见Fourier:)

    -在plus中,不要忘记此组合函数(需要区分时有用的规则):

    结论

    -如果为一个三维实体(=三维模型=三维对象)找到一个三维参数化函数(=算法),则可以在三维空间中绘制它

    -参数化不是绘制三维实体(三维对象)的单一方法。。。 例如可以使用旋转的2D函数来获得它

    或者,请参见另一种方法(而不是参数化)以获取三维实体:管状体(沿路径拉伸)图像,作为中两个棱镜的相交结果 将P'(投影点P到两个棱镜的相交平面)的计算作为pr