我有一个OpenGL程序(用Delphi编写),允许用户绘制多边形。我想围绕一个轴(比如Y asix)自动旋转(车床)并得到一个3D形状。
我该怎么做?
答案 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形状:
有一点需要注意的是,通常,我使用的三角函数的种类以弧度为单位测量角度,而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轴旋转。如果你想要一台车床,那么这就复杂得多了。