首页 > 解决方案 > 3D 计算机图形动画:背面剔除无法正常工作

问题描述

因此,我尝试使用 Visual Basic 对立方体进行背面剔除。我确信我写的代码是正确的,但不知何故,它不是我想要的背面。

这是数据结构

Structure TLine
    Dim p1, p2 As Integer
End Structure

Structure TLine2
    Dim p1, p2 As TPoint
End Structure

Structure TPoint
    Dim x, y, z, w As Double
End Structure

Structure TPolygon
    Dim p1, p2, p3 As Integer
End Structure

这是功能

Sub SetPoint(ByRef V As TPoint, ByVal a As Double, ByVal b As Double, ByVal c As Double, ByVal d As Double)
    V.x = a
    V.y = b
    V.z = c
    V.w = 1
End Sub

Sub SetLine(ByVal idx As Integer, ByVal p1 As Integer, ByVal p2 As Integer)
    edge(idx).p1 = p1
    edge(idx).p2 = p2
End Sub

Sub SetPolygon(ByVal idx As Integer, ByVal p1 As Integer, ByVal p2 As Integer, ByVal p3 As Integer)
    polygon(idx).p1 = p1
    polygon(idx).p2 = p2
    polygon(idx).p3 = p3
End Sub

这是绘图功能

Sub draw()
    bmp = New Bitmap(400, 400)
    Dim grp As Graphics = Graphics.FromImage(bmp)
    Dim i As Integer
    Dim p As New Pen(Color.Black)

    DOP.x = 0
    DOP.y = 0
    DOP.z = -2

    For i = 0 To 11
        temp_v1.x = v(polygon(i).p2).x - v(polygon(i).p1).x
        temp_v1.y = v(polygon(i).p2).y - v(polygon(i).p1).y
        temp_v1.z = v(polygon(i).p2).z - v(polygon(i).p1).z

        temp_v2.x = v(polygon(i).p3).x - v(polygon(i).p1).x
        temp_v2.y = v(polygon(i).p3).y - v(polygon(i).p1).y
        temp_v2.z = v(polygon(i).p3).z - v(polygon(i).p1).z

        normal.x = (temp_v1.y * temp_v2.z) - (temp_v2.y * temp_v1.z)
        normal.y = (temp_v1.z * temp_v2.x) - (temp_v2.z * temp_v1.x)
        normal.z = (temp_v1.x * temp_v2.y) - (temp_v2.x * temp_v1.y)

        result = (DOP.x * normal.x) + (DOP.y * normal.y) + (DOP.z * normal.z)

        If result < 0 Then
            grp.DrawLine(p, CInt(vs(polygon(i).p1).x), CInt(vs(polygon(i).p1).y), CInt(vs(polygon(i).p2).x), CInt(vs(polygon(i).p2).y))
            grp.DrawLine(p, CInt(vs(polygon(i).p1).x), CInt(vs(polygon(i).p1).y), CInt(vs(polygon(i).p3).x), CInt(vs(polygon(i).p3).y))
            grp.DrawLine(p, CInt(vs(polygon(i).p2).x), CInt(vs(polygon(i).p2).y), CInt(vs(polygon(i).p3).x), CInt(vs(polygon(i).p3).y))
            PictureBox1.Image = bmp
        End If
    Next
    'PictureBox1.Image = bmp
End Sub

这是一个立方体中的一组点和多边形

SetPoint(v(0), -1, -1, 1, 1)
    SetPoint(v(1), 1, -1, 1, 1)
    SetPoint(v(2), 1, 1, 1, 1)
    SetPoint(v(3), -1, 1, 1, 1)
    SetPoint(v(4), -1, -1, -1, 1)
    SetPoint(v(5), 1, -1, -1, 1)
    SetPoint(v(6), 1, 1, -1, 1)
    SetPoint(v(7), -1, 1, -1, 1)

    SetPolygon(0, 0, 1, 2)
    SetPolygon(1, 0, 3, 2)
    SetPolygon(2, 5, 4, 7)
    SetPolygon(3, 5, 6, 7)
    SetPolygon(4, 3, 2, 6)
    SetPolygon(5, 3, 7, 6)
    SetPolygon(6, 4, 5, 1)
    SetPolygon(7, 4, 0, 1)
    SetPolygon(8, 1, 5, 6)
    SetPolygon(9, 1, 2, 6)
    SetPolygon(10, 4, 0, 3)
    SetPolygon(11, 4, 7, 3)

这是我尝试通过旋转进行背面剔除的立方体的预览。

标签: 3dculling

解决方案


背面剔除取决于您的顶点在屏幕上的顺序。您假设顺时针或逆时针是“前”,而您只画那些。

在您的预览中,我看到您缺少一些正面,并且您绘制了一些您不应该绘制的背面。你只需要找到那几个破碎的三角形并通过交换第二个和第三个顶点来恢复它们的方向。


推荐阅读