我有一个由标准平面方程 a*x + b*y + c*z + d = 0 定义的平面,我希望能够使用 OpenGL 进行绘制。如何导出在 3D 空间中将其绘制为四边形所需的四个点?
我的飞机类型定义为:
struct Plane {
float x,y,z; // plane normal
float d;
};
void DrawPlane(const Plane & p)
{
???
}
Run Code Online (Sandbox Code Playgroud)
编辑:
所以,重新思考这个问题,我真正想要的是在 3D 空间中绘制一个平面的谨慎表示,而不是一个无限的平面。根据@a.lasram 提供的答案,我制作了这个实现,它只是:
void DrawPlane(const Vector3 & center, const Vector3 & planeNormal, float planeScale, float normalVecScale, const fColorRGBA & planeColor, const fColorRGBA & normalVecColor)
{
Vector3 tangent, bitangent;
OrthogonalBasis(planeNormal, tangent, bitangent);
const Vector3 v1(center - (tangent * planeScale) - (bitangent * planeScale));
const Vector3 v2(center + (tangent * planeScale) - (bitangent * planeScale));
const Vector3 v3(center + (tangent * planeScale) + (bitangent * planeScale));
const Vector3 v4(center - (tangent * planeScale) + (bitangent * planeScale));
// Draw wireframe plane quadrilateral:
DrawLine(v1, v2, planeColor);
DrawLine(v2, v3, planeColor);
DrawLine(v3, v4, planeColor);
DrawLine(v4, v1, planeColor);
// And a line depicting the plane normal:
const Vector3 pvn(
(center[0] + planeNormal[0] * normalVecScale),
(center[1] + planeNormal[1] * normalVecScale),
(center[2] + planeNormal[2] * normalVecScale)
);
DrawLine(center, pvn, normalVecColor);
}
Run Code Online (Sandbox Code Playgroud)
其中 OrthogonalBasis() 计算平面法线的切线和双切线。
要将平面视为无限,您可以找到 4 个四边形顶点,以便剪裁的四边形和剪裁的无限平面形成相同的多边形。例子:
在平面上采样 2 个随机点P1
,P2
例如P1 != P2
。
推导出切线t
和双切线b
为
t = normalize(P2-P1); // get a normalized tangent
b = cross(t, n); // the bi-tangent is the cross product of the tangent and the normal
Run Code Online (Sandbox Code Playgroud)
计算视锥体的边界球体。球体将具有直径D
(如果这一步看起来很困难,只需设置D
为足够大的值,例如相应的球体包含截锥体)。
获取 4 个四边形顶点v1
、v2
、v3
和v4
(逆时针或顺时针取决于 P1 和 P2 的选择):
v1 = P1 - t*D - b*D;
v2 = P1 + t*D - b*D;
v3 = P1 + t*D + b*D;
v4 = P1 - t*D + b*D;
Run Code Online (Sandbox Code Playgroud)