CAD的正反面片以及转换程序

来源:互联网 发布:罪恶之城 知乎 编辑:程序博客网 时间:2024/06/10 22:21

 

在CAD中,一般的面片都是3D Face。3D Face是由四个顶点形成,在实际运用中为了能更好的显示,一般将这四个点中的两个点重合,形成三角形。在CAD中,一般认为,如果绘制面的时候是按逆时针方向,则为正面,反之为反面。具体来说就是,如果3D Face地四个顶点是按照逆时针方向的顺序排列,则该面为正面;按照顺时针方向顺序排列为反面。
正反面非常重要,如在3DMAX中,如果需要以地形的表面为基础高程,则地物将会在地形表面上,如果是反面,则地形向下,即在地下,看不见!所以在导入地形前,需要进行一些相应的前处理工作。下面的程序代码就是如何实现正反面判断、如何转换正反面的:

Public Class 更正CAD中面片法线方向
    Public AcadApp As AutoCAD.AcadApplication
    Public Sub 启动CAD()
        On Error Resume Next
        AcadApp = GetObject(, "AutoCAD.Application")
        If Err.Number Then
            Err.Clear()
            AcadApp = CreateObject("AutoCAD.Application")
        End If
        AcadApp.Visible = True
        AcadApp.WindowState = AutoCAD.AcWindowState.acMax
        AppActivate(AcadApp.Caption)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Call 启动CAD()
        Dim sset As AutoCAD.AcadSelectionSet
        sset = AcadApp.ActiveDocument.SelectionSets.Add("NewSelectionSet01")
        sset.SelectOnScreen()
        Dim ent As Object
        Dim count As Integer
        For Each ent In sset
            If ent.objectname = "AcDbFace" Then
                Dim ss As AutoCAD.Acad3DFace
                ss = ent
                Dim i As Integer
                Dim point01(2), point02(2), point03(2), point04(2), newArrayPoints(3, 2) As Double
                For i = 0 To 2
                    point01(i) = ss.Coordinate(0)(i)
                    point02(i) = ss.Coordinate(1)(i)
                    point03(i) = ss.Coordinate(2)(i)
                    point04(i) = ss.Coordinate(3)(i)
                Next
                If Is3Points(point01, point02, point03, point04, newArrayPoints) Then
                    ss.Delete()
                    Dim p01(2), p02(2), p03(2) As Double
                    Dim j As Integer
                    For j = 0 To 2
                        p01(j) = newArrayPoints(0, j)
                        p02(j) = newArrayPoints(1, j)
                        p03(j) = newArrayPoints(2, j)
                    Next
                    AcadApp.ActiveDocument.ModelSpace.Add3DFace(p01, p03, p02, p01)
                    count = count + 1
                End If
            End If
        Next
        MsgBox("共有" & count.ToString() & "个反面")
        AcadApp.ActiveDocument.SelectionSets.Item("NewSelectionSet01").Delete()
    End Sub
    Private Function IsNotUp(ByVal vector01() As Double, ByVal vector02() As Double) As Boolean '检验两个向量的向量积是否向上
        Dim Zresult As Double
        Zresult = vector01(0) * vector02(1) - vector01(1) * vector02(0)
        If Zresult >= 0 Then
            Return True
        End If
        Return False
    End Function
    Private Sub DoVector3(ByVal point01() As Double, ByVal point02() As Double, ByVal point03() As Double, ByRef vector01() As Double, ByRef vector02() As Double) '根据三个点得到两个矢量
        vector01(0) = point02(0) - point01(0)
        vector01(1) = point02(1) - point01(1)
        vector01(2) = point02(2) - point01(2)
        vector02(0) = point03(0) - point02(0)
        vector02(1) = point03(1) - point02(1)
        vector02(2) = point03(2) - point02(2)
    End Sub
    Private Function Is3Points(ByVal point01() As Double, ByVal point02() As Double, ByVal point03() As Double, ByVal point04() As Double, ByRef newArrayPoints(,) As Double) As Boolean
        Is3Points = False
        Dim i, j As Integer
        Dim AllPoints(3, 2) As Double
        For i = 0 To 2
            AllPoints(0, i) = point01(i)
        Next
        For i = 0 To 2
            AllPoints(1, i) = point02(i)
        Next
        For i = 0 To 2
            AllPoints(2, i) = point03(i)
        Next
        For i = 0 To 2
            AllPoints(3, i) = point04(i)
        Next
        For i = 0 To 3
            For j = 0 To 3
                If j = i Then Continue For
                If AllPoints(i, 0) = AllPoints(j, 0) And AllPoints(i, 1) = AllPoints(j, 1) And AllPoints(i, 2) = AllPoints(j, 2) Then
                    Is3Points = True
                    GoTo handle01
                End If
            Next
        Next
handle01:
        If j < 3 Then
            Dim k As Integer
            For k = 0 To 2 - j
                For i = 0 To 2
                    AllPoints(j + k, i) = AllPoints(j + k + 1, i)
                Next
            Next
        End If
        Dim vector01(2), vector02(2) As Double
        Dim p01(2), p02(2), p03(2) As Double
        For i = 0 To 2
            p01(i) = AllPoints(0, i)
            p02(i) = AllPoints(1, i)
            p03(i) = AllPoints(2, i)
        Next
        DoVector3(p01, p02, p03, vector01, vector02)
        If (IsNotUp(vector01, vector02)) Then
            Is3Points = False
        End If
        Dim s As String
        For i = 0 To 3
            s = s + AllPoints(i, 0).ToString() + "," + AllPoints(i, 1).ToString() + "," + AllPoints(i, 2).ToString() + Chr(13)
        Next
        s = s + vector01(0).ToString() + "," + vector01(1).ToString() + "," + vector01(2).ToString() + Chr(13)
        s = s + vector02(0).ToString() + "," + vector02(1).ToString() + "," + vector02(2).ToString() + Chr(13)
        RichTextBox1.Text = s
        For i = 0 To 3
            For j = 0 To 2
                newArrayPoints(i, j) = AllPoints(i, j)
            Next
        Next
    End Function
End Class

这个程序的核心就是如何判断正反面,在此我设计的是两个矢量相乘,即求向量积,判断k方向的系数的正负,从而判断面的方向.正数对应的是正面,负数对应的是负面.
原创粉丝点击