Berend I was thrown by the (0) in CopyMemory P1(0), P2(0), 24
after crashing a couple of times i got it.
Messing with stuff a little more
I found that a sub runs faster than a function
(try changing the subs below to functions and compare times)
Looking at VecCrossC without() I can't see a reason to add () in the sub call.
vba goes faster when you dim everything.
predimming every double like in VecCrossB is way too much work
whereas VecCrossC is definately worth it in a common function
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, Source As Any, ByVal numBytes As Long)
Private retvecTop(2) As Double
Type Point3d
X As Double
Y As Double
Z As Double
End Type
Function Pto3(P() As Double) As Point3d
Dim P3 As Point3d
P3.X = P(0): P3.Y = P(1): P3.Z = P(2)
Pto3 = P3
End Function
Sub VecCross1(retvec() As Double, v1() As Double, v2() As Double)
retvec(0) = v1(1) * v2(2) - v2(1) * v1(2)
retvec(1) = v1(2) * v2(0) - v2(2) * v1(0)
retvec(2) = v1(0) * v2(1) - v2(0) * v1(1)
End Sub
Function VecCross2(v1() As Double, _
v2() As Double) _
As Double()
Dim result(2) As Double
result(0) = v1(1) * v2(2) - v2(1) * v1(2)
result(1) = v1(2) * v2(0) - v2(2) * v1(0)
result(2) = v1(0) * v2(1) - v2(0) * v1(1)
VecCross2 = result
End Function
Private Sub VecCrossA(retvec() As Double, _
X1 As Double, Y1 As Double, Z1 As Double, _
X2 As Double, Y2 As Double, Z2 As Double)
retvec(0) = Y1 * Z2 - Y2 * Z1
retvec(1) = Z1 * X2 - Z2 * X1
retvec(2) = X1 * Y2 - X2 * Y1
End Sub
Private Sub VecCrossB _
(X1 As Double, Y1 As Double, Z1 As Double, _
X2 As Double, Y2 As Double, Z2 As Double)
retvecTop(0) = Y1 * Z2 - Y2 * Z1
retvecTop(1) = Z1 * X2 - Z2 * X1
retvecTop(2) = X1 * Y2 - X2 * Y1
End Sub
Private Sub VecCrossC(retvec() As Double, v1() As Double, v2() As Double)
Dim X1 As Double, Y1 As Double, Z1 As Double
Dim X2 As Double, Y2 As Double, Z2 As Double
retvec(0) = Y1 * Z2 - Y2 * Z1
retvec(1) = Z1 * X2 - Z2 * X1
retvec(2) = X1 * Y2 - X2 * Y1
End Sub
Private Sub VecCrossD(RV As Point3d, P1 As Point3d, P2 As Point3d)
RV.X = P1.Y * P2.Z - P2.Y * P1.Z
RV.Y = P1.Z * P2.X - P2.Z * P1.X
RV.Z = P1.X * P2.Y - P2.X * P1.Y
End Sub
Private Sub VecCrossE(P, v1() As Double, v2() As Double)
Dim X1 As Double, Y1 As Double, Z1 As Double
Dim X2 As Double, Y2 As Double, Z2 As Double
Dim Ans(2) As Double
Ans(0) = Y1 * Z2 - Y2 * Z1
Ans(1) = Z1 * X2 - Z2 * X1
Ans(2) = X1 * Y2 - X2 * Y1
CopyMemory P(0), Ans(0), 24
End Sub
Private Function VecCrossf(v1() As Double, v2() As Double) As Double()
Dim X1 As Double, Y1 As Double, Z1 As Double
Dim X2 As Double, Y2 As Double, Z2 As Double
Dim Ans(2) As Double
Ans(0) = Y1 * Z2 - Y2 * Z1
Ans(1) = Z1 * X2 - Z2 * X1
Ans(2) = X1 * Y2 - X2 * Y1
VecCrossf = Ans
End Function
Sub Test()
Dim T As Single
Dim v1(2) As Double, v2(2) As Double
Dim d() As Double
Dim i As Long
v1(0) = 223: v1(1) = 123: v1(2) = 323
v2(0) = 343: v2(1) = 4: v2(2) = 0
Dim retvec(2) As Double
Dim c As Double
T = Timer
For i = 0 To 1000000
VecCross1 retvec(), v1(), v2()
c = retvec(0) + retvec(1)
Next
Debug.Print "1=" & Timer - T
T = Timer
For i = 0 To 1000000
VecCrossA retvec(), v1(0), v1(1), v1(2), v2(0), v2(1), v2(2)
c = retvec(0) + retvec(1)
Next
Debug.Print "A=" & Timer - T
T = Timer
For i = 0 To 1000000
VecCrossB v1(0), v1(1), v1(2), v2(0), v2(1), v2(2)
c = retvecTop(0) + retvecTop(1)
Next
Debug.Print "B=" & Timer - T
T = Timer
For i = 0 To 1000000
VecCrossC retvec(), v1(), v2()
c = retvec(0) + retvec(1)
Next
Debug.Print "C=" & Timer - T
T = Timer
For i = 0 To 1000000
VecCrossC retvec, v1, v2
c = retvec(0) + retvec(1)
Next
Debug.Print "C=" & Timer - T & " without()"
T = Timer
Dim P1 As Point3d, P2 As Point3d
Dim RV As Point3d
P1 = Pto3(v1): P2 = Pto3(v2)
For i = 0 To 1000000
VecCrossD RV, P1, P2
c = retvec(0) + retvec(1)
Next
Debug.Print "D=" & Timer - T
End Sub
1=1.730469
A=1.410156
B=1.433594
C=1.230469
C=1.214844 without()
D=1.199219