OpenGL:如何将2D形状车削成3D?

时间:2010-11-07 09:00:23

标签: delphi opengl

我有一个OpenGL程序(用Delphi编写),允许用户绘制多边形。我想围绕一个轴(比如Y asix)自动旋转(车床)并得到一个3D形状。

我该怎么做?

3 个答案:

答案 0 :(得分:5)

为简单起见,您可以强制至少一个点位于旋转轴上。您可以通过向所有x值添加/减去相同的值,并对多边形中的点的所有y值使用相同的值来轻松完成此操作。它将保留原始形状。

剩下的并不是那么难。选择一个相当小的角度,比如一度或两度,并在围绕轴旋转时计算出多边形顶点的坐标。然后用三角形扇形和三角形条加入点。

围绕轴旋转点只是基本的毕达哥拉斯。在0度旋转时,您在2-d坐标处具有点,在第三维中具有值0。

让我们假设这些点在X和Y中,我们围绕Y旋转。原始的'X'坐标代表斜边。在1度旋转时,我们有:

sin(1) = z/hypotenuse
cos(1) = x/hypotenuse

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

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

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

因此,对于多边形边缘上的每个点,您将生成一个以旋转轴为中心的360点圆。

现在制作一个像这样的3d形状:

  1. 使用您的中心点和第一个旋转点阵列
  2. 创建一个GL'三角扇'
  3. 对于每个连续的数组,使用数组中的点和前一个数组中的点
  4. 创建一个三角形条
  5. 通过创建另一个以中心点为中心并使用最后一个数组中的点的三角形风扇完成
  6. 有一点需要注意的是,通常,我使用的三角函数的种类以弧度为单位测量角度,而OpenGL使用度数。要将度数转换为弧度,公式为:

    degrees = radians / pi * 180
    

答案 1 :(得分: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)函数)。

答案 2 :(得分:0)

如果你只是想让它旋转,那么:

glRotatef(angle,0,1,0);

将围绕Y轴旋转。如果你想要一台车床,那么这就复杂得多了。