OpenGL:如何将2D形状转换成3D?

5
我有一个使用OpenGL编写的程序(用Delphi编写),允许用户绘制多边形。我想自动围绕轴(例如Y轴)旋转它,并获得一个3D形状。
如何做到这一点?
3个回答

5
为了简化,您可以强制至少一个点位于旋转轴上。您可以通过为多边形中的所有点的x值添加/减去相同的值,并为所有点的y值添加/减去相同的值来轻松完成此操作。它将保留原始形状。
其余部分并不是很难。选择一个相当小的角度,例如一到两度,并计算多边形顶点绕轴旋转时的坐标。然后只需使用三角形扇和三角形带连接点即可。
要围绕轴旋转一个点只需要基本的勾股定理。在0度旋转时,点在第三个维度中的值为0,处于其二维坐标。
假设点在X和Y中,我们正在绕Y旋转。原始的“X”坐标表示斜边。在1度旋转时,我们有:
sin(1) = z/hypotenuse
cos(1) = x/hypotenuse

(假设是基于角度的三角函数)

要围绕Y轴旋转点(x,y)T角度以产生一个3d点(x',y',z'):

y' = y
x' = x * cos(T)
z' = x * sin(T)

因此,对于多边形边缘上的每个点,您需要在旋转轴上创建一个包含360个点的圆。

现在按照以下方式制作3D形状:

  1. 使用中心点和第一个旋转点数组创建GL“三角形扇形”
  2. 对于每个连续的数组,使用该数组中的点和上一个数组中的点创建三角形带
  3. 最后使用最后一个数组中的点创建以中心点为中心的另一个三角形扇形

需要注意的一件事是,通常我所使用的三角函数度量角度的单位是弧度,而OpenGL使用的单位是度。要将角度转换为弧度,可使用以下公式:

degrees = radians / pi * 180

谢谢你的回答!它很简单易懂。 - Mahm00d

1

基本上,该策略是围绕给定轴扫描用户提供的配置文件,并生成一系列连接相邻切片的三角形条带。

假设用户在XZ平面绘制了多边形。另外,假设用户打算围绕Z轴(即线X = 0)旋转以生成革命体,并且多边形的一条边位于该轴上(一旦您使这个简化的情况工作起来,可以进行概括)。

对于足够简单的几何图形,您可以将多边形周长视为函数x = f(z),也就是说,假设每个Z值都有一个唯一的X值。当我们走向3D时,该函数变为r = f(z),也就是说,半径在物体的长度上是唯一的。

现在,假设我们想用M个“切片”来近似表示该实体,每个切片跨越2 * Pi / M弧度。我们还将使用N个“堆栈”(Z维度中的采样)。对于每个这样的切片,我们可以建立一个三角形条带,将一片(i)上的点与下一片(i + 1)上的点连接起来。以下是描述该过程的伪代码:

double dTheta = 2.0 * pi / M;
double dZ = (zMax - zMin) / N;

// Iterate over "slices"
for (int i = 0; i < M; ++i) {
  double theta = i * dTheta;
  double theta_next = (i+1) * dTheta;

  // Iterate over "stacks":
  for (int j = 0; j <= N; ++j) {
    double z = zMin + i * dZ;

    // Get cross-sectional radius at this Z location from your 2D model (was the
    // X coordinate in the 2D polygon):
    double r = f(z);  // See above definition

    // Convert 2D to 3D by sweeping by angle represented by this slice:
    double x = r * cos(theta);
    double y = r * sin(theta);

    // Get coordinates of next slice over so we can join them with a triangle strip:
    double xNext = r * cos(theta_next);
    double yNext = r * sin(theta_next);

    // Add these two points to your triangle strip (heavy pseudocode):
    strip.AddPoint(x, y, z);
    strip.AddPoint(xNext, yNext, z);
  }
}

这就是基本思路。正如sje697所说,您可能需要添加端盖来保持几何闭合(即实体对象,而不是壳体)。但这应该足以让您开始了。这也可以很容易地推广到环形形状(在这种情况下,您将没有一对一的r = f(z)函数)。


0
如果你只想让它旋转,那么:
glRotatef(angle,0,1,0);

将其绕 Y 轴旋转。如果你想要一个车床,那么这就更加复杂了。


我的错误。我想说的是车床。我会编辑问题。 - Mahm00d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接