home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CyberMycha 2006 April
/
SGP.iso
/
dema
/
Keepsake-Demo-en-li-v1.0.exe
/
res
/
bin
/
prime
/
vector3.tcl
< prev
next >
Wrap
Text File
|
2005-10-29
|
3KB
|
127 lines
namespace eval vector {}
proc vector::norm2 {V1} {
set n 0
foreach v1 $V1 {set n [expr {$n + ($v1 * $v1)}]}
return [expr {sqrt($n)}]
}
proc vector::normalize {V1} {
set n [norm2 $V1]
if {$n == 0} {return $V1}
set W ""
foreach v1 $V1 {lappend W [expr {$v1 / $n}]}
return $W
}
proc vector::add {V1 V2} {
set W ""
foreach v1 $V1 v2 $V2 {lappend W [expr {$v1 + $v2}]}
return $W
}
proc vector::sub {V1 V2} {
set W ""
foreach v1 $V1 v2 $V2 {lappend W [expr {$v1 - $v2}]}
return $W
}
proc vector::mul {V1 a} {
set W ""
foreach v1 $V1 {lappend W [expr {$v1 * $a}]}
return $W
}
proc vector::div {V1 a} {
set W ""
foreach v1 $V1 {lappend W [expr {$v1 / $a}]}
return $W
}
proc vector::simple_expr {l op r} {
case $op {
{+} {
if {[llength $l] != [llength $r]} {
error "$ls and $rs must be of equal length."
}
vector::add $l $r
}
{-} {
if {[llength $l] != [llength $r]} {
error "$l and $r must be of equal length."
}
vector::sub $l $r
}
{\\*} {
if {[llength $l] == 1} {
vector::mul $r $l
} elseif {[llength $r] == 1} {
vector::mul $l $r
} else {
error "$l or $r must be a scalar."
}
}
{/} {
if {[llength $l] == 1} {
vector::div $r [expr double($l)]
} elseif {[llength $r] == 1} {
vector::div $l [expr double($r)]
} else {
error "$l or $r must be a scalar."
}
}
}
}
proc vector::vexpr {args} {
if {[llength $args] == 1} {
set a [lindex $args 0]
} else {
set a $args
}
regsub -all {\$[^ ^)]*} $a {{&}} a
set a [uplevel 1 subst \{$a\}]
set ::i 0
while {[regexp {([^\{]*)\{([^\}]*)\}(.*)} $a -> h v f]} {
incr ::i
set a "$h%$::i$f"
set ::vector($::i) $v
}
do $a
}
proc vector::do {a} {
if {[regexp {^%([0-9]+)$} [string trim $a] -> i]} {
return $::vector($i)
}
if {[regexp {(.*)\((.*)\)(.*)} $a -> h exp f]} {
regexp {([^\)]*)(.*)} $exp -> exp br
set f $br$f
if {[regexp {(.*)(norm2|normalize)$} $h -> h func]} {
set exp [$func [do $exp]]
} else {
set exp [do $exp]
}
incr ::i
set ::vector($::i) $exp
return [do $h%$::i$f]
} elseif {[regexp {(.*)([\+\-])(.*)} $a -> l op r]} {
return [simple_expr [do $l] $op [do $r]]
} elseif {[regexp {(.*)([\*\/])(.*)} $a -> l op r]} {
return [simple_expr [do $l] $op [do $r]]
}
error "Couldn't parse expression: $a"
}