Shape.Vertices 속성으로부터 도형의 모든 Nodes의 위치 정보를 가져오게 되면, Vertices는 (1 to n, 1 to 2) 배열값을 가집니다. 첫번째 인덱스 1~n은 Nodes의 순서이며, 두번째 인덱스는 가로 방향 위치 X와 세로방향 위치 Y를 의미합니다. 즉, (n, 1)은 n번째 점의 X좌표, (n, 2)는 n번째 점의 Y좌표를 의미합니다.
만약, Vertices 배열을 가져온 후, i 번째 점의 위치만 추출하고자 한다면, 아래와 같은 함수를 쓸 수 있습니다. 또한 모든 점들에 대한 정보는 2개의 숫자 배열이며, 이는 벡터와 동일한 역할을 합니다. 점들의 좌표, 즉 벡터에 대한 연산을 위해 아래와 같이 간단한 함수들을 미리 만들어두면 향후 코드가 간결해질 수 있습니다.
'----------------------
'Vertices 배열에서 특정 인덱스의 점을 추출
Function Node_Point(iVertices() As Single, iIndex As Long) As Single()
Function Node_Point(iVertices() As Single, iIndex As Long) As Single()
Dim tNode(1 To 2) As Single
tNode(1) = iVertices(iIndex, 1)
tNode(2) = iVertices(iIndex, 2)
Node_Point = tNode
End Function
'----------------------
'내적 함수
tNode(1) = iVertices(iIndex, 1)
tNode(2) = iVertices(iIndex, 2)
Node_Point = tNode
End Function
'----------------------
'내적 함수
Function Vec_Inner(iVec1() As Single, iVec2() As Single) As Single
Vec_Inner = iVec1(1) * iVec2(1) + iVec1(2) * iVec2(2)
End Function
'----------------------
Vec_Inner = iVec1(1) * iVec2(1) + iVec1(2) * iVec2(2)
End Function
'----------------------
'벡터에 상수를 사칙연산
Function Vec_OprConst(iVec() As Single, iConst As Single, Optional iOperation As String = "+") As Single()
Dim tVec() As Single
ReDim tVec(1 To 2)
Select Case iOperation
Case "+"
tVec(1) = iVec(1) + iConst: tVec(2) = iVec(2) + iConst
Case "-"
tVec(1) = iVec(1) - iConst: tVec(2) = iVec(2) - iConst
Case "*"
tVec(1) = iVec(1) * iConst: tVec(2) = iVec(2) * iConst
Case "/"
If iConst = 0 Then
tVec(1) = iVec(1): tVec(2) = iVec(2)
Else
tVec(1) = iVec(1) / iConst: tVec(2) = iVec(2) / iConst
End If
End Select
Vec_OprConst = tVec
End Function
'----------------------
'벡터와 벡터에 대한 사칙연산
Function Vec_Opr(iVec1() As Single, iVec2() As Single, Optional iOperation As String = "+") As Single()
Dim tVec() As Single
ReDim tVec(1 To 2)
Select Case iOperation
Case "+"
tVec(1) = iVec1(1) + iVec2(1): tVec(2) = iVec1(2) + iVec2(2)
Case "-"
tVec(1) = iVec1(1) - iVec2(1): tVec(2) = iVec1(2) - iVec2(2)
Case "*"
tVec(1) = iVec1(1) * iVec2(1): tVec(2) = iVec1(2) * iVec2(2)
Case "/"
tVec(1) = iVec1(1) / iVec2(1): tVec(2) = iVec1(2) / iVec2(2)
End Select
Vec_Opr = tVec
End Function
'----------------------
위의 함수들은 단순히 배열에 대한 연산이니 쉽게 이해될 수 있습니다. 앞으로 모든 좌표들은 2차원 벡터 연산이 주로 되는데, 그러다보면 어떤 벡터에 수직인 성분과 수평인 성분으로 분해하는 경우가 자주 있습니다. 따라서, 아래와 같이, 임의의 벡터를 다른 벡터에 나란한 성분과 수직인 성분으로 분해하는 함수를 만들어둘 수 있습니다.
'----------------------
'임의의 벡터를 다른 벡터에 대해 평행한 성분과 수직인 성분으로 분해
Function Vec_Decomp(iVec() As Single, iVecTool() As Single, oTan() As Single, oNorm() As Single)
Dim tL As Single
ReDim oTan(1 To 2): ReDim oNorm(1 To 2)
tL = Sqr(Vec_Inner(iVecTool, iVecTool))
If tL = 0 Then
oTan(1) = 0: oTan(2) = 0
oNorm = iVec
Else
oTan = Vec_OprConst(iVecTool, Vec_Inner(iVec, iVecTool) / tL ^ 2, "*")
oNorm = Vec_Opr(iVec, oTan, "-")
End If
End Function
'----------------------