1Math::Vec(3) User Contributed Perl Documentation Math::Vec(3)
2
3
4
6 Math::Vec - Object-Oriented Vector Math Methods in Perl
7
9 use Math::Vec;
10 $v = Math::Vec->new(0,1,2);
11
12 or
13
14 use Math::Vec qw(NewVec);
15 $v = NewVec(0,1,2);
16 @res = $v->Cross([1,2.5,0]);
17 $p = NewVec(@res);
18 $q = $p->Dot([0,1,0]);
19
20 or
21
22 use Math::Vec qw(:terse);
23 $v = V(0,1,2);
24 $q = ($v x [1,2.5,0]) * [0,1,0];
25
27 This module is still somewhat incomplete. If a function does nothing,
28 there is likely a really good reason. Please have a look at the code
29 if you are trying to use this in a production environment.
30
32 Eric L. Wilhelm <ewilhelm at cpan dot org>
33
34 http://scratchcomputing.com
35
37 This module was adapted from Math::Vector, written by Wayne M. Syvin‐
38 ski.
39
40 It uses most of the same algorithms, and currently preserves the same
41 names as the original functions, though some aliases have been added to
42 make the interface more natural (at least to the way I think.)
43
44 The "object" for the object oriented calling style is a blessed array
45 reference which contains a vector of the form [x,y,z]. Methods will
46 typically return a list.
47
49 Copyright (C) 2003-2006 Eric Wilhelm
50
51 portions Copyright 2003 Wayne M. Syvinski
52
54 Absolutely, positively NO WARRANTY, neither express or implied, is
55 offered with this software. You use this software at your own risk.
56 In case of loss, neither Wayne M. Syvinski, Eric Wilhelm, nor anyone
57 else, owes you anything whatseover. You have been warned.
58
59 Note that this includes NO GUARANTEE of MATHEMATICAL CORRECTNESS. If
60 you are going to use this code in a production environment, it is YOUR
61 RESPONSIBILITY to verify that the methods return the correct values.
62
64 You may use this software under one of the following licenses:
65
66 (1) GNU General Public License
67 (found at http://www.gnu.org/copyleft/gpl.html)
68 (2) Artistic License
69 (found at http://www.perl.com/pub/language/misc/Artistic.html)
70
72 Math::Vector
73
75 new
76
77 Returns a blessed array reference to cartesian point ($x, $y, $z),
78 where $z is optional. Note the feed-me-list, get-back-reference syntax
79 here. This is the opposite of the rest of the methods for a good rea‐
80 son (it allows nesting of function calls.)
81
82 The z value is optional, (and so are x and y.) Undefined values are
83 silently translated into zeros upon construction.
84
85 $vec = Math::Vec->new($x, $y, $z);
86
87 NewVec
88
89 This is simply a shortcut to Math::Vec->new($x, $y, $z) for those of
90 you who don't want to type so much so often. This also makes it easier
91 to nest / chain your function calls. Note that methods will typically
92 output lists (e.g. the answer to your question.) While you can simply
93 [bracket] the answer to make an array reference, you need that to be
94 blessed in order to use the $object->method(@args) syntax. This func‐
95 tion does that blessing.
96
97 This function is exported as an option. To use it, simply use
98 Math::Vec qw(NewVec); at the start of your code.
99
100 use Math::Vec qw(NewVec);
101 $vec = NewVec($x, $y, $z);
102 $diff = NewVec($vec->Minus([$ovec->ScalarMult(0.5)]));
103
105 These are all one-letter shortcuts which are imported to your namespace
106 with the :terse flag.
107
108 use Math::Vec qw(:terse);
109
110 V
111
112 This is the same as Math::Vec->new($x,$y,$z).
113
114 $vec = V($x, $y, $z);
115
116 U
117
118 Shortcut to V($x,$y,$z)->UnitVector()
119
120 $unit = U($x, $y, $z);
121
122 This will also work if called with a vector object:
123
124 $unit = U($vector);
125
126 X
127
128 Returns an x-axis unit vector.
129
130 $xvec = X();
131
132 Y
133
134 Returns a y-axis unit vector.
135
136 $yvec = Y();
137
138 Z
139
140 Returns a z-axis unit vector.
141
142 $zvec = Z();
143
145 Best used with the :terse functions, the Overloading scheme introduces
146 an interface which is unique from the Methods interface. Where the
147 methods take references and return lists, the overloaded operators will
148 return references. This allows vector arithmetic to be chained
149 together more easily. Of course, you can easily dereference these with
150 @{$vec}.
151
152 The following sections contain equivelant expressions from the longhand
153 and terse interfaces, respectively.
154
155 Negation:
156
157 @a = NewVec->(0,1,1)->ScalarMult(-1);
158 @a = @{-V(0,1,1)};
159
160 Stringification:
161
162 This also performs concatenation and other string operations.
163
164 print join(", ", 0,1,1), "\n";
165
166 print V(0,1,1), "\n";
167
168 $v = V(0,1,1);
169 print "$v\n";
170 print "$v" . "\n";
171 print $v, "\n";
172
173 Addition:
174
175 @a = NewVec(0,1,1)->Plus([2,2]);
176
177 @a = @{V(0,1,1) + V(2,2)};
178
179 # only one argument needs to be blessed:
180 @a = @{V(0,1,1) + [2,2]};
181
182 # and which one is blessed doesn't matter:
183 @a = @{[0,1,1] + V(2,2)};
184
185 Subtraction:
186
187 @a = NewVec(0,1,1)->Minus([2,2]);
188
189 @a = @{[0,1,1] - V(2,2)};
190
191 Scalar Multiplication:
192
193 @a = NewVec(0,1,1)->ScalarMult(2);
194
195 @a = @{V(0,1,1) * 2};
196
197 @a = @{2 * V(0,1,1)};
198
199 Scalar Division:
200
201 @a = NewVec(0,1,1)->ScalarMult(1/2);
202
203 # order matters!
204 @a = @{V(0,1,1) / 2};
205
206 Cross Product:
207
208 @a = NewVec(0,1,1)->Cross([0,1]);
209
210 @a = @{V(0,1,1) x [0,1]};
211
212 @a = @{[0,1,1] x V(0,1)};
213
214 Dot Product:
215
216 Also known as the "Scalar Product".
217
218 $a = NewVec(0,1,1)->Dot([0,1]);
219
220 $a = V(0,1,1) * [0,1];
221
222 Note: Not using the '.' operator here makes everything more efficient.
223 I know, the * is not a dot, but at least it's a mathematical operator
224 (perl does some implied string concatenation somewhere which drove me
225 to avoid the dot.)
226
227 Comparison:
228
229 The == and != operators will compare vectors for equal direction and
230 magnitude. No attempt is made to apply tolerance to this equality.
231
232 Length:
233
234 $a = NewVec(0,1,1)->Length();
235
236 $a = abs(V(0,1,1));
237
238 Vector Projection:
239
240 This one is a little different. Where the method is written
241 $a->Proj($b) to give the projection of $b onto $a, this reads like you
242 would say it (b projected onto a): $b>>$a.
243
244 @a = NewVec(0,1,1)->Proj([0,0,1]);
245
246 @a = @{V(0,0,1)>>[0,1,1]};
247
249 The above examples simply show how to go from the method interface to
250 the overloaded interface, but where the overloading really shines is in
251 chaining multiple operations together. Because the return values from
252 the overloaded operators are all references, you dereference them only
253 when you are done.
254
255 Unit Vector left of a line
256
257 This comes from the CAD::Calc::line_to_rectangle() function.
258
259 use Math::Vec qw(:terse);
260 @line = ([0,1],[1,0]);
261 my ($a, $b) = map({V(@$_)} @line);
262 $unit = U($b - $a);
263 $left = $unit x -Z();
264
265 Length of a cross product
266
267 $length = abs($va x $vb);
268
269 Vectors as coordinate axes
270
271 This is useful in drawing eliptical arcs using dxf data.
272
273 $val = 3.14159; # the 'start parameter'
274 @c = (14.15973317961194, 6.29684276451746); # codes 10, 20, 30
275 @e = (6.146127847120538, 0); # codes 11, 21, 31
276 @ep = @{V(@c) + \@e}; # that's the axis endpoint
277 $ux = U(@e); # unit on our x' axis
278 $uy = U($ux x -Z()); # y' is left of x'
279 $center = V(@c);
280 # autodesk gives you this:
281 @pt = ($a * cos($val), $b * sin($val));
282 # but they don't tell you about the major/minor axis issue:
283 @pt = @{$center + $ux * $pt[0] + $uy * $pt[1]};;
284
286 The operator precedence is going to be whatever perl wants it to be. I
287 have not yet investigated this to see if it matches standard vector
288 arithmetic notation. If in doubt, use parentheses.
289
290 One item of note here is that the 'x' and '*' operators have the same
291 precedence, so the leftmost wins. In the following example, you can
292 get away without parentheses if you have the cross-product first.
293
294 # dot product of a cross product:
295 $v1 x $v2 * $v3
296 ($v1 x $v2) * $v3
297
298 # scalar crossed with a vector (illegal!)
299 $v3 * $v1 x $v2
300
302 The typical theme is that methods require array references and return
303 lists. This means that you can choose whether to create an anonymous
304 array ref for use in feeding back into another function call, or you
305 can simply use the list as-is. Methods which return a scalar or list
306 of scalars (in the mathematical sense, not the Perl SV sense) are
307 exempt from this theme, but methods which return what could become one
308 vector will return it as a list.
309
310 If you want to chain calls together, either use the NewVec constructor,
311 or enclose the call in square brackets to make an anonymous array out
312 of the result.
313
314 my $vec = NewVec(@pt);
315 my $doubled = NewVec($vec->ScalarMult(0.5));
316 my $other = NewVec($vec->Plus([0,2,1], [4,2,3]));
317 my @result = $other->Minus($doubled);
318 $unit = NewVec(NewVec(@result)->UnitVector());
319
320 The vector objects are simply blessed array references. This makes for
321 a fairly limited amount of manipulation, but vector math is not compli‐
322 cated stuff. Hopefully, you can save at least two lines of code per
323 calculation using this module.
324
325 Dot
326
327 Returns the dot product of $vec 'dot' $othervec.
328
329 $vec->Dot($othervec);
330
331 DotProduct
332
333 Alias to Dot()
334
335 $number = $vec->DotProduct($othervec);
336
337 Cross
338
339 Returns $vec x $other_vec
340
341 @list = $vec->Cross($other_vec);
342 # or, to use the result as a vec:
343 $cvec = NewVec($vec->Cross($other_vec));
344
345 CrossProduct
346
347 Alias to Cross() (should really strip out all of this clunkiness and go
348 to operator overloading, but that gets into other hairiness.)
349
350 $vec->CrossProduct();
351
352 Length
353
354 Returns the length of $vec
355
356 $length = $vec->Length();
357
358 Magnitude
359
360 $vec->Magnitude();
361
362 UnitVector
363
364 $vec->UnitVector();
365
366 ScalarMult
367
368 Factors each element of $vec by $factor.
369
370 @new = $vec->ScalarMult($factor);
371
372 Minus
373
374 Subtracts an arbitrary number of vectors.
375
376 @result = $vec->Minus($other_vec, $another_vec?);
377
378 This would be equivelant to:
379
380 @result = $vec->Minus([$other_vec->Plus(@list_of_vectors)]);
381
382 VecSub
383
384 Alias to Minus()
385
386 $vec->VecSub();
387
388 InnerAngle
389
390 Returns the acute angle (in radians) in the plane defined by the two
391 vectors.
392
393 $vec->InnerAngle($other_vec);
394
395 DirAngles
396
397 $vec->DirAngles();
398
399 Plus
400
401 Adds an arbitrary number of vectors.
402
403 @result = $vec->Plus($other_vec, $another_vec);
404
405 PlanarAngles
406
407 If called in list context, returns the angle of the vector in each of
408 the primary planes. If called in scalar context, returns only the
409 angle in the xy plane. Angles are returned in radians counter-clock‐
410 wise from the primary axis (the one listed first in the pairs below.)
411
412 ($xy_ang, $xz_ang, $yz_ang) = $vec->PlanarAngles();
413
414 Ang
415
416 A simpler alias to PlanarAngles() which eliminates the concerns about
417 context and simply returns the angle in the xy plane.
418
419 $xy_ang = $vec->Ang();
420
421 VecAdd
422
423 $vec->VecAdd();
424
425 UnitVectorPoints
426
427 Returns a unit vector which points from $A to $B.
428
429 $A->UnitVectorPoints($B);
430
431 InnerAnglePoints
432
433 Returns the InnerAngle() between the three points. $Vert is the vertex
434 of the points.
435
436 $Vert->InnerAnglePoints($endA, $endB);
437
438 PlaneUnitNormal
439
440 Returns a unit vector normal to the plane described by the three
441 points. The sense of this vector is according to the right-hand rule
442 and the order of the given points. The $Vert vector is taken as the
443 vertex of the three points. e.g. if $Vert is the origin of a coordi‐
444 nate system where the x-axis is $A and the y-axis is $B, then the
445 return value would be a unit vector along the positive z-axis.
446
447 $Vert->PlaneUnitNormal($A, $B);
448
449 TriAreaPoints
450
451 Returns the angle of the triangle formed by the three points.
452
453 $A->TriAreaPoints($B, $C);
454
455 Comp
456
457 Returns the scalar projection of $B onto $A (also called the component
458 of $B along $A.)
459
460 $A->Comp($B);
461
462 Proj
463
464 Returns the vector projection of $B onto $A.
465
466 $A->Proj($B);
467
468 PerpFoot
469
470 Returns a point on line $A,$B which is as close to $pt as possible (and
471 therefore perpendicular to the line.)
472
473 $pt->PerpFoot($A, $B);
474
476 The following have yet to be translated into this interface. They are
477 shown here simply because I intended to fully preserve the function
478 names from the original Math::Vector module written by Wayne M. Syvin‐
479 ski.
480
481 TripleProduct
482
483 $vec->TripleProduct();
484
485 IJK
486
487 $vec->IJK();
488
489 OrdTrip
490
491 $vec->OrdTrip();
492
493 STV
494
495 $vec->STV();
496
497 Equil
498
499 $vec->Equil();
500
501
502
503perl v5.8.8 2007-05-05 Math::Vec(3)