3차원 벡터(또는 점)에 대한 구조체(structure)를 아래와 같이 작성할 수 있다.
<특이점>
1) 벡터의 성분은 X, Y, Z로 명백하므로 그냥 Public 변수로 설정함
2) 배열로 선언된 벡터 성분과도 호환되도록 함
- VB.NET의 Default Property를 이용함
- 사용예 :
[code lang-vb]Dim v1,v2 As Vector3D
Dim innerProduct As Single = v1(0)*v2(0) + v1(1)*v2(1) + v1(2)*v2(2)[/code]

구조체 소스코드
[code lang-vb]Public Structure Vector3D
    Public X, Y, Z As Single
    Public Shared ReadOnly ZeroVector As Vector3D = New Vector3D(0, 0, 0)

#Region "Constructors"
    'Private Sub New()
    'Nothing -> No default initialization
    'End Sub
    Public Sub New(ByVal x As Single, ByVal y As Single, ByVal z As Single)
        Me.X = x
        Me.Y = y
        Me.Z = z
    End Sub
    Public Sub New(ByVal v As Vector3D)
        Me.New(v.X, v.Y, v.Z) 'copy constructor
    End Sub
#End Region

#Region "Properties"
    ''' <summary>
    ''' 배열로 선언된 벡터 성분과 호환이 되도록 작성함
    ''' </summary>
    ''' <param name="index">성분의 위치를 지정하는 값 0:x, 1:y, 2:z</param>
    ''' <value>해당성분의 값</value>
    ''' <returns>해당성분의 값</returns>
    ''' <remarks>
    ''' 왜 호환되게 했나고요?
    ''' c/c++로 짠 코드를 변환하다 보면, 배열로 간단하게 해결한 것들이 많아서요.
    ''' </remarks>
    Default Public Property Elements(ByVal index As Short) As Single
        Get
            Dim i As Short = index Mod 3'실수를 방지하기 위해서
            Select Case i
                Case 0
                    Return X
                Case 1
                    Return Y
                Case 2
                    Return Z
            End Select
        End Get
        Set(ByVal value As Single)
            Dim i As Short = index Mod 3
            Select Case i
                Case 0
                    X = value
                Case 1
                    Y = value
                Case 2
                    Z = value
            End Select
        End Set
    End Property
#End Region
''각종 Property와 Operator 등은 생략 ^^
End Class[/code]

Posted by solarview

2008/06/21 04:48 2008/06/21 04:48
, , ,
Response
No Trackback , No Comment
RSS :
http://www.solarview.net/rss/response/174

Intersection with a ray and an AABB

광선과 AABB가 교차하는지를 평가하는 함수이다. 이 함수는 Stefan Zerbst의 책 "3D Game Engine Programming"의 138~140쪽에 나오는 ZFXRay::Intersects 함수를 VB.NET으로 변환한 것이다. 이 함수의 원천적인 알고리즘은 Andrew Woo의 알고리즘에서 비롯한 것이다.

[code lang-vb]Function IntersectionAABBonText(ByVal RayDirection As Vector3D, ByVal RayOrigin As Vector3D) As Boolean
        Dim RayInsideAABB As Boolean = True
        Dim HitPoint As Vector3D
        Dim MaxT As New Vector3D(-1.0F, -1.0F, -1.0F)
        Dim Epsilon As Single = 0.00001F
        '
        'Find the x component
        If (RayOrigin.X < Me.m_Min.X) Then
            HitPoint.X = Me.m_Min.X
            RayInsideAABB = False
            If RayDirection.X <> 0.0F Then
                MaxT.X = (Me.m_Min.X - RayOrigin.X) / RayDirection.X
            End If
        ElseIf (RayOrigin.X > Me.m_Max.X) Then
            HitPoint.X = Me.m_Max.X
            RayInsideAABB = False
            If RayDirection.X <> 0.0F Then
                MaxT.X = (Me.m_Max.X - RayOrigin.X) / RayDirection.X
            End If
        End If
        'Find the y component
        If (RayOrigin.Y < Me.m_Min.Y) Then
            HitPoint.Y = Me.m_Min.Y
            RayInsideAABB = False
            If RayDirection.Y <> 0.0F Then
                MaxT.Y = (Me.m_Min.Y - RayOrigin.Y) / RayDirection.Y
            End If
        ElseIf (RayOrigin.Y > Me.m_Max.Y) Then
            HitPoint.Y = Me.m_Max.Y
            RayInsideAABB = False
            If RayDirection.Y <> 0.0F Then
                MaxT.Y = (Me.m_Max.Y - RayOrigin.Y) / RayDirection.Y
            End If
        End If
        'Find the z component
        If (RayOrigin.Z < Me.m_Min.Z) Then
            HitPoint.Z = Me.m_Min.Z
            RayInsideAABB = False
            If RayDirection.Z <> 0.0F Then
                MaxT.Z = (Me.m_Min.Z - RayOrigin.Z) / RayDirection.Z
            End If
        ElseIf (RayOrigin.Z > Me.m_Max.Z) Then
            HitPoint.Z = Me.m_Max.Z
            RayInsideAABB = False
            If RayDirection.Z <> 0.0F Then
                MaxT.Z = (Me.m_Max.Z - RayOrigin.Z) / RayDirection.Z
            End If
        End If
        '
        '---- Ray origin inside bounding box
        '광선의 시점이 박스 안에 있다. 이 판단이 내 프로그램에서 유용할 것인가?
        '내 프로그램은 기본적으로 3D Face이기 때문에 정확한 판단이 아닐 수도 있다.
        If RayInsideAABB Then
            HitPoint = RayOrigin
            Return True
        End If
        '
        '---- Get largest of the maxT's for final choice of intersection
        '최대값 구하기
        Dim nPlane As Integer = 0
        If (MaxT.Y > MaxT(nPlane)) Then nPlane = 1
        If (MaxT.Z > MaxT(nPlane)) Then nPlane = 2
        '
        '---- Check final candidate actually inside box
        If (MaxT(nPlane) < 0.0F) Then Return False
        If nPlane <> 0 Then
            HitPoint.X = RayOrigin.X + MaxT.X * RayDirection.X
            If (HitPoint.X < Me.m_Min.X - Epsilon) OrElse (HitPoint.X > Me.m_Max.X + Epsilon) Then
                Return False
            End If
        End If
        If nPlane <> 1 Then
            HitPoint.Y = RayOrigin.Y + MaxT.Y * RayDirection.Y
            If (HitPoint.Y < Me.m_Min.Y - Epsilon) OrElse (HitPoint.Y > Me.m_Max.Y + Epsilon) Then
                Return False
            End If
        End If
        If nPlane <> 2 Then
            HitPoint.Z = RayOrigin.Z + MaxT.Z * RayDirection.Z
            If (HitPoint.Z < Me.m_Min.Z - Epsilon) OrElse (HitPoint.Z > Me.m_Max.Z + Epsilon) Then
                Return False
            End If
        End If
        Return True
    End Function[/code]

Posted by solarview

2008/06/19 04:45 2008/06/19 04:45
,
Response
No Trackback , No Comment
RSS :
http://www.solarview.net/rss/response/173