line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/bin/perl -I/home/phil/perl/cpan/DataTableText/lib/ |
2
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
3
|
|
|
|
|
|
|
# Vectors in two dimensions |
4
|
|
|
|
|
|
|
# Philip R Brenan at gmail dot com, Appa Apps Ltd Inc., 2017-2020 |
5
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
6
|
|
|
|
|
|
|
# podDocumentation |
7
|
|
|
|
|
|
|
package Math::Vectors2; |
8
|
|
|
|
|
|
|
require v5.16; |
9
|
|
|
|
|
|
|
our $VERSION = 20231002; |
10
|
1
|
|
|
1
|
|
1553
|
use warnings FATAL => qw(all); |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
42
|
|
11
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
24
|
|
12
|
1
|
|
|
1
|
|
5
|
use Carp qw(confess); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
85
|
|
13
|
1
|
|
|
1
|
|
1088
|
use Data::Dump qw(dump); |
|
1
|
|
|
|
|
7937
|
|
|
1
|
|
|
|
|
64
|
|
14
|
1
|
|
|
1
|
|
6398
|
use Data::Table::Text qw(genHash); |
|
1
|
|
|
|
|
148233
|
|
|
1
|
|
|
|
|
350
|
|
15
|
1
|
|
|
1
|
|
3463
|
use Math::Trig; |
|
1
|
|
|
|
|
15368
|
|
|
1
|
|
|
|
|
2855
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
my $nearness = 1e-6; # Definition of near |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub near($$) # Check two scalars are near each other. |
20
|
393
|
|
|
393
|
0
|
3496
|
{my ($o, $p) = @_; |
21
|
393
|
|
|
|
|
1283
|
abs($p-$o) < $nearness |
22
|
|
|
|
|
|
|
} |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub near2($$) # Check two vectors are near each other. |
25
|
45
|
|
|
45
|
0
|
1145
|
{my ($o, $p) = @_; |
26
|
45
|
|
|
|
|
111
|
$o->d($p) < $nearness |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
#D1 Methods # Vector methods. |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub new($$) #S Create new vector from components. |
32
|
643
|
|
|
643
|
1
|
10704
|
{my ($x, $y) = @_; # X component, Y component |
33
|
643
|
|
|
|
|
1658
|
genHash(__PACKAGE__, # Attributes of a vector |
34
|
|
|
|
|
|
|
x => $x, # X coordinate |
35
|
|
|
|
|
|
|
y => $y, # Y coordinate |
36
|
|
|
|
|
|
|
); |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub zeroAndUnits() #S Create the useful vectors: zero=(0,0), x=(1,0), y=(0,1). |
40
|
12
|
|
|
12
|
1
|
40
|
{map {&new(@$_)} ([0, 0], [1, 0], [0, 1]) |
|
36
|
|
|
|
|
967
|
|
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub eq($$) # Whether two vectors are equal to within the accuracy of floating point arithmetic. |
44
|
13
|
|
|
13
|
1
|
20
|
{my ($o, $p) = @_; # First vector, second vector |
45
|
13
|
|
|
|
|
28
|
near2($o, $p) |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub zero($) # Whether a vector is equal to zero within the accuracy of floating point arithmetic. |
49
|
3
|
|
|
3
|
1
|
8
|
{my ($o) = @_; # Vector |
50
|
3
|
100
|
|
|
|
85
|
near($o->x, 0) && near($o->y, 0) |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub print($@) # Print one or more vectors. |
54
|
13
|
|
|
13
|
1
|
23
|
{my ($p, @p) = @_; # Vector to print, more vectors to print |
55
|
13
|
|
|
|
|
25
|
join ', ', map {'('.$_->x.','.$_->y.')'} @_ |
|
13
|
|
|
|
|
212
|
|
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub clone($) # Clone a vector. |
59
|
139
|
|
|
139
|
1
|
260
|
{my ($o) = @_; # Vector to clone |
60
|
139
|
|
|
|
|
2466
|
new($o->x, $o->y) |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub Plus($@) # Add zero or more other vectors to the first vector and return the result. |
64
|
37
|
|
|
37
|
1
|
1240
|
{my ($o, @p) = @_; # First vector, other vectors |
65
|
37
|
|
|
|
|
68
|
for(@p) |
66
|
37
|
|
|
|
|
642
|
{$o->x += $_->x; |
67
|
37
|
|
|
|
|
720
|
$o->y += $_->y; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
$o |
70
|
37
|
|
|
|
|
354
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub plus($@) # Add zero or more other vectors to a copy of the first vector and return the result. |
73
|
35
|
|
|
35
|
1
|
61
|
{my ($o, @p) = @_; # First vector, other vectors |
74
|
35
|
|
|
|
|
72
|
$o->clone->Plus(@p) |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub Minus($@) # Subtract zero or more vectors from the first vector and return the result. |
78
|
61
|
|
|
61
|
1
|
1929
|
{my ($o, @p) = @_; # First vector, other vectors |
79
|
61
|
|
|
|
|
97
|
for(@p) |
80
|
61
|
|
|
|
|
1060
|
{$o->x -= $_->x; |
81
|
61
|
|
|
|
|
1175
|
$o->y -= $_->y; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
$o |
84
|
61
|
|
|
|
|
875
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub minus($@) # Subtract zero or more vectors from a copy of the first vector and return the result. |
87
|
59
|
|
|
59
|
1
|
102
|
{my ($o, @p) = @_; # First vector, other vectors |
88
|
59
|
|
|
|
|
108
|
$o->clone->Minus(@p) |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub Multiply($$) # Multiply a vector by a scalar and return the result. |
92
|
41
|
|
|
41
|
1
|
1263
|
{my ($o, $m) = @_; # Vector, scalar to multiply by |
93
|
41
|
|
|
|
|
741
|
$o->x *= $m; $o->y *= $m; |
|
41
|
|
|
|
|
835
|
|
94
|
41
|
|
|
|
|
218
|
$o |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub multiply($$) # Multiply a copy of a vector by a scalar and return the result. |
98
|
39
|
|
|
39
|
1
|
65
|
{my ($o, $m) = @_; # Vector, scalar to multiply by |
99
|
39
|
|
|
|
|
73
|
$o->clone->Multiply($m) |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
sub Divide($$) # Divide a vector by a scalar and return the result. |
103
|
7
|
|
|
7
|
1
|
173
|
{my ($o, $d) = @_; # Vector, scalar to multiply by |
104
|
7
|
|
|
|
|
130
|
$o->x /= $d; $o->y /= $d; |
|
7
|
|
|
|
|
137
|
|
105
|
7
|
|
|
|
|
36
|
$o |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub divide($$) # Divide a copy of a vector by a scalar and return the result. |
109
|
5
|
|
|
5
|
1
|
8
|
{my ($o, $d) = @_; # Vector, scalar to divide by |
110
|
5
|
|
|
|
|
12
|
$o->clone->Divide($d) |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub l($) # Length of a vector. |
114
|
1563
|
|
|
1563
|
1
|
40625
|
{my ($o) = @_; # Vector |
115
|
1563
|
|
|
|
|
23761
|
sqrt($o->x**2 + $o->y**2) |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
sub l2($) # Length squared of a vector. |
119
|
2
|
|
|
2
|
1
|
9
|
{my ($o) = @_; # Vector |
120
|
2
|
|
|
|
|
34
|
$o->x**2 + $o->y**2 |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub d($$) # Distance between the points identified by two vectors when placed on the same point. |
124
|
46
|
|
|
46
|
1
|
78
|
{my ($o, $p) = @_; # Vector 1, vector 2 |
125
|
46
|
|
|
|
|
896
|
sqrt(($o->x-$p->x)**2 + ($o->y-$p->y)**2) |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub d2($$) # Distance squared between the points identified by two vectors when placed on the same point. |
129
|
1
|
|
|
1
|
1
|
13
|
{my ($o, $p) = @_; # Vector 1, vector 2 |
130
|
1
|
|
|
|
|
23
|
($o->x-$p->x)**2 + ($o->y-$p->y)**2 |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub n($) # Return a normalized a copy of a vector. |
134
|
1
|
|
|
1
|
1
|
3
|
{my ($o) = @_; # Vector |
135
|
1
|
|
|
|
|
2
|
my $l = $o->l; |
136
|
1
|
50
|
|
|
|
30
|
$l == 0 and confess; |
137
|
1
|
|
|
|
|
19
|
new($o->x / $l, $o->y / $l) |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
sub dot($$) # Dot product of two vectors. |
141
|
393
|
|
|
393
|
1
|
594
|
{my ($o, $p) = @_; # Vector 1, vector 2 |
142
|
393
|
|
|
|
|
8577
|
$o->x * $p->x + $o->y * $p->y |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub area($$) # Signed area of the parallelogram defined by the two vectors. The area is negative if the second vector appears to the right of the first if they are both placed at the origin and the observer stands against the z-axis in a left handed coordinate system. |
146
|
399
|
|
|
399
|
1
|
608
|
{my ($o, $p) = @_; # Vector 1, vector 2 |
147
|
399
|
|
|
|
|
6347
|
$o->x * $p->y - $o->y * $p->x |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub cosine($$) # Cos(angle between two vectors). |
151
|
389
|
|
|
389
|
1
|
700
|
{my ($o, $p) = @_; # Vector 1, vector 2 |
152
|
389
|
|
|
|
|
741
|
$o->dot($p) / $o->l / $p->l |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub sine($$) # Sin(angle between two vectors). |
156
|
391
|
|
|
391
|
1
|
702
|
{my ($o, $p) = @_; # Vector 1, vector 2 |
157
|
391
|
|
|
|
|
808
|
$o->area($p) / $o->l / $p->l |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub angle($$) # Angle in radians anticlockwise that the first vector must be rotated to point along the second vector normalized to the range: -pi to +pi. |
161
|
384
|
|
|
384
|
1
|
846
|
{my ($o, $p) = @_; # Vector 1, vector 2 |
162
|
384
|
|
|
|
|
758
|
my $c = $o->cosine($p); |
163
|
384
|
|
|
|
|
8879
|
my $s = $o->sine($p); |
164
|
384
|
|
|
|
|
8236
|
my $a = Math::Trig::acos($c); |
165
|
384
|
100
|
|
|
|
3695
|
$s > 0 ? $a : -$a |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub smallestAngleToNormalPlane($$) # The smallest angle between the second vector and a plane normal to the first vector. |
169
|
9
|
|
|
9
|
1
|
47
|
{my ($a, $b) = @_; # Vector 1, vector 2 |
170
|
9
|
|
|
|
|
21
|
my $r = abs $a->angle($b); |
171
|
9
|
|
|
|
|
23
|
my $p = Math::Trig::pi / 2; |
172
|
9
|
100
|
|
|
|
49
|
$r < $p ? $p - $r : $r - $p |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
sub r90($) # Rotate a vector by 90 degrees anticlockwise. |
176
|
12
|
|
|
12
|
1
|
211
|
{my ($o) = @_; # Vector to rotate |
177
|
12
|
|
|
|
|
238
|
new(-$o->y, $o->x) |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
sub r180($) # Rotate a vector by 180 degrees. |
181
|
0
|
|
|
0
|
1
|
0
|
{my ($o) = @_; # Vector to rotate |
182
|
0
|
|
|
|
|
0
|
new(-$o->x, -$o->y) |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub r270($) # Rotate a vector by 270 degrees anticlockwise. |
186
|
0
|
|
|
0
|
1
|
0
|
{my ($o) = @_; # Vector to rotate |
187
|
0
|
|
|
|
|
0
|
new($o->y, -$o->x) |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub rotate($$$$) # Rotate a vector about another vector through an angle specified by its values as sin, and cos. |
191
|
6
|
|
|
6
|
1
|
171
|
{my ($p, $o, $sin, $cos) = @_; # Vector to rotate, center of rotation, sin of the angle of rotation, cosine of the angle of rotation |
192
|
6
|
|
|
|
|
16
|
my $q = $p - $o; |
193
|
6
|
|
|
|
|
99
|
$o + new($cos*$q->x-$sin*$q->y, $sin*$q->x+$cos*$q->y) |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
my sub min(@) #P Find the minimum number in a list of numbers |
197
|
16
|
|
|
16
|
|
107
|
{my (@m) = @_; # Numbers |
198
|
16
|
|
|
|
|
23
|
my $M = shift @m; |
199
|
16
|
|
|
|
|
28
|
for(@m) |
200
|
16
|
100
|
|
|
|
38
|
{$M = $_ if $_ < $M; |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
$M |
203
|
16
|
|
|
|
|
31
|
} |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
my sub max(@) #P Find the maximum number in a list of numbers |
206
|
16
|
|
|
16
|
|
93
|
{my (@m) = @_; # Numbers |
207
|
16
|
|
|
|
|
24
|
my $M = shift @m; |
208
|
16
|
|
|
|
|
27
|
for(@m) |
209
|
16
|
100
|
|
|
|
70
|
{$M = $_ if $_ > $M; |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
$M |
212
|
16
|
|
|
|
|
34
|
} |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
sub intersection($$$$) # Find the intersection of two line segments delimited by vectors if such a point exists. |
215
|
4
|
|
|
4
|
1
|
65
|
{my ($a, $b, $c, $d) = @_; # Start of first line segment, end of first line segment, start of second line segment, end of second line segment |
216
|
|
|
|
|
|
|
|
217
|
4
|
|
|
|
|
93
|
my $abx = min($a->x, $b->x); my $abX = max($a->x, $b->x); |
|
4
|
|
|
|
|
74
|
|
218
|
4
|
|
|
|
|
66
|
my $aby = min($a->y, $b->y); my $abY = max($a->y, $b->y); |
|
4
|
|
|
|
|
62
|
|
219
|
4
|
|
|
|
|
63
|
my $cdx = min($c->x, $d->x); my $cdX = max($c->x, $d->x); |
|
4
|
|
|
|
|
64
|
|
220
|
4
|
|
|
|
|
70
|
my $cdy = min($c->y, $d->y); my $cdY = max($c->y, $d->y); |
|
4
|
|
|
|
|
64
|
|
221
|
|
|
|
|
|
|
|
222
|
4
|
50
|
|
|
|
9
|
return undef if $abX < $cdx; # Quick reject |
223
|
4
|
50
|
|
|
|
9
|
return undef if $abY < $cdy; |
224
|
4
|
50
|
|
|
|
10
|
return undef if $abx > $cdX; |
225
|
4
|
50
|
|
|
|
8
|
return undef if $aby > $cdY; |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# $a + $l * ($b - $a) == $c + $m * ($d - $c) |
228
|
|
|
|
|
|
|
# $a - $c == $m * ($d - $c) - $l * ($b - $a) |
229
|
|
|
|
|
|
|
# $ac == $m * ($dc) - $l * ($ba) |
230
|
|
|
|
|
|
|
# |
231
|
|
|
|
|
|
|
# $acx = $m * $dcx - $l * $bax |
232
|
|
|
|
|
|
|
# $acy = $m * $dcy - $l * $bay |
233
|
|
|
|
|
|
|
# |
234
|
|
|
|
|
|
|
# $acx * $dcy = $m * $dcx * $dcy - $l * $bax * $dcy |
235
|
|
|
|
|
|
|
# $acy * $dcx = $m * $dcx * $dcy - $l * $dcx * $bay |
236
|
|
|
|
|
|
|
# |
237
|
|
|
|
|
|
|
# $acx * $dcy - $acy * $dcx = $l($dcx * $bay - $bax * $dcy) |
238
|
|
|
|
|
|
|
# |
239
|
|
|
|
|
|
|
# $l = ($acx * $dcy - $acy * $dcx) / ($dcx * $bay - $bax * $dcy) |
240
|
|
|
|
|
|
|
|
241
|
4
|
|
|
|
|
25
|
my $l = (($a-$c)->x * ($d-$c)->y - ($a-$c)->y * ($d-$c)->x) / (($d-$c)->x * ($b-$a)->y - ($b-$a)->x * ($d-$c)->y); |
242
|
4
|
|
|
|
|
38
|
$a + $l * ($b - $a) |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
sub triangulate($@) # Find a set of triangles that cover a shape whose boundary points are represented by an array of vectors. The points along the boundary must be given in such away that the interior of the shape is always on the same side for each pair of successive points as indicated by the clockwise parameter. |
246
|
2
|
|
|
2
|
1
|
60
|
{my ($clockwise, @boundary) = @_; # If true then the interior of the shape is on the left as the boundary of the shape is traversed otherwise on the right, vectors representing the boundary of the shape |
247
|
|
|
|
|
|
|
|
248
|
2
|
50
|
|
|
|
9
|
@boundary >= 3 or confess "Need at least 3 points to outline the shape."; |
249
|
|
|
|
|
|
|
|
250
|
2
|
|
|
|
|
5
|
my @t; my @b = @boundary; # Generated triangles. Current boundary |
|
2
|
|
|
|
|
5
|
|
251
|
|
|
|
|
|
|
|
252
|
2
|
|
|
|
|
16
|
while(@b > 3) # Reduce the boundary by one point by triangulating four consecutive points. |
253
|
2
|
|
|
|
|
7
|
{my @B; # New boundary |
254
|
2
|
|
|
|
|
9
|
for(my $i = 0; $i < @b; ++$i) # Move around border filling in where possible to establish a new inner boundary that is smaller than the outer boundary |
255
|
2
|
|
|
|
|
5
|
{my $A = $b[$i % @b]; |
256
|
2
|
|
|
|
|
8
|
my ($B, $C, $D) = ($b[($i+1) % @b], $b[($i+2) % @b], $b[($i+3) % @b]); |
257
|
2
|
50
|
|
|
|
6
|
if (defined(my $X = intersection($A, $C, $B, $D))) # Located the intersection |
258
|
2
|
|
|
|
|
5
|
{my $a = area($X - $A, $B - $A); # Area of triangle made by first pair and intersection |
259
|
2
|
|
|
|
|
89
|
my $b = area($X - $B, $C - $B); # Area of triangle made by second pair and intersection |
260
|
2
|
|
|
|
|
122
|
my $c = area($X - $C, $D - $C); # Area of triangle made by third pair and intersection |
261
|
2
|
50
|
66
|
|
|
113
|
if ($a < 0 && $b < 0 && $c < 0 && $clockwise or |
|
|
|
66
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
262
|
|
|
|
|
|
|
$a > 0 && $b > 0 && $c > 0 && !$clockwise) # All of the triangles are on the expected side |
263
|
2
|
|
|
|
|
20
|
{push @t, [$X, $A, $B], [$X, $B, $C], [$X, $C, $D]; |
264
|
2
|
|
|
|
|
8
|
push @B, $A, $X, $D; |
265
|
2
|
|
|
|
|
11
|
$i += 3; |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
else # One or more of the triangles is outside the shape |
268
|
0
|
|
|
|
|
0
|
{push @B, $A; |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
} |
272
|
2
|
50
|
|
|
|
7
|
if (@B == @b) # Unable to make any reductions |
273
|
0
|
0
|
|
|
|
0
|
{my $c = $clockwise ? 0 : 1; |
274
|
0
|
|
|
|
|
0
|
confess <
|
275
|
|
|
|
|
|
|
No reductions available yet shape not filled. You might want to try again with |
276
|
|
|
|
|
|
|
the clockwise parameter set to $c. |
277
|
|
|
|
|
|
|
END |
278
|
|
|
|
|
|
|
} |
279
|
2
|
|
|
|
|
7
|
@b = @B; # New boundary |
280
|
|
|
|
|
|
|
} |
281
|
2
|
50
|
|
|
|
8
|
push @t, [@b] if @b == 3; # Last triangle |
282
|
|
|
|
|
|
|
@t # Triangulation |
283
|
2
|
|
|
|
|
7
|
} |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
sub swap($) # Swap the components of a vector. |
286
|
1
|
|
|
1
|
1
|
2
|
{my ($o) = @_; # Vector |
287
|
1
|
|
|
|
|
23
|
new($o->y, $o->x) |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
use overload |
291
|
13
|
|
|
13
|
|
149
|
'==' => sub {my ($o, $p) = @_; $o->eq ($p)}, |
|
13
|
|
|
|
|
32
|
|
292
|
34
|
|
|
34
|
|
297
|
'+' => sub {my ($o, $p) = @_; $o->plus ($p)}, |
|
34
|
|
|
|
|
74
|
|
293
|
1
|
|
|
1
|
|
40
|
'+=' => sub {my ($o, $p) = @_; $o->Plus ($p)}, |
|
1
|
|
|
|
|
5
|
|
294
|
72
|
100
|
|
72
|
|
383
|
'-' => sub {my ($o, $p) = @_; ref($p) ? $o->minus($p) : $o->multiply(-1)}, |
|
72
|
|
|
|
|
198
|
|
295
|
1
|
|
|
1
|
|
43
|
'-=' => sub {my ($o, $p) = @_; $o->Minus ($p)}, |
|
1
|
|
|
|
|
5
|
|
296
|
24
|
|
|
24
|
|
105
|
'*' => sub {my ($o, $p) = @_; $o->multiply($p)}, |
|
24
|
|
|
|
|
60
|
|
297
|
1
|
|
|
1
|
|
4
|
'*=' => sub {my ($o, $p) = @_; $o->Multiply($p)}, |
|
1
|
|
|
|
|
15
|
|
298
|
4
|
|
|
4
|
|
8
|
'/' => sub {my ($o, $p) = @_; $o->divide ($p)}, |
|
4
|
|
|
|
|
13
|
|
299
|
1
|
|
|
1
|
|
8
|
'/=' => sub {my ($o, $p) = @_; $o->Divide ($p)}, |
|
1
|
|
|
|
|
4
|
|
300
|
4
|
|
|
4
|
|
9
|
'.' => sub {my ($o, $p) = @_; $o->dot ($p)}, |
|
4
|
|
|
|
|
11
|
|
301
|
0
|
|
|
0
|
|
0
|
'x' => sub {my ($o, $p) = @_; $o->area ($p)}, |
|
0
|
|
|
|
|
0
|
|
302
|
367
|
|
|
367
|
|
13385
|
'<' => sub {my ($o, $p) = @_; $o->angle ($p)}, |
|
367
|
|
|
|
|
774
|
|
303
|
12
|
|
|
12
|
|
26
|
'""' => sub {my ($o) = @_; $o->print }, |
|
12
|
|
|
|
|
29
|
|
304
|
1
|
|
|
1
|
|
9
|
"fallback" => 1; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
40
|
|
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
#D0 |
307
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
308
|
|
|
|
|
|
|
# Export - eeee |
309
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
310
|
|
|
|
|
|
|
|
311
|
1
|
|
|
1
|
|
190
|
use Exporter qw(import); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
44
|
|
312
|
|
|
|
|
|
|
|
313
|
1
|
|
|
1
|
|
7
|
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
385
|
|
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
# containingFolder |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
318
|
|
|
|
|
|
|
@EXPORT = qw(); |
319
|
|
|
|
|
|
|
@EXPORT_OK = qw(); |
320
|
|
|
|
|
|
|
%EXPORT_TAGS = (all=>[@EXPORT, @EXPORT_OK]); |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
# podDocumentation |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=encoding utf-8 |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
=head1 Name |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
Math::Vectors2 - Vectors in two dimensions |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=head1 Synopsis |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
use Math::Vectors2; |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
my ($zero, $x, $y) = Math::Vectors2::zeroAndUnits; |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
ok near deg2rad(-60), $x + $y * sqrt(3) < $x; |
337
|
|
|
|
|
|
|
ok near deg2rad(+30), ($x + $y * sqrt(3))->angle($y); |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
=head1 Description |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
Vectors in two dimensions |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
Version 20231001. |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
The following sections describe the methods in each functional area of this |
348
|
|
|
|
|
|
|
module. For an alphabetic listing of all methods by name see L. |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=head1 Methods |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
Vector methods. |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
=head2 new($x, $y) |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
Create new vector from components. |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
Parameter Description |
361
|
|
|
|
|
|
|
1 $x X component |
362
|
|
|
|
|
|
|
2 $y Y component |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
B |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
ok near $y->angle(new(+1, -1)), deg2rad(-135); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
ok near $y->angle(new(+1, 0)), deg2rad(-90); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
ok near $y->angle(new(+1, +1)), deg2rad(-45); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
ok near $y->angle(new( 0, +1)), deg2rad(+0); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
ok near $y->angle(new(-1, +1)), deg2rad(+45); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
ok near $y->angle(new(-1, 0)), deg2rad(+90); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
ok near $y->angle(new(-1, -1)), deg2rad(+135); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
ok near new(1,1) < new( 0, -1), deg2rad(-135); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
ok near new(1,1) < new( 1, -1), deg2rad(-90); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
ok near new(1,1) < new( 1, 0), deg2rad(-45); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
ok near new(1,1) < new( 1, 1), deg2rad(0); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
ok near new(1,1) < new( 0, 1), deg2rad(+45); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
ok near new(1,1) < new(-1, 1), deg2rad(+90); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
ok near new(1,1) < new(-1, 0), deg2rad(+135); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
ok near deg2rad(-60), $x + $y * sqrt(3) < $x; |
413
|
|
|
|
|
|
|
ok near deg2rad(+30), ($x + $y * sqrt(3))->angle($y); |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
ok near deg2rad( 0), $y->smallestAngleToNormalPlane( $x); # First vector is y, second vector is 0 degrees anti-clockwise from x axis |
416
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane( $x + $y); |
417
|
|
|
|
|
|
|
ok near deg2rad(+90), $y->smallestAngleToNormalPlane( $y); |
418
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane(-$x + -$y); |
419
|
|
|
|
|
|
|
ok near deg2rad( 0), $y->smallestAngleToNormalPlane(-$x); |
420
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane(-$x + -$y); |
421
|
|
|
|
|
|
|
ok near deg2rad(+90), $y->smallestAngleToNormalPlane( -$y); |
422
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane(-$x + -$y); |
423
|
|
|
|
|
|
|
ok near deg2rad( 0), $y->smallestAngleToNormalPlane( $x); |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
for my $i(-179..179) |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
{ok near $x < new(cos(deg2rad($i)), sin(deg2rad($i))), deg2rad($i); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
} |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
This is a static method and so should either be imported or invoked as: |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
Math::Vectors2::new |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
=head2 zeroAndUnits() |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
Create the useful vectors: zero=(0,0), x=(1,0), y=(0,1). |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
B |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
ok $x + $y + $z == $x->plus($y); |
449
|
|
|
|
|
|
|
ok $x - $y == $x->minus($y); |
450
|
|
|
|
|
|
|
ok $x * 3 == $x->multiply(3); |
451
|
|
|
|
|
|
|
ok $y / 2 == $y->divide(2); |
452
|
|
|
|
|
|
|
ok $x + $y eq '(1,1)'; |
453
|
|
|
|
|
|
|
ok $x - $y eq '(1,-1)'; |
454
|
|
|
|
|
|
|
ok $x * 3 eq '(3,0)'; |
455
|
|
|
|
|
|
|
ok $y / 2 eq '(0,0.5)'; |
456
|
|
|
|
|
|
|
ok (($x * 2 + $y * 3)-> print eq '(2,3)'); |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
This is a static method and so should either be imported or invoked as: |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
Math::Vectors2::zeroAndUnits |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=head2 eq($o, $p) |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
Whether two vectors are equal to within the accuracy of floating point arithmetic. |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
Parameter Description |
469
|
|
|
|
|
|
|
1 $o First vector |
470
|
|
|
|
|
|
|
2 $p Second vector |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
B |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
476
|
|
|
|
|
|
|
ok $x + $y + $z == $x->plus($y); |
477
|
|
|
|
|
|
|
ok $x - $y == $x->minus($y); |
478
|
|
|
|
|
|
|
ok $x * 3 == $x->multiply(3); |
479
|
|
|
|
|
|
|
ok $y / 2 == $y->divide(2); |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
ok $x + $y eq '(1,1)'; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
ok $x - $y eq '(1,-1)'; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
ok $x * 3 eq '(3,0)'; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
ok $y / 2 eq '(0,0.5)'; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
ok (($x * 2 + $y * 3)-> print eq '(2,3)'); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
=head2 zero($o) |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
Whether a vector is equal to zero within the accuracy of floating point arithmetic. |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
Parameter Description |
502
|
|
|
|
|
|
|
1 $o Vector |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
B |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
ok $zero->zero; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
ok !$x->zero; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
ok !$y->zero; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
=head2 print($p, @p) |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
Print one or more vectors. |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
Parameter Description |
526
|
|
|
|
|
|
|
1 $p Vector to print |
527
|
|
|
|
|
|
|
2 @p More vectors to print |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
B |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
533
|
|
|
|
|
|
|
ok $x + $y + $z == $x->plus($y); |
534
|
|
|
|
|
|
|
ok $x - $y == $x->minus($y); |
535
|
|
|
|
|
|
|
ok $x * 3 == $x->multiply(3); |
536
|
|
|
|
|
|
|
ok $y / 2 == $y->divide(2); |
537
|
|
|
|
|
|
|
ok $x + $y eq '(1,1)'; |
538
|
|
|
|
|
|
|
ok $x - $y eq '(1,-1)'; |
539
|
|
|
|
|
|
|
ok $x * 3 eq '(3,0)'; |
540
|
|
|
|
|
|
|
ok $y / 2 eq '(0,0.5)'; |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
ok (($x * 2 + $y * 3)-> print eq '(2,3)'); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=head2 clone($o) |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
Clone a vector. |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
Parameter Description |
551
|
|
|
|
|
|
|
1 $o Vector to clone |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
B |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
557
|
|
|
|
|
|
|
ok $x->swap == $y; |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
ok $x->clone == $x; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
=head2 Plus($o, @p) |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
Add zero or more other vectors to the first vector and return the result. |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
Parameter Description |
568
|
|
|
|
|
|
|
1 $o First vector |
569
|
|
|
|
|
|
|
2 @p Other vectors |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
B |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
$x->Plus(new(1,1)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
ok $x eq '(2,1)'; |
579
|
|
|
|
|
|
|
$y += new(1,1); |
580
|
|
|
|
|
|
|
ok $y eq '(1,2)'; |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
=head2 plus($o, @p) |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
Add zero or more other vectors to a copy of the first vector and return the result. |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
Parameter Description |
589
|
|
|
|
|
|
|
1 $o First vector |
590
|
|
|
|
|
|
|
2 @p Other vectors |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
B |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
ok $x + $y + $z == $x->plus($y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
ok $x - $y == $x->minus($y); |
600
|
|
|
|
|
|
|
ok $x * 3 == $x->multiply(3); |
601
|
|
|
|
|
|
|
ok $y / 2 == $y->divide(2); |
602
|
|
|
|
|
|
|
ok $x + $y eq '(1,1)'; |
603
|
|
|
|
|
|
|
ok $x - $y eq '(1,-1)'; |
604
|
|
|
|
|
|
|
ok $x * 3 eq '(3,0)'; |
605
|
|
|
|
|
|
|
ok $y / 2 eq '(0,0.5)'; |
606
|
|
|
|
|
|
|
ok (($x * 2 + $y * 3)-> print eq '(2,3)'); |
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
=head2 Minus($o, @p) |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
Subtract zero or more vectors from the first vector and return the result. |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
Parameter Description |
614
|
|
|
|
|
|
|
1 $o First vector |
615
|
|
|
|
|
|
|
2 @p Other vectors |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
B |
618
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
$x->Minus(new(0, 1)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
ok $x eq '(1,-1)'; |
625
|
|
|
|
|
|
|
$y -= new(1,1); |
626
|
|
|
|
|
|
|
ok $y eq '(-1,0)'; |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
=head2 minus($o, @p) |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
Subtract zero or more vectors from a copy of the first vector and return the result. |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
Parameter Description |
634
|
|
|
|
|
|
|
1 $o First vector |
635
|
|
|
|
|
|
|
2 @p Other vectors |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
B |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
641
|
|
|
|
|
|
|
ok $x + $y + $z == $x->plus($y); |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
ok $x - $y == $x->minus($y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
ok $x * 3 == $x->multiply(3); |
646
|
|
|
|
|
|
|
ok $y / 2 == $y->divide(2); |
647
|
|
|
|
|
|
|
ok $x + $y eq '(1,1)'; |
648
|
|
|
|
|
|
|
ok $x - $y eq '(1,-1)'; |
649
|
|
|
|
|
|
|
ok $x * 3 eq '(3,0)'; |
650
|
|
|
|
|
|
|
ok $y / 2 eq '(0,0.5)'; |
651
|
|
|
|
|
|
|
ok (($x * 2 + $y * 3)-> print eq '(2,3)'); |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
=head2 Multiply($o, $m) |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
Multiply a vector by a scalar and return the result. |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
Parameter Description |
659
|
|
|
|
|
|
|
1 $o Vector |
660
|
|
|
|
|
|
|
2 $m Scalar to multiply by |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
B |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
$x->Multiply(2); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
ok $x eq '(2,0)'; |
670
|
|
|
|
|
|
|
$y *= 2; |
671
|
|
|
|
|
|
|
ok $y eq '(0,2)'; |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
=head2 multiply($o, $m) |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
Multiply a copy of a vector by a scalar and return the result. |
678
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
Parameter Description |
680
|
|
|
|
|
|
|
1 $o Vector |
681
|
|
|
|
|
|
|
2 $m Scalar to multiply by |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
B |
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
687
|
|
|
|
|
|
|
ok $x + $y + $z == $x->plus($y); |
688
|
|
|
|
|
|
|
ok $x - $y == $x->minus($y); |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
ok $x * 3 == $x->multiply(3); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
ok $y / 2 == $y->divide(2); |
693
|
|
|
|
|
|
|
ok $x + $y eq '(1,1)'; |
694
|
|
|
|
|
|
|
ok $x - $y eq '(1,-1)'; |
695
|
|
|
|
|
|
|
ok $x * 3 eq '(3,0)'; |
696
|
|
|
|
|
|
|
ok $y / 2 eq '(0,0.5)'; |
697
|
|
|
|
|
|
|
ok (($x * 2 + $y * 3)-> print eq '(2,3)'); |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
=head2 Divide($o, $d) |
701
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
Divide a vector by a scalar and return the result. |
703
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
Parameter Description |
705
|
|
|
|
|
|
|
1 $o Vector |
706
|
|
|
|
|
|
|
2 $d Scalar to multiply by |
707
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
B |
709
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
|
711
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
712
|
|
|
|
|
|
|
|
713
|
|
|
|
|
|
|
$x->Divide(1/2); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
ok $x eq '(2,0)'; |
716
|
|
|
|
|
|
|
$y /= 1/2; |
717
|
|
|
|
|
|
|
ok $y eq '(0,2)'; |
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
=head2 divide($o, $d) |
722
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
Divide a copy of a vector by a scalar and return the result. |
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
Parameter Description |
726
|
|
|
|
|
|
|
1 $o Vector |
727
|
|
|
|
|
|
|
2 $d Scalar to divide by |
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
B |
730
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
733
|
|
|
|
|
|
|
ok $x + $y + $z == $x->plus($y); |
734
|
|
|
|
|
|
|
ok $x - $y == $x->minus($y); |
735
|
|
|
|
|
|
|
ok $x * 3 == $x->multiply(3); |
736
|
|
|
|
|
|
|
|
737
|
|
|
|
|
|
|
ok $y / 2 == $y->divide(2); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
738
|
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
ok $x + $y eq '(1,1)'; |
740
|
|
|
|
|
|
|
ok $x - $y eq '(1,-1)'; |
741
|
|
|
|
|
|
|
ok $x * 3 eq '(3,0)'; |
742
|
|
|
|
|
|
|
ok $y / 2 eq '(0,0.5)'; |
743
|
|
|
|
|
|
|
ok (($x * 2 + $y * 3)-> print eq '(2,3)'); |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
=head2 l($o) |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
Length of a vector. |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
Parameter Description |
751
|
|
|
|
|
|
|
1 $o Vector |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
B |
754
|
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
757
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
ok 5 == ($x * 3 + $y * 4)->l; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
ok 25 == ($x * 3 + $y * 4)->l2; |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
ok 2 * ($x + $y)->l == ($x + $y)->d (-$x - $y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
ok 4 * ($x + $y)->l2 == ($x + $y)->d2(-$x - $y); |
767
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
=head2 l2($o) |
770
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
Length squared of a vector. |
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
Parameter Description |
774
|
|
|
|
|
|
|
1 $o Vector |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
B |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
ok 5 == ($x * 3 + $y * 4)->l; |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
ok 25 == ($x * 3 + $y * 4)->l2; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
784
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
ok 2 * ($x + $y)->l == ($x + $y)->d (-$x - $y); |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
ok 4 * ($x + $y)->l2 == ($x + $y)->d2(-$x - $y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
=head2 d($o, $p) |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
Distance between the points identified by two vectors when placed on the same point. |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
Parameter Description |
797
|
|
|
|
|
|
|
1 $o Vector 1 |
798
|
|
|
|
|
|
|
2 $p Vector 2 |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
B |
801
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
ok 5 == ($x * 3 + $y * 4)->l; |
806
|
|
|
|
|
|
|
ok 25 == ($x * 3 + $y * 4)->l2; |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
ok 2 * ($x + $y)->l == ($x + $y)->d (-$x - $y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
810
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
ok 4 * ($x + $y)->l2 == ($x + $y)->d2(-$x - $y); |
812
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
=head2 d2($o, $p) |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
Distance squared between the points identified by two vectors when placed on the same point. |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
Parameter Description |
819
|
|
|
|
|
|
|
1 $o Vector 1 |
820
|
|
|
|
|
|
|
2 $p Vector 2 |
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
B |
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
826
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
ok 5 == ($x * 3 + $y * 4)->l; |
828
|
|
|
|
|
|
|
ok 25 == ($x * 3 + $y * 4)->l2; |
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
ok 2 * ($x + $y)->l == ($x + $y)->d (-$x - $y); |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
ok 4 * ($x + $y)->l2 == ($x + $y)->d2(-$x - $y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
=head2 n($o) |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
Return a normalized a copy of a vector. |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
Parameter Description |
841
|
|
|
|
|
|
|
1 $o Vector |
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
B |
844
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
ok (($x * 3 + $y * 4)->n == $x * 3/5 + $y * 4/5); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
ok 0 == $x . $y; |
852
|
|
|
|
|
|
|
ok 1 == $x . $x; |
853
|
|
|
|
|
|
|
ok 1 == $y . $y; |
854
|
|
|
|
|
|
|
ok 8 == ($x * 1 + $y * 2) .($x * 2 + $y * 3); |
855
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
=head2 dot($o, $p) |
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
Dot product of two vectors. |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
Parameter Description |
862
|
|
|
|
|
|
|
1 $o Vector 1 |
863
|
|
|
|
|
|
|
2 $p Vector 2 |
864
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
B |
866
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
869
|
|
|
|
|
|
|
ok (($x * 3 + $y * 4)->n == $x * 3/5 + $y * 4/5); |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
ok 0 == $x . $y; |
872
|
|
|
|
|
|
|
ok 1 == $x . $x; |
873
|
|
|
|
|
|
|
ok 1 == $y . $y; |
874
|
|
|
|
|
|
|
ok 8 == ($x * 1 + $y * 2) .($x * 2 + $y * 3); |
875
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
=head2 area($o, $p) |
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
Signed area of the parallelogram defined by the two vectors. The area is negative if the second vector appears to the right of the first if they are both placed at the origin and the observer stands against the z-axis in a left handed coordinate system. |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
Parameter Description |
882
|
|
|
|
|
|
|
1 $o Vector 1 |
883
|
|
|
|
|
|
|
2 $p Vector 2 |
884
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
B |
886
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
889
|
|
|
|
|
|
|
ok +1 == $x->cosine($x); |
890
|
|
|
|
|
|
|
ok +1 == $y->cosine($y); |
891
|
|
|
|
|
|
|
ok 0 == $x->cosine($y); |
892
|
|
|
|
|
|
|
ok 0 == $y->cosine($x); |
893
|
|
|
|
|
|
|
|
894
|
|
|
|
|
|
|
ok 0 == $x->sine($x); |
895
|
|
|
|
|
|
|
ok 0 == $y->sine($y); |
896
|
|
|
|
|
|
|
ok +1 == $x->sine($y); |
897
|
|
|
|
|
|
|
ok -1 == $y->sine($x); |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
ok near -sqrt(1/2), ($x + $y)->sine($x); |
900
|
|
|
|
|
|
|
ok near +sqrt(1/2), ($x + $y)->sine($y); |
901
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
ok near -2, ($x + $y)->area($x * 2); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
ok near +2, ($x + $y)->area($y * 2); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
|
909
|
|
|
|
|
|
|
=head2 cosine($o, $p) |
910
|
|
|
|
|
|
|
|
911
|
|
|
|
|
|
|
Cos(angle between two vectors). |
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
Parameter Description |
914
|
|
|
|
|
|
|
1 $o Vector 1 |
915
|
|
|
|
|
|
|
2 $p Vector 2 |
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
B |
918
|
|
|
|
|
|
|
|
919
|
|
|
|
|
|
|
|
920
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
921
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
ok +1 == $x->cosine($x); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
923
|
|
|
|
|
|
|
|
924
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
ok +1 == $y->cosine($y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
926
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
ok 0 == $x->cosine($y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
929
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
ok 0 == $y->cosine($x); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
ok 0 == $x->sine($x); |
935
|
|
|
|
|
|
|
ok 0 == $y->sine($y); |
936
|
|
|
|
|
|
|
ok +1 == $x->sine($y); |
937
|
|
|
|
|
|
|
ok -1 == $y->sine($x); |
938
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
ok near -sqrt(1/2), ($x + $y)->sine($x); |
940
|
|
|
|
|
|
|
ok near +sqrt(1/2), ($x + $y)->sine($y); |
941
|
|
|
|
|
|
|
ok near -2, ($x + $y)->area($x * 2); |
942
|
|
|
|
|
|
|
ok near +2, ($x + $y)->area($y * 2); |
943
|
|
|
|
|
|
|
|
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
=head2 sine($o, $p) |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
Sin(angle between two vectors). |
948
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
Parameter Description |
950
|
|
|
|
|
|
|
1 $o Vector 1 |
951
|
|
|
|
|
|
|
2 $p Vector 2 |
952
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
B |
954
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
957
|
|
|
|
|
|
|
ok +1 == $x->cosine($x); |
958
|
|
|
|
|
|
|
ok +1 == $y->cosine($y); |
959
|
|
|
|
|
|
|
ok 0 == $x->cosine($y); |
960
|
|
|
|
|
|
|
ok 0 == $y->cosine($x); |
961
|
|
|
|
|
|
|
|
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
ok 0 == $x->sine($x); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
964
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
|
966
|
|
|
|
|
|
|
ok 0 == $y->sine($y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
967
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
ok +1 == $x->sine($y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
970
|
|
|
|
|
|
|
|
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
ok -1 == $y->sine($x); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
973
|
|
|
|
|
|
|
|
974
|
|
|
|
|
|
|
|
975
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
ok near -sqrt(1/2), ($x + $y)->sine($x); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
977
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
|
979
|
|
|
|
|
|
|
ok near +sqrt(1/2), ($x + $y)->sine($y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
980
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
ok near -2, ($x + $y)->area($x * 2); |
982
|
|
|
|
|
|
|
ok near +2, ($x + $y)->area($y * 2); |
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
|
985
|
|
|
|
|
|
|
=head2 angle($o, $p) |
986
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
Angle in radians anticlockwise that the first vector must be rotated to point along the second vector normalized to the range: -pi to +pi. |
988
|
|
|
|
|
|
|
|
989
|
|
|
|
|
|
|
Parameter Description |
990
|
|
|
|
|
|
|
1 $o Vector 1 |
991
|
|
|
|
|
|
|
2 $p Vector 2 |
992
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
B |
994
|
|
|
|
|
|
|
|
995
|
|
|
|
|
|
|
|
996
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
997
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
ok near $y->angle(new(+1, -1)), deg2rad(-135); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
999
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
ok near $y->angle(new(+1, 0)), deg2rad(-90); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1002
|
|
|
|
|
|
|
|
1003
|
|
|
|
|
|
|
|
1004
|
|
|
|
|
|
|
ok near $y->angle(new(+1, +1)), deg2rad(-45); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1005
|
|
|
|
|
|
|
|
1006
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
ok near $y->angle(new( 0, +1)), deg2rad(+0); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1008
|
|
|
|
|
|
|
|
1009
|
|
|
|
|
|
|
|
1010
|
|
|
|
|
|
|
ok near $y->angle(new(-1, +1)), deg2rad(+45); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1011
|
|
|
|
|
|
|
|
1012
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
ok near $y->angle(new(-1, 0)), deg2rad(+90); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1014
|
|
|
|
|
|
|
|
1015
|
|
|
|
|
|
|
|
1016
|
|
|
|
|
|
|
ok near $y->angle(new(-1, -1)), deg2rad(+135); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1017
|
|
|
|
|
|
|
|
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
ok near new(1,1) < new( 0, -1), deg2rad(-135); |
1020
|
|
|
|
|
|
|
ok near new(1,1) < new( 1, -1), deg2rad(-90); |
1021
|
|
|
|
|
|
|
ok near new(1,1) < new( 1, 0), deg2rad(-45); |
1022
|
|
|
|
|
|
|
ok near new(1,1) < new( 1, 1), deg2rad(0); |
1023
|
|
|
|
|
|
|
ok near new(1,1) < new( 0, 1), deg2rad(+45); |
1024
|
|
|
|
|
|
|
ok near new(1,1) < new(-1, 1), deg2rad(+90); |
1025
|
|
|
|
|
|
|
ok near new(1,1) < new(-1, 0), deg2rad(+135); |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
ok near deg2rad(-60), $x + $y * sqrt(3) < $x; |
1028
|
|
|
|
|
|
|
|
1029
|
|
|
|
|
|
|
ok near deg2rad(+30), ($x + $y * sqrt(3))->angle($y); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1030
|
|
|
|
|
|
|
|
1031
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
ok near deg2rad( 0), $y->smallestAngleToNormalPlane( $x); # First vector is y, second vector is 0 degrees anti-clockwise from x axis |
1033
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane( $x + $y); |
1034
|
|
|
|
|
|
|
ok near deg2rad(+90), $y->smallestAngleToNormalPlane( $y); |
1035
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane(-$x + -$y); |
1036
|
|
|
|
|
|
|
ok near deg2rad( 0), $y->smallestAngleToNormalPlane(-$x); |
1037
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane(-$x + -$y); |
1038
|
|
|
|
|
|
|
ok near deg2rad(+90), $y->smallestAngleToNormalPlane( -$y); |
1039
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane(-$x + -$y); |
1040
|
|
|
|
|
|
|
ok near deg2rad( 0), $y->smallestAngleToNormalPlane( $x); |
1041
|
|
|
|
|
|
|
|
1042
|
|
|
|
|
|
|
for my $i(-179..179) |
1043
|
|
|
|
|
|
|
{ok near $x < new(cos(deg2rad($i)), sin(deg2rad($i))), deg2rad($i); |
1044
|
|
|
|
|
|
|
} |
1045
|
|
|
|
|
|
|
|
1046
|
|
|
|
|
|
|
|
1047
|
|
|
|
|
|
|
=head2 smallestAngleToNormalPlane($a, $b) |
1048
|
|
|
|
|
|
|
|
1049
|
|
|
|
|
|
|
The smallest angle between the second vector and a plane normal to the first vector. |
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
Parameter Description |
1052
|
|
|
|
|
|
|
1 $a Vector 1 |
1053
|
|
|
|
|
|
|
2 $b Vector 2 |
1054
|
|
|
|
|
|
|
|
1055
|
|
|
|
|
|
|
=head2 r90($o) |
1056
|
|
|
|
|
|
|
|
1057
|
|
|
|
|
|
|
Rotate a vector by 90 degrees anticlockwise. |
1058
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
Parameter Description |
1060
|
|
|
|
|
|
|
1 $o Vector to rotate |
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
B |
1063
|
|
|
|
|
|
|
|
1064
|
|
|
|
|
|
|
|
1065
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
1066
|
|
|
|
|
|
|
|
1067
|
|
|
|
|
|
|
ok $x->r90 == $y; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1068
|
|
|
|
|
|
|
|
1069
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
ok $y->r90 == -$x; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
|
1073
|
|
|
|
|
|
|
ok $x->r90->r90 == -$x; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1074
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
|
1076
|
|
|
|
|
|
|
ok $y->r90->r90 == -$y; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1077
|
|
|
|
|
|
|
|
1078
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
ok $x->r90->r90->r90 == -$y; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1080
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
ok $y->r90->r90->r90 == $x; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1083
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
|
1086
|
|
|
|
|
|
|
=head2 r180($o) |
1087
|
|
|
|
|
|
|
|
1088
|
|
|
|
|
|
|
Rotate a vector by 180 degrees. |
1089
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
Parameter Description |
1091
|
|
|
|
|
|
|
1 $o Vector to rotate |
1092
|
|
|
|
|
|
|
|
1093
|
|
|
|
|
|
|
B |
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
|
1096
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
1097
|
|
|
|
|
|
|
ok $x->r90 == $y; |
1098
|
|
|
|
|
|
|
ok $y->r90 == -$x; |
1099
|
|
|
|
|
|
|
ok $x->r90->r90 == -$x; |
1100
|
|
|
|
|
|
|
ok $y->r90->r90 == -$y; |
1101
|
|
|
|
|
|
|
ok $x->r90->r90->r90 == -$y; |
1102
|
|
|
|
|
|
|
ok $y->r90->r90->r90 == $x; |
1103
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
=head2 r270($o) |
1106
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
Rotate a vector by 270 degrees anticlockwise. |
1108
|
|
|
|
|
|
|
|
1109
|
|
|
|
|
|
|
Parameter Description |
1110
|
|
|
|
|
|
|
1 $o Vector to rotate |
1111
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
B |
1113
|
|
|
|
|
|
|
|
1114
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
1116
|
|
|
|
|
|
|
ok $x->r90 == $y; |
1117
|
|
|
|
|
|
|
ok $y->r90 == -$x; |
1118
|
|
|
|
|
|
|
ok $x->r90->r90 == -$x; |
1119
|
|
|
|
|
|
|
ok $y->r90->r90 == -$y; |
1120
|
|
|
|
|
|
|
ok $x->r90->r90->r90 == -$y; |
1121
|
|
|
|
|
|
|
ok $y->r90->r90->r90 == $x; |
1122
|
|
|
|
|
|
|
|
1123
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
=head2 rotate($p, $o, $sin, $cos) |
1125
|
|
|
|
|
|
|
|
1126
|
|
|
|
|
|
|
Rotate a vector about another vector through an angle specified by its values as sin, and cos. |
1127
|
|
|
|
|
|
|
|
1128
|
|
|
|
|
|
|
Parameter Description |
1129
|
|
|
|
|
|
|
1 $p Vector to rotate |
1130
|
|
|
|
|
|
|
2 $o Center of rotation |
1131
|
|
|
|
|
|
|
3 $sin Sin of the angle of rotation |
1132
|
|
|
|
|
|
|
4 $cos Cosine of the angle of rotation |
1133
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
B |
1135
|
|
|
|
|
|
|
|
1136
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
ok near2 new(1, 0)->rotate(new(0,0), 1, 0), new( 0, 1); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1139
|
|
|
|
|
|
|
|
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
ok near2 new(1, 1)->rotate(new(0,0), 1, 0), new(-1, 1); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1142
|
|
|
|
|
|
|
|
1143
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
ok near2 new(0, 1)->rotate(new(0,0), 1, 0), new(-1, 0); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1145
|
|
|
|
|
|
|
|
1146
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
ok near2 new(2, 2)->rotate(new(1,1), -1/sqrt(2), 1/sqrt(2)), new(1+sqrt(2), 1); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1148
|
|
|
|
|
|
|
|
1149
|
|
|
|
|
|
|
|
1150
|
|
|
|
|
|
|
ok near2 new(3, 1)->rotate(new(1,1), sqrt(3)/2, 1/2), new(2, 1+sqrt(3)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1151
|
|
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
|
1153
|
|
|
|
|
|
|
|
1154
|
|
|
|
|
|
|
ok near2 new(3, 1)->rotate(new(1,1), # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1155
|
|
|
|
|
|
|
|
1156
|
|
|
|
|
|
|
new(1, 0)->sine (new(1,1)), |
1157
|
|
|
|
|
|
|
new(1, 0)->cosine(new(1,1))), |
1158
|
|
|
|
|
|
|
new(1+sqrt(2), 1+sqrt(2)); |
1159
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
|
1161
|
|
|
|
|
|
|
=head2 intersection($a, $b, $c, $d) |
1162
|
|
|
|
|
|
|
|
1163
|
|
|
|
|
|
|
Find the intersection of two line segments delimited by vectors if such a point exists. |
1164
|
|
|
|
|
|
|
|
1165
|
|
|
|
|
|
|
Parameter Description |
1166
|
|
|
|
|
|
|
1 $a Start of first line segment |
1167
|
|
|
|
|
|
|
2 $b End of first line segment |
1168
|
|
|
|
|
|
|
3 $c Start of second line segment |
1169
|
|
|
|
|
|
|
4 $d End of second line segment |
1170
|
|
|
|
|
|
|
|
1171
|
|
|
|
|
|
|
B |
1172
|
|
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
|
1174
|
|
|
|
|
|
|
|
1175
|
|
|
|
|
|
|
ok near2 intersection(new(0,0), new(2,2), new(0,2),new(2,0)), new(1,1); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1176
|
|
|
|
|
|
|
|
1177
|
|
|
|
|
|
|
|
1178
|
|
|
|
|
|
|
ok near2 intersection(new(1,1), new(3,3), new(1,3),new(3,1)), new(2,2); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1179
|
|
|
|
|
|
|
|
1180
|
|
|
|
|
|
|
|
1181
|
|
|
|
|
|
|
|
1182
|
|
|
|
|
|
|
=head2 triangulate($clockwise, @boundary) |
1183
|
|
|
|
|
|
|
|
1184
|
|
|
|
|
|
|
Find a set of triangles that cover a shape whose boundary points are represented by an array of vectors. The points along the boundary must be given in such away that the interior of the shape is always on the same side for each pair of successive points as indicated by the clockwise parameter. |
1185
|
|
|
|
|
|
|
|
1186
|
|
|
|
|
|
|
Parameter Description |
1187
|
|
|
|
|
|
|
1 $clockwise If true then the interior of the shape is on the left as the boundary of the shape is traversed otherwise on the right |
1188
|
|
|
|
|
|
|
2 @boundary Vectors representing the boundary of the shape |
1189
|
|
|
|
|
|
|
|
1190
|
|
|
|
|
|
|
B |
1191
|
|
|
|
|
|
|
|
1192
|
|
|
|
|
|
|
|
1193
|
|
|
|
|
|
|
|
1194
|
|
|
|
|
|
|
my @t = triangulate(1, new(0,0), new(2,0), new(2,2), new(0,2)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1195
|
|
|
|
|
|
|
|
1196
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
ok near2 $t[0][0], new(1, 1); |
1198
|
|
|
|
|
|
|
ok near2 $t[0][1], new(0, 0); |
1199
|
|
|
|
|
|
|
ok near2 $t[0][2], new(2, 0); |
1200
|
|
|
|
|
|
|
|
1201
|
|
|
|
|
|
|
ok near2 $t[1][0], new(1, 1); |
1202
|
|
|
|
|
|
|
ok near2 $t[1][1], new(2, 0); |
1203
|
|
|
|
|
|
|
ok near2 $t[1][2], new(2, 2); |
1204
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
ok near2 $t[2][0], new(1, 1); |
1206
|
|
|
|
|
|
|
ok near2 $t[2][1], new(2, 2); |
1207
|
|
|
|
|
|
|
ok near2 $t[2][2], new(0, 2); |
1208
|
|
|
|
|
|
|
|
1209
|
|
|
|
|
|
|
ok near2 $t[3][0], new(0, 0); |
1210
|
|
|
|
|
|
|
ok near2 $t[3][1], new(1, 1); |
1211
|
|
|
|
|
|
|
ok near2 $t[3][2], new(0, 2); |
1212
|
|
|
|
|
|
|
|
1213
|
|
|
|
|
|
|
|
1214
|
|
|
|
|
|
|
my @t = triangulate(0, new(2,2), new(2, 4), new(4,4), new(4, 2)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1215
|
|
|
|
|
|
|
|
1216
|
|
|
|
|
|
|
|
1217
|
|
|
|
|
|
|
ok near2 $t[0][0], new(3, 3); |
1218
|
|
|
|
|
|
|
ok near2 $t[0][1], new(2, 2); |
1219
|
|
|
|
|
|
|
ok near2 $t[0][2], new(2, 4); |
1220
|
|
|
|
|
|
|
|
1221
|
|
|
|
|
|
|
ok near2 $t[1][0], new(3, 3); |
1222
|
|
|
|
|
|
|
ok near2 $t[1][1], new(2, 4); |
1223
|
|
|
|
|
|
|
ok near2 $t[1][2], new(4, 4); |
1224
|
|
|
|
|
|
|
|
1225
|
|
|
|
|
|
|
ok near2 $t[2][0], new(3, 3); |
1226
|
|
|
|
|
|
|
ok near2 $t[2][1], new(4, 4); |
1227
|
|
|
|
|
|
|
ok near2 $t[2][2], new(4, 2); |
1228
|
|
|
|
|
|
|
|
1229
|
|
|
|
|
|
|
ok near2 $t[3][0], new(2, 2); |
1230
|
|
|
|
|
|
|
ok near2 $t[3][1], new(3, 3); |
1231
|
|
|
|
|
|
|
ok near2 $t[3][2], new(4, 2); |
1232
|
|
|
|
|
|
|
|
1233
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
=head2 swap($o) |
1235
|
|
|
|
|
|
|
|
1236
|
|
|
|
|
|
|
Swap the components of a vector. |
1237
|
|
|
|
|
|
|
|
1238
|
|
|
|
|
|
|
Parameter Description |
1239
|
|
|
|
|
|
|
1 $o Vector |
1240
|
|
|
|
|
|
|
|
1241
|
|
|
|
|
|
|
B |
1242
|
|
|
|
|
|
|
|
1243
|
|
|
|
|
|
|
|
1244
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
1245
|
|
|
|
|
|
|
|
1246
|
|
|
|
|
|
|
ok $x->swap == $y; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 |
1247
|
|
|
|
|
|
|
|
1248
|
|
|
|
|
|
|
ok $x->clone == $x; |
1249
|
|
|
|
|
|
|
|
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
|
1252
|
|
|
|
|
|
|
=head1 Hash Definitions |
1253
|
|
|
|
|
|
|
|
1254
|
|
|
|
|
|
|
|
1255
|
|
|
|
|
|
|
|
1256
|
|
|
|
|
|
|
|
1257
|
|
|
|
|
|
|
=head2 Math::Vectors2 Definition |
1258
|
|
|
|
|
|
|
|
1259
|
|
|
|
|
|
|
|
1260
|
|
|
|
|
|
|
Attributes of a vector |
1261
|
|
|
|
|
|
|
|
1262
|
|
|
|
|
|
|
|
1263
|
|
|
|
|
|
|
|
1264
|
|
|
|
|
|
|
|
1265
|
|
|
|
|
|
|
=head3 Output fields |
1266
|
|
|
|
|
|
|
|
1267
|
|
|
|
|
|
|
|
1268
|
|
|
|
|
|
|
=head4 x |
1269
|
|
|
|
|
|
|
|
1270
|
|
|
|
|
|
|
X coordinate |
1271
|
|
|
|
|
|
|
|
1272
|
|
|
|
|
|
|
=head4 y |
1273
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
Y coordinate |
1275
|
|
|
|
|
|
|
|
1276
|
|
|
|
|
|
|
|
1277
|
|
|
|
|
|
|
|
1278
|
|
|
|
|
|
|
=head1 Index |
1279
|
|
|
|
|
|
|
|
1280
|
|
|
|
|
|
|
|
1281
|
|
|
|
|
|
|
1 L - Angle in radians anticlockwise that the first vector must be rotated to point along the second vector normalized to the range: -pi to +pi. |
1282
|
|
|
|
|
|
|
|
1283
|
|
|
|
|
|
|
2 L - Signed area of the parallelogram defined by the two vectors. |
1284
|
|
|
|
|
|
|
|
1285
|
|
|
|
|
|
|
3 L - Clone a vector. |
1286
|
|
|
|
|
|
|
|
1287
|
|
|
|
|
|
|
4 L - Cos(angle between two vectors). |
1288
|
|
|
|
|
|
|
|
1289
|
|
|
|
|
|
|
5 L - Distance between the points identified by two vectors when placed on the same point. |
1290
|
|
|
|
|
|
|
|
1291
|
|
|
|
|
|
|
6 L - Distance squared between the points identified by two vectors when placed on the same point. |
1292
|
|
|
|
|
|
|
|
1293
|
|
|
|
|
|
|
7 L - Divide a vector by a scalar and return the result. |
1294
|
|
|
|
|
|
|
|
1295
|
|
|
|
|
|
|
8 L - Divide a copy of a vector by a scalar and return the result. |
1296
|
|
|
|
|
|
|
|
1297
|
|
|
|
|
|
|
9 L - Dot product of two vectors. |
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
10 L - Whether two vectors are equal to within the accuracy of floating point arithmetic. |
1300
|
|
|
|
|
|
|
|
1301
|
|
|
|
|
|
|
11 L - Find the intersection of two line segments delimited by vectors if such a point exists. |
1302
|
|
|
|
|
|
|
|
1303
|
|
|
|
|
|
|
12 L - Length of a vector. |
1304
|
|
|
|
|
|
|
|
1305
|
|
|
|
|
|
|
13 L - Length squared of a vector. |
1306
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
14 L - Subtract zero or more vectors from the first vector and return the result. |
1308
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
15 L - Subtract zero or more vectors from a copy of the first vector and return the result. |
1310
|
|
|
|
|
|
|
|
1311
|
|
|
|
|
|
|
16 L - Multiply a copy of a vector by a scalar and return the result. |
1312
|
|
|
|
|
|
|
|
1313
|
|
|
|
|
|
|
17 L - Multiply a vector by a scalar and return the result. |
1314
|
|
|
|
|
|
|
|
1315
|
|
|
|
|
|
|
18 L - Return a normalized a copy of a vector. |
1316
|
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
19 L - Create new vector from components. |
1318
|
|
|
|
|
|
|
|
1319
|
|
|
|
|
|
|
20 L - Add zero or more other vectors to a copy of the first vector and return the result. |
1320
|
|
|
|
|
|
|
|
1321
|
|
|
|
|
|
|
21 L - Add zero or more other vectors to the first vector and return the result. |
1322
|
|
|
|
|
|
|
|
1323
|
|
|
|
|
|
|
22 L - Print one or more vectors. |
1324
|
|
|
|
|
|
|
|
1325
|
|
|
|
|
|
|
23 L - Rotate a vector by 180 degrees. |
1326
|
|
|
|
|
|
|
|
1327
|
|
|
|
|
|
|
24 L - Rotate a vector by 270 degrees anticlockwise. |
1328
|
|
|
|
|
|
|
|
1329
|
|
|
|
|
|
|
25 L - Rotate a vector by 90 degrees anticlockwise. |
1330
|
|
|
|
|
|
|
|
1331
|
|
|
|
|
|
|
26 L - Rotate a vector about another vector through an angle specified by its values as sin, and cos. |
1332
|
|
|
|
|
|
|
|
1333
|
|
|
|
|
|
|
27 L - Sin(angle between two vectors). |
1334
|
|
|
|
|
|
|
|
1335
|
|
|
|
|
|
|
28 L - The smallest angle between the second vector and a plane normal to the first vector. |
1336
|
|
|
|
|
|
|
|
1337
|
|
|
|
|
|
|
29 L - Swap the components of a vector. |
1338
|
|
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
30 L - Find a set of triangles that cover a shape whose boundary points are represented by an array of vectors. |
1340
|
|
|
|
|
|
|
|
1341
|
|
|
|
|
|
|
31 L - Whether a vector is equal to zero within the accuracy of floating point arithmetic. |
1342
|
|
|
|
|
|
|
|
1343
|
|
|
|
|
|
|
32 L - Create the useful vectors: zero=(0,0), x=(1,0), y=(0,1). |
1344
|
|
|
|
|
|
|
|
1345
|
|
|
|
|
|
|
=head1 Installation |
1346
|
|
|
|
|
|
|
|
1347
|
|
|
|
|
|
|
This module is written in 100% Pure Perl and, thus, it is easy to read, |
1348
|
|
|
|
|
|
|
comprehend, use, modify and install via B: |
1349
|
|
|
|
|
|
|
|
1350
|
|
|
|
|
|
|
sudo cpan install Math::Vectors2 |
1351
|
|
|
|
|
|
|
|
1352
|
|
|
|
|
|
|
=head1 Author |
1353
|
|
|
|
|
|
|
|
1354
|
|
|
|
|
|
|
L |
1355
|
|
|
|
|
|
|
|
1356
|
|
|
|
|
|
|
L |
1357
|
|
|
|
|
|
|
|
1358
|
|
|
|
|
|
|
=head1 Copyright |
1359
|
|
|
|
|
|
|
|
1360
|
|
|
|
|
|
|
Copyright (c) 2016-2023 Philip R Brenan. |
1361
|
|
|
|
|
|
|
|
1362
|
|
|
|
|
|
|
This module is free software. It may be used, redistributed and/or modified |
1363
|
|
|
|
|
|
|
under the same terms as Perl itself. |
1364
|
|
|
|
|
|
|
|
1365
|
|
|
|
|
|
|
=cut |
1366
|
|
|
|
|
|
|
|
1367
|
|
|
|
|
|
|
|
1368
|
|
|
|
|
|
|
|
1369
|
|
|
|
|
|
|
# Tests and documentation |
1370
|
|
|
|
|
|
|
|
1371
|
|
|
|
|
|
|
sub test |
1372
|
1
|
|
|
1
|
0
|
84
|
{my $p = __PACKAGE__; |
1373
|
1
|
|
|
|
|
11
|
binmode($_, ":utf8") for *STDOUT, *STDERR; |
1374
|
1
|
50
|
|
|
|
63
|
return if eval "eof(${p}::DATA)"; |
1375
|
0
|
|
|
|
|
|
my $s = eval "join('', <${p}::DATA>)"; |
1376
|
0
|
0
|
|
|
|
|
$@ and die $@; |
1377
|
0
|
|
|
|
|
|
eval $s; |
1378
|
0
|
0
|
|
|
|
|
$@ and die $@; |
1379
|
0
|
|
|
|
|
|
1 |
1380
|
|
|
|
|
|
|
} |
1381
|
|
|
|
|
|
|
|
1382
|
|
|
|
|
|
|
test unless caller; |
1383
|
|
|
|
|
|
|
|
1384
|
|
|
|
|
|
|
1; |
1385
|
|
|
|
|
|
|
# podDocumentation |
1386
|
|
|
|
|
|
|
#__DATA__ |
1387
|
1
|
|
|
1
|
|
750
|
use Test::More tests => 465; |
|
1
|
|
|
|
|
81368
|
|
|
1
|
|
|
|
|
8
|
|
1388
|
|
|
|
|
|
|
|
1389
|
|
|
|
|
|
|
eval "goto latest"; |
1390
|
|
|
|
|
|
|
|
1391
|
|
|
|
|
|
|
if (1) { #TzeroAndUnits #Tplus #Tminus #Tmultiply #Tdivide #Teq #Tprint |
1392
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
1393
|
|
|
|
|
|
|
ok $x + $y + $z == $x->plus($y); |
1394
|
|
|
|
|
|
|
ok $x - $y == $x->minus($y); |
1395
|
|
|
|
|
|
|
ok $x * 3 == $x->multiply(3); |
1396
|
|
|
|
|
|
|
ok $y / 2 == $y->divide(2); |
1397
|
|
|
|
|
|
|
ok $x + $y eq '(1,1)'; |
1398
|
|
|
|
|
|
|
ok $x - $y eq '(1,-1)'; |
1399
|
|
|
|
|
|
|
ok $x * 3 eq '(3,0)'; |
1400
|
|
|
|
|
|
|
ok $y / 2 eq '(0,0.5)'; |
1401
|
|
|
|
|
|
|
ok (($x * 2 + $y * 3)-> print eq '(2,3)'); |
1402
|
|
|
|
|
|
|
} |
1403
|
|
|
|
|
|
|
|
1404
|
|
|
|
|
|
|
if (1) { #Tclone #Tswap |
1405
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
1406
|
|
|
|
|
|
|
ok $x->swap == $y; |
1407
|
|
|
|
|
|
|
ok $x->clone == $x; |
1408
|
|
|
|
|
|
|
} |
1409
|
|
|
|
|
|
|
|
1410
|
|
|
|
|
|
|
if (1) { #Td #Td2 #Tl #Tl2 |
1411
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
1412
|
|
|
|
|
|
|
|
1413
|
|
|
|
|
|
|
ok 5 == ($x * 3 + $y * 4)->l; |
1414
|
|
|
|
|
|
|
ok 25 == ($x * 3 + $y * 4)->l2; |
1415
|
|
|
|
|
|
|
|
1416
|
|
|
|
|
|
|
ok 2 * ($x + $y)->l == ($x + $y)->d (-$x - $y); |
1417
|
|
|
|
|
|
|
ok 4 * ($x + $y)->l2 == ($x + $y)->d2(-$x - $y); |
1418
|
|
|
|
|
|
|
} |
1419
|
|
|
|
|
|
|
|
1420
|
|
|
|
|
|
|
if (1) { #Tn #Tdot |
1421
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
1422
|
|
|
|
|
|
|
ok (($x * 3 + $y * 4)->n == $x * 3/5 + $y * 4/5); |
1423
|
|
|
|
|
|
|
|
1424
|
|
|
|
|
|
|
ok 0 == $x . $y; |
1425
|
|
|
|
|
|
|
ok 1 == $x . $x; |
1426
|
|
|
|
|
|
|
ok 1 == $y . $y; |
1427
|
|
|
|
|
|
|
ok 8 == ($x * 1 + $y * 2) .($x * 2 + $y * 3); |
1428
|
|
|
|
|
|
|
} |
1429
|
|
|
|
|
|
|
|
1430
|
|
|
|
|
|
|
|
1431
|
|
|
|
|
|
|
if (1) { #Tr90 #Tr180 #Tr270 |
1432
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
1433
|
|
|
|
|
|
|
ok $x->r90 == $y; |
1434
|
|
|
|
|
|
|
ok $y->r90 == -$x; |
1435
|
|
|
|
|
|
|
ok $x->r90->r90 == -$x; |
1436
|
|
|
|
|
|
|
ok $y->r90->r90 == -$y; |
1437
|
|
|
|
|
|
|
ok $x->r90->r90->r90 == -$y; |
1438
|
|
|
|
|
|
|
ok $y->r90->r90->r90 == $x; |
1439
|
|
|
|
|
|
|
} |
1440
|
|
|
|
|
|
|
|
1441
|
|
|
|
|
|
|
|
1442
|
|
|
|
|
|
|
if (1) { #Tsine #Tcosine #Tarea |
1443
|
|
|
|
|
|
|
my ($z, $x, $y) = zeroAndUnits; |
1444
|
|
|
|
|
|
|
ok +1 == $x->cosine($x); |
1445
|
|
|
|
|
|
|
ok +1 == $y->cosine($y); |
1446
|
|
|
|
|
|
|
ok 0 == $x->cosine($y); |
1447
|
|
|
|
|
|
|
ok 0 == $y->cosine($x); |
1448
|
|
|
|
|
|
|
|
1449
|
|
|
|
|
|
|
ok 0 == $x->sine($x); |
1450
|
|
|
|
|
|
|
ok 0 == $y->sine($y); |
1451
|
|
|
|
|
|
|
ok +1 == $x->sine($y); |
1452
|
|
|
|
|
|
|
ok -1 == $y->sine($x); |
1453
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
ok near -sqrt(1/2), ($x + $y)->sine($x); |
1455
|
|
|
|
|
|
|
ok near +sqrt(1/2), ($x + $y)->sine($y); |
1456
|
|
|
|
|
|
|
ok near -2, ($x + $y)->area($x * 2); |
1457
|
|
|
|
|
|
|
ok near +2, ($x + $y)->area($y * 2); |
1458
|
|
|
|
|
|
|
} |
1459
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
if (1) { #Tangle #Tnew |
1461
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
1462
|
|
|
|
|
|
|
ok near $y->angle(new(+1, -1)), deg2rad(-135); |
1463
|
|
|
|
|
|
|
ok near $y->angle(new(+1, 0)), deg2rad(-90); |
1464
|
|
|
|
|
|
|
ok near $y->angle(new(+1, +1)), deg2rad(-45); |
1465
|
|
|
|
|
|
|
ok near $y->angle(new( 0, +1)), deg2rad(+0); |
1466
|
|
|
|
|
|
|
ok near $y->angle(new(-1, +1)), deg2rad(+45); |
1467
|
|
|
|
|
|
|
ok near $y->angle(new(-1, 0)), deg2rad(+90); |
1468
|
|
|
|
|
|
|
ok near $y->angle(new(-1, -1)), deg2rad(+135); |
1469
|
|
|
|
|
|
|
|
1470
|
|
|
|
|
|
|
ok near new(1,1) < new( 0, -1), deg2rad(-135); |
1471
|
|
|
|
|
|
|
ok near new(1,1) < new( 1, -1), deg2rad(-90); |
1472
|
|
|
|
|
|
|
ok near new(1,1) < new( 1, 0), deg2rad(-45); |
1473
|
|
|
|
|
|
|
ok near new(1,1) < new( 1, 1), deg2rad(0); |
1474
|
|
|
|
|
|
|
ok near new(1,1) < new( 0, 1), deg2rad(+45); |
1475
|
|
|
|
|
|
|
ok near new(1,1) < new(-1, 1), deg2rad(+90); |
1476
|
|
|
|
|
|
|
ok near new(1,1) < new(-1, 0), deg2rad(+135); |
1477
|
|
|
|
|
|
|
|
1478
|
|
|
|
|
|
|
ok near deg2rad(-60), $x + $y * sqrt(3) < $x; |
1479
|
|
|
|
|
|
|
ok near deg2rad(+30), ($x + $y * sqrt(3))->angle($y); |
1480
|
|
|
|
|
|
|
|
1481
|
|
|
|
|
|
|
ok near deg2rad( 0), $y->smallestAngleToNormalPlane( $x); # First vector is y, second vector is 0 degrees anti-clockwise from x axis |
1482
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane( $x + $y); |
1483
|
|
|
|
|
|
|
ok near deg2rad(+90), $y->smallestAngleToNormalPlane( $y); |
1484
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane(-$x + -$y); |
1485
|
|
|
|
|
|
|
ok near deg2rad( 0), $y->smallestAngleToNormalPlane(-$x); |
1486
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane(-$x + -$y); |
1487
|
|
|
|
|
|
|
ok near deg2rad(+90), $y->smallestAngleToNormalPlane( -$y); |
1488
|
|
|
|
|
|
|
ok near deg2rad(+45), $y->smallestAngleToNormalPlane(-$x + -$y); |
1489
|
|
|
|
|
|
|
ok near deg2rad( 0), $y->smallestAngleToNormalPlane( $x); |
1490
|
|
|
|
|
|
|
|
1491
|
|
|
|
|
|
|
for my $i(-179..179) |
1492
|
|
|
|
|
|
|
{ok near $x < new(cos(deg2rad($i)), sin(deg2rad($i))), deg2rad($i); |
1493
|
|
|
|
|
|
|
} |
1494
|
|
|
|
|
|
|
} |
1495
|
|
|
|
|
|
|
|
1496
|
|
|
|
|
|
|
if (1) { #TPlus |
1497
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
1498
|
|
|
|
|
|
|
$x->Plus(new(1,1)); |
1499
|
|
|
|
|
|
|
ok $x eq '(2,1)'; |
1500
|
|
|
|
|
|
|
$y += new(1,1); |
1501
|
|
|
|
|
|
|
ok $y eq '(1,2)'; |
1502
|
|
|
|
|
|
|
|
1503
|
|
|
|
|
|
|
} |
1504
|
|
|
|
|
|
|
if (1) { #TMinus |
1505
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
1506
|
|
|
|
|
|
|
$x->Minus(new(0, 1)); |
1507
|
|
|
|
|
|
|
ok $x eq '(1,-1)'; |
1508
|
|
|
|
|
|
|
$y -= new(1,1); |
1509
|
|
|
|
|
|
|
ok $y eq '(-1,0)'; |
1510
|
|
|
|
|
|
|
} |
1511
|
|
|
|
|
|
|
if (1) { #TMultiply |
1512
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
1513
|
|
|
|
|
|
|
$x->Multiply(2); |
1514
|
|
|
|
|
|
|
ok $x eq '(2,0)'; |
1515
|
|
|
|
|
|
|
$y *= 2; |
1516
|
|
|
|
|
|
|
ok $y eq '(0,2)'; |
1517
|
|
|
|
|
|
|
|
1518
|
|
|
|
|
|
|
} |
1519
|
|
|
|
|
|
|
if (1) { #TDivide |
1520
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
1521
|
|
|
|
|
|
|
$x->Divide(1/2); |
1522
|
|
|
|
|
|
|
ok $x eq '(2,0)'; |
1523
|
|
|
|
|
|
|
$y /= 1/2; |
1524
|
|
|
|
|
|
|
ok $y eq '(0,2)'; |
1525
|
|
|
|
|
|
|
|
1526
|
|
|
|
|
|
|
} |
1527
|
|
|
|
|
|
|
|
1528
|
|
|
|
|
|
|
if (1) { #Tzero |
1529
|
|
|
|
|
|
|
my ($zero, $x, $y) = zeroAndUnits; |
1530
|
|
|
|
|
|
|
ok $zero->zero; |
1531
|
|
|
|
|
|
|
ok !$x->zero; |
1532
|
|
|
|
|
|
|
ok !$y->zero; |
1533
|
|
|
|
|
|
|
} |
1534
|
|
|
|
|
|
|
|
1535
|
|
|
|
|
|
|
#latest:; |
1536
|
|
|
|
|
|
|
if (1) { #Trotate |
1537
|
|
|
|
|
|
|
ok near2 new(1, 0)->rotate(new(0,0), 1, 0), new( 0, 1); |
1538
|
|
|
|
|
|
|
ok near2 new(1, 1)->rotate(new(0,0), 1, 0), new(-1, 1); |
1539
|
|
|
|
|
|
|
ok near2 new(0, 1)->rotate(new(0,0), 1, 0), new(-1, 0); |
1540
|
|
|
|
|
|
|
ok near2 new(2, 2)->rotate(new(1,1), -1/sqrt(2), 1/sqrt(2)), new(1+sqrt(2), 1); |
1541
|
|
|
|
|
|
|
ok near2 new(3, 1)->rotate(new(1,1), sqrt(3)/2, 1/2), new(2, 1+sqrt(3)); |
1542
|
|
|
|
|
|
|
|
1543
|
|
|
|
|
|
|
ok near2 new(3, 1)->rotate(new(1,1), |
1544
|
|
|
|
|
|
|
new(1, 0)->sine (new(1,1)), |
1545
|
|
|
|
|
|
|
new(1, 0)->cosine(new(1,1))), |
1546
|
|
|
|
|
|
|
new(1+sqrt(2), 1+sqrt(2)); |
1547
|
|
|
|
|
|
|
} |
1548
|
|
|
|
|
|
|
|
1549
|
|
|
|
|
|
|
#latest:; |
1550
|
|
|
|
|
|
|
if (1) { #Tintersection |
1551
|
|
|
|
|
|
|
ok near2 intersection(new(0,0), new(2,2), new(0,2),new(2,0)), new(1,1); |
1552
|
|
|
|
|
|
|
ok near2 intersection(new(1,1), new(3,3), new(1,3),new(3,1)), new(2,2); |
1553
|
|
|
|
|
|
|
} |
1554
|
|
|
|
|
|
|
|
1555
|
|
|
|
|
|
|
#latest:; |
1556
|
|
|
|
|
|
|
if (1) { #Ttriangulate |
1557
|
|
|
|
|
|
|
my @t = triangulate(1, new(0,0), new(2,0), new(2,2), new(0,2)); |
1558
|
|
|
|
|
|
|
|
1559
|
|
|
|
|
|
|
ok near2 $t[0][0], new(1, 1); |
1560
|
|
|
|
|
|
|
ok near2 $t[0][1], new(0, 0); |
1561
|
|
|
|
|
|
|
ok near2 $t[0][2], new(2, 0); |
1562
|
|
|
|
|
|
|
|
1563
|
|
|
|
|
|
|
ok near2 $t[1][0], new(1, 1); |
1564
|
|
|
|
|
|
|
ok near2 $t[1][1], new(2, 0); |
1565
|
|
|
|
|
|
|
ok near2 $t[1][2], new(2, 2); |
1566
|
|
|
|
|
|
|
|
1567
|
|
|
|
|
|
|
ok near2 $t[2][0], new(1, 1); |
1568
|
|
|
|
|
|
|
ok near2 $t[2][1], new(2, 2); |
1569
|
|
|
|
|
|
|
ok near2 $t[2][2], new(0, 2); |
1570
|
|
|
|
|
|
|
|
1571
|
|
|
|
|
|
|
ok near2 $t[3][0], new(0, 0); |
1572
|
|
|
|
|
|
|
ok near2 $t[3][1], new(1, 1); |
1573
|
|
|
|
|
|
|
ok near2 $t[3][2], new(0, 2); |
1574
|
|
|
|
|
|
|
} |
1575
|
|
|
|
|
|
|
|
1576
|
|
|
|
|
|
|
#latest:; |
1577
|
|
|
|
|
|
|
if (1) { #Ttriangulate |
1578
|
|
|
|
|
|
|
my @t = triangulate(0, new(2,2), new(2, 4), new(4,4), new(4, 2)); |
1579
|
|
|
|
|
|
|
|
1580
|
|
|
|
|
|
|
ok near2 $t[0][0], new(3, 3); |
1581
|
|
|
|
|
|
|
ok near2 $t[0][1], new(2, 2); |
1582
|
|
|
|
|
|
|
ok near2 $t[0][2], new(2, 4); |
1583
|
|
|
|
|
|
|
|
1584
|
|
|
|
|
|
|
ok near2 $t[1][0], new(3, 3); |
1585
|
|
|
|
|
|
|
ok near2 $t[1][1], new(2, 4); |
1586
|
|
|
|
|
|
|
ok near2 $t[1][2], new(4, 4); |
1587
|
|
|
|
|
|
|
|
1588
|
|
|
|
|
|
|
ok near2 $t[2][0], new(3, 3); |
1589
|
|
|
|
|
|
|
ok near2 $t[2][1], new(4, 4); |
1590
|
|
|
|
|
|
|
ok near2 $t[2][2], new(4, 2); |
1591
|
|
|
|
|
|
|
|
1592
|
|
|
|
|
|
|
ok near2 $t[3][0], new(2, 2); |
1593
|
|
|
|
|
|
|
ok near2 $t[3][1], new(3, 3); |
1594
|
|
|
|
|
|
|
ok near2 $t[3][2], new(4, 2); |
1595
|
|
|
|
|
|
|
} |