blob: a9161a4a6b14ad5adbfb288ced7b1d7c2992bd76 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
# math.tcl --
#
# This file provides global math datatypes and utilities.
#
namespace eval ::vec2 {
proc add {a b} {
list [+ [lindex $a 0] [lindex $b 0]] [+ [lindex $a 1] [lindex $b 1]]
}
proc sub {a b} {
list [- [lindex $a 0] [lindex $b 0]] [- [lindex $a 1] [lindex $b 1]]
}
proc mult {a b} {
list [* [lindex $a 0] [lindex $b 0]] [* [lindex $a 1] [lindex $b 1]]
}
proc div {a b} {
list [/ [lindex $a 0] [lindex $b 0]] [/ [lindex $a 1] [lindex $b 1]]
}
proc scale {a args} {
if {[llength $args] == 1} {
set sx [lindex $args 0]; set sy [lindex $args 0]
} else {
lassign $args sx sy
}
list [* [lindex $a 0] $sx] [* [lindex $a 1] $sy]
}
proc rotate {a theta} {
lassign $a x y
list [expr {$x*cos($theta) + $y*sin($theta)}] \
[expr {-$x*sin($theta) + $y*cos($theta)}]
}
proc distance {a b} {
lassign $a ax ay
lassign $b bx by
expr {sqrt(pow($ax-$bx, 2) + pow($ay-$by, 2))}
}
proc normalize {a} {
set l2 [vec2 distance $a [list 0 0]]
vec2 scale $a [/ 1 $l2]
}
proc dot {a b} {
expr {[lindex $a 0]*[lindex $b 0] + [lindex $a 1]*[lindex $b 1]}
}
proc distanceToLineSegment {a v w} {
set l2 [vec2 distance $v $w]
if {$l2 == 0.0} {
return [distance $a $v]
}
set t [max 0 [min 1 [/ [dot [sub $a $v] [sub $w $v]] $l2]]]
set proj [add $v [scale [sub $w $v] $t]]
vec2 distance $a $proj
}
proc midpoint {a b} {
lassign $a x1 y1; lassign $b x2 y2
list [/ [+ $x1 $x2] 2] [/ [+ $y1 $y2] 2]
}
namespace export *
namespace ensemble create
}
# From tcllib ::math::geometry
# Original code found at: https://www.ecse.rpi.edu/~wrf/Research/Short_Notes/pnpoly.html
# Thanks to Christian Gollwitzer, Peter Lewerin and Eduard Zozuly
proc ::math::geometry::pointInsidePolygon {point polygon} {
lassign $point testx testy
foreach p $polygon {
lassign $p x y
lappend vertx $x
lappend verty $y
}
set c 0
set nvert [llength $vertx]
for {set i 0 ; set j [expr {$nvert-1}]} {$i < $nvert} {set j $i ; incr i} {
if {
(([lindex $verty $i]>$testy) != ([lindex $verty $j]>$testy)) &&
($testx < ([lindex $vertx $j] - [lindex $vertx $i]) *
($testy - [lindex $verty $i]) /
([lindex $verty $j] - [lindex $verty $i]) + [lindex $vertx $i])
} {
set c [expr {!$c}]
}
}
return $c
}
namespace eval ::math {
proc min {args} {
if {[llength $args] == 0} { error "min: No args" }
set min infinity
foreach arg $args { if {$arg < $min} { set min $arg } }
return $min
}
proc max {args} {
if {[llength $args] == 0} { error "max: No args" }
set max -infinity
foreach arg $args { if {$arg > $max} { set max $arg } }
return $max
}
proc mean {val args} {
set sum $val
set N [ expr { [ llength $args ] + 1 } ]
foreach val $args {
set sum [ expr { $sum + $val } ]
}
set mean [expr { double($sum) / $N }]
}
proc sin {x} { expr {sin($x)} }
proc cos {x} { expr {cos($x)} }
}
namespace import ::math::*
|