使用OpenGL ES 2.0和iOS,如何在两点之间绘制圆柱体?
我得到了两个代表圆柱体起点和终点的使用OpenGL ES 2.0和iOS,如何在两点之间绘制圆柱体?,ios,opengl-es-2.0,Ios,Opengl Es 2.0,我得到了两个代表圆柱体起点和终点的GLKVector3。使用这些点和半径,我需要构建和渲染圆柱体。我可以在点之间构建一个具有正确距离的圆柱体,但方向是固定的(当前始终是y(0,1,0)向上方向)。我不确定我需要做什么样的计算才能使圆柱体在两点之间的正确平面上,这样一条线就会穿过两个端点。我在想,当我用方向向量或角度创建顶点数据时,可以应用某种计算方法,这将创建指向正确方向的圆柱体。有没有人有或者知道一种算法可以帮助你?请检查这一点;它已经过时了,但在适应了算法之后,它就像一个符咒。一个提示,Op
GLKVector3
。使用这些点和半径,我需要构建和渲染圆柱体。我可以在点之间构建一个具有正确距离的圆柱体,但方向是固定的(当前始终是y(0,1,0)向上方向)。我不确定我需要做什么样的计算才能使圆柱体在两点之间的正确平面上,这样一条线就会穿过两个端点。我在想,当我用方向向量或角度创建顶点数据时,可以应用某种计算方法,这将创建指向正确方向的圆柱体。有没有人有或者知道一种算法可以帮助你?请检查这一点;它已经过时了,但在适应了算法之后,它就像一个符咒。一个提示,OpenGL ES 2.0只支持三角形,因此,不要像方法那样使用GL_四边形条带,而是使用GL_三角形条带,结果是相同的。还包含了一系列关于OpenGL几何图形的其他有用信息
有关解决方案,请参见下面的代码。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) * q.x;
normal.y = cosf(theta) * perp.y + sinf(theta) * q.y;
normal.z = cosf(theta) * perp.z + sinf(theta) * q.z;
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;
}
-(instancetype)initWithOriginRadius:(CGFloat)originRadius
originPoint:(GLKVector3)原点
安德拉迪乌斯:(CGFloat)端半径
atEndPoint:(GLKVector3)端点
带精度:(NSInteger)精度
andColor:(GLKVECTRO4)颜色
{
self=[super init];
如果(自我){
//从原点到端点的法线指向
GLKVector3 normal=GLKVector3Make(originPoint.x-endPoint.x,
originPoint.y-endPoint.y,
原点z-端点z);
//创建两个垂直向量-perp和q
GLKVector3 perp=正常;
if(normal.x==0&&normal.z==0){
perp.x+=1;
}否则{
人均y+=1;
}
//叉积
GLKVector3 q=GLKVector3交叉积(perp,正常);
perp=GLKVector3CrossProduct(正常,q);
//规范化向量
perp=GLKVector3规范化(perp);
q=GLKVector3规范化(q);
//计算顶点
cgpi=2*PI;
NSInteger指数=0;
对于(NSInteger i=0;i
您是否绘制了多个圆柱体?或者曾经在不同的位置画过它?如果是这样的话,那么使用awesome文章中的算法就不是什么好主意了。每次将几何体数据上载到GPU时,都会产生性能成本
一个更好的方法是计算一次单个基本圆柱体的几何图形,比如说,一个具有单位半径和高度的圆柱体。然后,在绘制时,使用“模型到世界”变换矩阵进行缩放(如果需要,在半径和长度上独立),并将圆柱体旋转到位。这样,每次绘制调用发送到GPU的唯一新数据是一个4x4矩阵,而不是您绘制的任何多个圆柱体的所有顶点数据。我可能需要绘制任意数量的顶点数据,但通常仅绘制一个。它的位置可以是任何地方。目前,我正在生成顶点数据并将其存储在VBO中。性能很好,在这一点上生成的顶点数量相当小,我用“分辨率”表示圆周围的点数。我没有,但是如果你发一个问题,我当然可以帮你。我可以用OpenGL 2.0的圆柱体做一个例子。我有一个立方体和一个球体。看看上面的代码,它应该会给你一个好的开始。@kschins在上面的代码中AGLKMeshVertex和AGLKMeshVertexDynamic是什么?询问,因为它给了我以上两行的错误。