在iOS中使用OpenGL ES 2.0时,如何在两点之间绘制柱面?

我给了两个GLKVector3代表圆柱体的起点和终点。 使用这些点和半径,我需要build立和渲染一个圆柱体。 我可以build立一个点之间的正确距离,但在一个固定的方向(目前总是在y(0,1,0)向上的方向)一个圆柱体。 我不知道需要做什么样的计算才能将圆柱体置于两点之间的正确平面上,从而使得一条直线穿过两个端点。 我想有一种计算方法可以应用,因为我使用方向vector或angular度创build顶点数据,这将创build指向正确方向的柱面。 有没有人有algorithm,或知道一个,这将有助于?

你正在绘制多个这些气瓶吗? 或者曾经在不同的位置绘制它? 如果是这样的话,使用真棒文章中的algorithm是一个不太好的想法。 每次将几何数据上传到GPU时,都会产生性能成本。

一个更好的方法是计算单个基本圆柱体的几何graphics – 比如说单位半径和高度单位 – 并将顶点数据填充到VBO中 。 然后,在绘制时,使用模型到世界的变换matrix来缩放(如果需要,可以独立于半径和长度)并将圆柱体转动到位。 这样一来,每次绘制调用就发送给GPU的唯一新数据就是一个4×4的matrix,而不是所有的顶点数据。

检查这个真棒文章 ; 它是过时的,但适应algorithm后,它就像一个魅力。 一个技巧,OpenGL ES 2.0只支持三angular形,而不是像方法那样使用GL_QUAD_STRIP,而是使用GL_TRIANGLE_STRIP,结果是相同的。 该网站还包含一些关于OpenGL几何graphics的其他有用信息。

请参阅下面的代码解决scheme Self表示网格并包含顶点,索引等。

 - (instancetype)initWithOriginRadius:(CGFloat)originRadius atOriginPoint:(GLKVector3)originPoint andEndRadius:(CGFloat)endRadius atEndPoint:(GLKVector3)endPoint withPrecision:(NSInteger)precision andColor:(GLKVector4)color { self = [super init]; if (self) { // normal pointing from origin point to end point GLKVector3 normal = GLKVector3Make(originPoint.x - endPoint.x, originPoint.y - endPoint.y, originPoint.z - endPoint.z); // create two perpendicular vectors - perp and q GLKVector3 perp = normal; if (normal.x == 0 && normal.z == 0) { perp.x += 1; } else { perp.y += 1; } // cross product GLKVector3 q = GLKVector3CrossProduct(perp, normal); perp = GLKVector3CrossProduct(normal, q); // normalize vectors perp = GLKVector3Normalize(perp); q = GLKVector3Normalize(q); // calculate vertices CGFloat twoPi = 2 * PI; NSInteger index = 0; for (NSInteger i = 0; i < precision + 1; i++) { CGFloat theta = ((CGFloat) i) / precision * twoPi; // go around circle and get points // normals normal.x = cosf(theta) * perp.x + sinf(theta) * qx; normal.y = cosf(theta) * perp.y + sinf(theta) * qy; normal.z = cosf(theta) * perp.z + sinf(theta) * qz; AGLKMeshVertex meshVertex; AGLKMeshVertexDynamic colorVertex; // top vertex meshVertex.position.x = endPoint.x + endRadius * normal.x; meshVertex.position.y = endPoint.y + endRadius * normal.y; meshVertex.position.z = endPoint.z + endRadius * normal.z; meshVertex.normal = normal; meshVertex.originalColor = color; // append vertex [self appendVertex:meshVertex]; // append color vertex colorVertex.colors = color; [self appendColorVertex:colorVertex]; // append index [self appendIndex:index++]; // bottom vertex meshVertex.position.x = originPoint.x + originRadius * normal.x; meshVertex.position.y = originPoint.y + originRadius * normal.y; meshVertex.position.z = originPoint.z + originRadius * normal.z; meshVertex.normal = normal; meshVertex.originalColor = color; // append vertex [self appendVertex:meshVertex]; // append color vertex [self appendColorVertex:colorVertex]; // append index [self appendIndex:index++]; } // draw command [self appendCommand:GL_TRIANGLE_STRIP firstIndex:0 numberOfIndices:self.numberOfIndices materialName:@""]; } return self; }