我在网上找到了一个例子,展示了如何在OpenGL中绘制一个锥形,它位于here:它是用C ++编写的,所以我把它翻译成C#。这是新代码:
public void RenderCone(Vector3 d, Vector3 a, float h, float rd, int n)
{
Vector3 c = new Vector3(a + (-d * h));
Vector3 e0 = Perp(d);
Vector3 e1 = Vector3.Cross(e0, d);
float angInc = (float)(360.0 / n * GrimoireMath.Pi / 180);
// calculate points around directrix
List<Vector3> pts = new List<Vector3>();
for (int i = 0; i < n; ++i)
{
float rad = angInc * i;
Vector3 p = c + (((e0 * (float)Math.Cos((rad)) + (e1 * (float)Math.Sin(rad))) * rd));
pts.Add(p);
}
// draw cone top
GL.Begin(PrimitiveType.TriangleFan);
GL.Vertex3(a);
for (int i = 0; i < n; ++i)
{
GL.Vertex3(pts[i]);
}
GL.End();
// draw cone bottom
GL.Begin(PrimitiveType.TriangleFan);
GL.Vertex3(c);
for (int i = n - 1; i >= 0; --i)
{
GL.Vertex3(pts[i]);
}
GL.End();
}
public Vector3 Perp(Vector3 v)
{
float min = Math.Abs(v.X);
Vector3 cardinalAxis = new Vector3(1, 0, 0);
if (Math.Abs(v.Y) < min)
{
min = Math.Abs(v.Y);
cardinalAxis = new Vector3(0, 1, 0);
}
if (Math.Abs(v.Z) < min)
{
cardinalAxis = new Vector3(0, 0, 1);
}
return Vector3.Cross(v, cardinalAxis);
}
我认为我正确使用参数(页面在实际功能使用方面并不完全一致)。以下是原创作者提供的图例:
但是当我输入以下参数时:
RenderCone(new Vector3(0.0f, 1.0f, 0.0f), new Vector3(1.0f, 1.0f, 1.0f), 20.0f, 10.0f, 8);
我收到此信息(启用了线框):
正如你所看到的,无论是在开头还是最后,我都错过了一片。有谁知道这种方法有什么问题?或者我可能做错了会导致锥形不完整?
答案 0 :(得分:2)
// draw cone bottom
GL.Begin(PrimitiveType.TriangleFan);
GL.Vertex3(c);
for (int i = n - 1; i >= 0; --i)
{
GL.Vertex3(pts[i]);
}
GL.End();
将所有顶点相互连接并居中,但缺少一个连接。从第一个顶点到最后一个顶点没有指定连接。在循环之后添加 GL.Vertex3(pts [n-1]); 会添加缺少的连接。
答案 1 :(得分:0)
解决方案实际上非常简单,我需要将切片数量增加1.如果你问我,那就非常特别。
public void RenderCone(Vector3 baseToApexLength, Vector3 apexLocation, float height, float radius, int slices)
{
Vector3 c = new Vector3(apexLocation + (-baseToApexLength * height));
Vector3 e0 = Perpendicular(baseToApexLength);
Vector3 e1 = Vector3.Cross(e0, baseToApexLength);
float angInc = (float)(360.0 / slices * GrimoireMath.Pi / 180);
slices++; // this was the fix for my problem.
/**
* Compute the Vertices around the Directrix
*/
Vector3[] vertices = new Vector3[slices];
for (int i = 0; i < vertices.Length; ++i)
{
float rad = angInc * i;
Vector3 p = c + (((e0 * (float)Math.Cos((rad)) + (e1 * (float)Math.Sin(rad))) * radius));
vertices[i] = p;
}
/**
* Draw the Top of the Cone.
*/
GL.Begin(PrimitiveType.TriangleFan);
GL.Vertex3(apexLocation);
for (int i = 0; i < slices; ++i)
{
GL.Vertex3(vertices[i]);
}
GL.End();
/**
* Draw the Base of the Cone.
*/
GL.Begin(PrimitiveType.TriangleFan);
GL.Vertex3(c);
for (int i = slices - 1; i >= 0; --i)
{
GL.Vertex3(vertices[i]);
}
GL.End();
}