[vtkusers] Re: vtkmath in tcl
Mark B Stucky
mstucky5 at cox.net
Thu Jul 21 17:43:51 EDT 2005
This may be getting slightly off topic, but with regard to your
"DotProd" and "CrossProd" routines, you can speed them up
quite a bit by simply replacing the lines
scan $a "%f %f %f" ax ay az
scan $b "%f %f %f" bx by bz
with
foreach {ax ay az} $a {break}
foreach {bx by bz} $b {break}
I ran some timings and got the following :
Times :
CrossProd : 17 microseconds per iteration
myCrossProd : 7 microseconds per iteration
vecCross : 6 microseconds per iteration
DotProd : 15 microseconds per iteration
myDotProd : 4 microseconds per iteration
vecDot : 5 microseconds per iteration
"myCrossProd" and "myDotProd" are versions of your code
with the "foreach" fix.
"vecCross" and "vecDot" are a couple of routines that I found
on the net.
See the code below, or let me know if you have questions.
--Mark
(The code follows this message)
----- Original Message -----
From: "Goodwin Lawlor" <goodwin.lawlor at ucd.ie>
To: <vtkusers at public.kitware.com>
Sent: Thursday, July 21, 2005 8:55 AM
Subject: [vtkusers] Re: vtkmath in tcl
> Hi Alberto,
>
> The only vectors operations in vtkMath that work in tcl are vtkMath::Norm
> and vtkMath::Norm2D
>
> It would be easy enough to extend vtkMath to wrap Cross and Dot into
> tcl... you might like to add it as an idea to the bug tracker -
> http://www.vtk.org/Bug
>
> Here are some tcl procs I use to do Dot and Cross
>
> proc DotProd {a b} {
>
> if {[llength $a] < 3 || [llength $b] < 3} {
> return -code error "Vectors must have 3 components!"
> }
>
> scan $a "%f %f %f" ax ay az
> scan $b "%f %f %f" bx by bz
>
> return [expr {$ax*$bx + $ay*$by + $az*$bz}]
>
> }
>
> proc CrossProd {a b} {
>
> if {[llength $a] < 3 || [llength $b] < 3} {
> return -code error "Vectors must have 3 components!"
> }
>
> scan $a "%f %f %f" ax ay az
> scan $b "%f %f %f" bx by bz
>
> set cx [expr {$ay*$bz - $az*$by}]
> set cy [expr {$az*$bx - $ax*$bz}]
> set cz [expr {$ax*$by - $ay*$bx}]
>
> return [list $cx $cy $cz]
> }
>
> use them like this: CrossProd {1 2 3} {4 5 6}
>
>
> hth
>
> Goodwin
proc DotProd {a b} {
if {[llength $a] < 3 || [llength $b] < 3} {
return -code error "Vectors must have 3 components!"
}
scan $a "%f %f %f" ax ay az
scan $b "%f %f %f" bx by bz
return [expr {$ax*$bx + $ay*$by + $az*$bz}]
}
proc CrossProd {a b} {
if {[llength $a] < 3 || [llength $b] < 3} {
return -code error "Vectors must have 3 components!"
}
scan $a "%f %f %f" ax ay az
scan $b "%f %f %f" bx by bz
set cx [expr {$ay*$bz - $az*$by}]
set cy [expr {$az*$bx - $ax*$bz}]
set cz [expr {$ax*$by - $ay*$bx}]
return [list $cx $cy $cz]
}
proc myDotProd {a b} {
if {[llength $a] < 3 || [llength $b] < 3} {
return -code error "Vectors must have 3 components!"
}
foreach {ax ay az} $a {break}
foreach {bx by bz} $b {break}
return [expr {$ax*$bx + $ay*$by + $az*$bz}]
}
proc myCrossProd {a b} {
if {[llength $a] < 3 || [llength $b] < 3} {
return -code error "Vectors must have 3 components!"
}
foreach {ax ay az} $a {break}
foreach {bx by bz} $b {break}
set cx [expr {$ay*$bz - $az*$by}]
set cy [expr {$az*$bx - $ax*$bz}]
set cz [expr {$ax*$by - $ay*$bx}]
return [list $cx $cy $cz]
}
# vector.tcl - vector math routines
# Jonas Beskow 1999-2000
# http://www.speech.kth.se/~beskow/tcl/vec.tcl.txt
namespace eval vec {
variable PI
set PI [expr {4*atan(1.0)}]
}
# dot - calculate scalar dot product of two vectors
proc vec::dot {v1 v2} {
if {[llength $v1]!=[llength $v2]} {
error "Vectors must be of equal length"
}
set d 0.0
foreach c1 $v1 c2 $v2 {set d [expr {$d+$c1*$c2}]}
set d
}
# cross - cross product between two 3d-vectors
proc vec::cross {v1 v2} {
if {[llength $v1]!=3 || [llength $v2]!=3} {
error "Vectors must be of length 3"
}
set v1x [lindex $v1 0]
set v1y [lindex $v1 1]
set v1z [lindex $v1 2]
set v2x [lindex $v2 0]
set v2y [lindex $v2 1]
set v2z [lindex $v2 2]
list \
[expr {$v1y*$v2z-$v1z*$v2y}] \
[expr {$v1z*$v2x-$v1x*$v2z}] \
[expr {$v1x*$v2y-$v1y*$v2x}]
}
proc run_CrossProd { } {
CrossProd {1.9 2.5 3.1} {4.1 5.7 6.3}
}
proc run_DotProd { } {
DotProd {1.9 2.5 3.1} {4.1 5.7 6.3}
}
proc run_myCrossProd { } {
myCrossProd {1.9 2.5 3.1} {4.1 5.7 6.3}
}
proc run_myDotProd { } {
myDotProd {1.9 2.5 3.1} {4.1 5.7 6.3}
}
proc run_vecCross { } {
vec::cross {1.9 2.5 3.1} {4.1 5.7 6.3}
}
proc run_vecDot { } {
vec::dot {1.9 2.5 3.1} {4.1 5.7 6.3}
}
puts " "
puts "Results : "
puts " "
puts "CrossProd : [CrossProd {1.9 2.5 3.1} {4.1 5.7 6.3}]"
puts "myCrossProd : [myCrossProd {1.9 2.5 3.1} {4.1 5.7 6.3}]"
puts "vec::cross : [vec::cross {1.9 2.5 3.1} {4.1 5.7 6.3}]"
puts " "
puts "DotProd : [DotProd {1.9 2.5 3.1} {4.1 5.7 6.3}]"
puts "myDotProd : [myDotProd {1.9 2.5 3.1} {4.1 5.7 6.3}]"
puts "vec::dot : [vec::dot {1.9 2.5 3.1} {4.1 5.7 6.3}]"
puts " "
puts "Times : "
puts " "
puts "CrossProd : [time run_CrossProd 100000]"
puts "myCrossProd : [time run_myCrossProd 100000]"
puts "vecCross : [time run_vecCross 100000]"
puts " "
puts "DotProd : [time run_DotProd 100000]"
puts "myDotProd : [time run_myDotProd 100000]"
puts "vecDot : [time run_vecDot 100000]"
More information about the vtkusers
mailing list