C OpenGL沿路径的管状体
所以我在玩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
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是向量积