从平面方程绘制任意平面,OpenGL

10

我有一个平面,由标准平面方程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)
{
    ???
}

编辑:

重新思考问题,我实际上想要绘制三维空间中平面的离散表示,而不是无限平面。 基于@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);
}

OrthogonalBasis()函数计算平面法线的切线和双切线。


严格来说,平面是无限的,因此它没有边界顶点。此外,在三维空间中看到的平面 -> 二维投影要么占据整个投影平面(一般情况),要么变成一条线(部分情况)。你需要更好地定义你的问题。 - valdo
它也可以在相机后面(隐形) - MSalters
1
@valdo:如果飞机与视角轴平行,则实际上它不会填满整个视口,而是会消失在地平线上。 - datenwolf
1
@Vallentin 我并没有提到代码!不过我承认空函数是为了给任何想要实现它的善良灵魂一个提示;)任何能帮助我编写代码的数学定义都是非常好的!至于飞机是否无限大,是的!我的想法是在绘制之前允许用户定义平面的大小。 - glampert
2个回答

5
为了让平面看起来像是无限的,你可以找到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

计算视景体的包围球。该球的直径应为 D(如果这一步似乎很困难,只需将 D 设置为足够大的值,使相应的球体包含视景体即可)。

获取 4 个四边形顶点 v1v2v3v4(根据 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;

1
一种可能性(可能不是最干净的方法)是获取与平面对齐的正交向量,然后从那里选择点。
  1. P1 = < x, y, z >
  2. t1 = 与P1不共线的随机非零向量。
  3. P2 = norm(P1 cross t1)
  4. P3 = norm(P1 cross P2)
现在,所需平面中的所有点都定义为起始点加上P2和P3的线性组合。这样,您可以为几何体获取任意数量的点。
请注意:起始点只是您的平面法向量< x,y,z >乘以距离原点的绝对值:abs(d)。
此外,通过巧妙选择t1,您还可以使P2对齐某些视图。假设您正在从某个z点查看x,y平面。您可能希望选择t1 = < 0,1,0 >(只要它不与P1共线)。这将产生y分量为0的P2,以及x分量为0的P3。

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