Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Math::Vec(3)	      User Contributed Perl Documentation	  Math::Vec(3)

       Math::Vec - Object-Oriented Vector Math Methods in Perl

	 use Math::Vec;
	 $v = Math::Vec->new(0,1,2);


	 use Math::Vec qw(NewVec);
	 $v = NewVec(0,1,2);
	 @res =	$v->Cross([1,2.5,0]);
	 $p = NewVec(@res);
	 $q = $p->Dot([0,1,0]);


	 use Math::Vec qw(:terse);
	 $v = V(0,1,2);
	 $q = ($v x [1,2.5,0]) * [0,1,0];

       This module is still somewhat incomplete.  If a function	does nothing,
       there is	likely a really	good reason.  Please have a look at the	code
       if you are trying to use	this in	a production environment.

       Eric L. Wilhelm <ewilhelm at cpan dot org>

       This module was adapted from Math::Vector, written by Wayne M.

       It uses most of the same	algorithms, and	currently preserves the	same
       names as	the original functions,	though some aliases have been added to
       make the	interface more natural (at least to the	way I think.)

       The "object" for	the object oriented calling style is a blessed array
       reference which contains	a vector of the	form [x,y,z].  Methods will
       typically return	a list.

       Copyright (C) 2003-2006 Eric Wilhelm

       portions	Copyright 2003 Wayne M.	Syvinski

       Absolutely, positively NO WARRANTY, neither express or implied, is
       offered with this software.  You	use this software at your own risk.
       In case of loss,	neither	Wayne M. Syvinski, Eric	Wilhelm, nor anyone
       else, owes you anything whatseover.  You	have been warned.

       Note that this includes NO GUARANTEE of MATHEMATICAL CORRECTNESS.  If
       you are going to	use this code in a production environment, it is YOUR
       RESPONSIBILITY to verify	that the methods return	the correct values.

       You may use this	software under one of the following licenses:

	 (1) GNU General Public	License
	   (found at
	 (2) Artistic License
	   (found at


       Returns a blessed array reference to cartesian point ($x, $y, $z),
       where $z	is optional.  Note the feed-me-list, get-back-reference	syntax
       here.  This is the opposite of the rest of the methods for a good
       reason (it allows nesting of function calls.)

       The z value is optional,	(and so	are x and y.)  Undefined values	are
       silently	translated into	zeros upon construction.

	 $vec =	Math::Vec->new($x, $y, $z);

       This is simply a	shortcut to Math::Vec->new($x, $y, $z) for those of
       you who don't want to type so much so often.  This also makes it	easier
       to nest / chain your function calls.  Note that methods will typically
       output lists (e.g. the answer to	your question.)	 While you can simply
       [bracket] the answer to make an array reference,	you need that to be
       blessed in order	to use the $object->method(@args) syntax.  This
       function	does that blessing.

       This function is	exported as an option.	To use it, simply use
       Math::Vec qw(NewVec); at	the start of your code.

	 use Math::Vec qw(NewVec);
	 $vec =	NewVec($x, $y, $z);
	 $diff = NewVec($vec->Minus([$ovec->ScalarMult(0.5)]));

Terse Functions
       These are all one-letter	shortcuts which	are imported to	your namespace
       with the	:terse flag.

	 use Math::Vec qw(:terse);

       This is the same	as Math::Vec->new($x,$y,$z).

	 $vec =	V($x, $y, $z);

       Shortcut	to V($x,$y,$z)->UnitVector()

	 $unit = U($x, $y, $z);

       This will also work if called with a vector object:

	 $unit = U($vector);

       Returns an x-axis unit vector.

	 $xvec = X();

       Returns a y-axis	unit vector.

	 $yvec = Y();

       Returns a z-axis	unit vector.

	 $zvec = Z();

       Best used with the :terse functions, the	Overloading scheme introduces
       an interface which is unique from the Methods interface.	 Where the
       methods take references and return lists, the overloaded	operators will
       return references.  This	allows vector arithmetic to be chained
       together	more easily.  Of course, you can easily	dereference these with

       The following sections contain equivelant expressions from the longhand
       and terse interfaces, respectively.

	 @a = NewVec->(0,1,1)->ScalarMult(-1);
	 @a = @{-V(0,1,1)};

       This also performs concatenation	and other string operations.

	 print join(", ", 0,1,1), "\n";

	 print V(0,1,1), "\n";

	 $v = V(0,1,1);
	 print "$v\n";
	 print "$v" . "\n";
	 print $v, "\n";

	 @a = NewVec(0,1,1)->Plus([2,2]);

	 @a = @{V(0,1,1) + V(2,2)};

	 # only	one argument needs to be blessed:
	 @a = @{V(0,1,1) + [2,2]};

	 # and which one is blessed doesn't matter:
	 @a = @{[0,1,1]	+ V(2,2)};

	 @a = NewVec(0,1,1)->Minus([2,2]);

	 @a = @{[0,1,1]	- V(2,2)};

   Scalar Multiplication:
	 @a = NewVec(0,1,1)->ScalarMult(2);

	 @a = @{V(0,1,1) * 2};

	 @a = @{2 * V(0,1,1)};

   Scalar Division:
	 @a = NewVec(0,1,1)->ScalarMult(1/2);

	 # order matters!
	 @a = @{V(0,1,1) / 2};

   Cross Product:
	 @a = NewVec(0,1,1)->Cross([0,1]);

	 @a = @{V(0,1,1) x [0,1]};

	 @a = @{[0,1,1]	x V(0,1)};

   Dot Product:
       Also known as the "Scalar Product".

	 $a = NewVec(0,1,1)->Dot([0,1]);

	 $a = V(0,1,1) * [0,1];

       Note:  Not using	the '.'	operator here makes everything more efficient.
       I know, the * is	not a dot, but at least	it's a mathematical operator
       (perl does some implied string concatenation somewhere which drove me
       to avoid	the dot.)

       The == and != operators will compare vectors for	equal direction	and
       magnitude.  No attempt is made to apply tolerance to this equality.

	 $a = NewVec(0,1,1)->Length();

	 $a = abs(V(0,1,1));

   Vector Projection:
       This one	is a little different.	Where the method is written
       $a->Proj($b) to give the	projection of $b onto $a, this reads like you
       would say it (b projected onto a):  $b>>$a.

	 @a = NewVec(0,1,1)->Proj([0,0,1]);

	 @a = @{V(0,0,1)>>[0,1,1]};

Chaining Operations
       The above examples simply show how to go	from the method	interface to
       the overloaded interface, but where the overloading really shines is in
       chaining	multiple operations together.  Because the return values from
       the overloaded operators	are all	references, you	dereference them only
       when you	are done.

   Unit	Vector left of a line
       This comes from the CAD::Calc::line_to_rectangle() function.

	 use Math::Vec qw(:terse);
	 @line = ([0,1],[1,0]);
	 my ($a, $b) = map({V(@$_)} @line);
	 $unit = U($b -	$a);
	 $left = $unit x -Z();

   Length of a cross product
	 $length = abs($va x $vb);

   Vectors as coordinate axes
       This is useful in drawing eliptical arcs	using dxf data.

	 $val =	3.14159;			     # the 'start parameter'
	 @c = (14.15973317961194, 6.29684276451746); # codes 10, 20, 30
	 @e = (6.146127847120538, 0);		     # codes 11, 21, 31
	 @ep = @{V(@c) + \@e};			     # that's the axis endpoint
	 $ux = U(@e);				     # unit on our x' axis
	 $uy = U($ux x -Z());			    # y' is left of x'
	 $center = V(@c);
	 # autodesk gives you this:
	 @pt = ($a * cos($val),	$b * sin($val));
	 # but they don't tell you about the major/minor axis issue:
	 @pt = @{$center + $ux * $pt[0]	+ $uy *	$pt[1]};;

       The operator precedence is going	to be whatever perl wants it to	be.  I
       have not	yet investigated this to see if	it matches standard vector
       arithmetic notation.  If	in doubt, use parentheses.

       One item	of note	here is	that the 'x' and '*' operators have the	same
       precedence, so the leftmost wins.  In the following example, you	can
       get away	without	parentheses if you have	the cross-product first.

	 # dot product of a cross product:
	 $v1 x $v2 * $v3
	 ($v1 x	$v2) * $v3

	 # scalar crossed with a vector	(illegal!)
	 $v3 * $v1 x $v2

       The typical theme is that methods require array references and return
       lists.  This means that you can choose whether to create	an anonymous
       array ref for use in feeding back into another function call, or	you
       can simply use the list as-is.  Methods which return a scalar or	list
       of scalars (in the mathematical sense, not the Perl SV sense) are
       exempt from this	theme, but methods which return	what could become one
       vector will return it as	a list.

       If you want to chain calls together, either use the NewVec constructor,
       or enclose the call in square brackets to make an anonymous array out
       of the result.

	 my $vec = NewVec(@pt);
	 my $doubled = NewVec($vec->ScalarMult(0.5));
	 my $other = NewVec($vec->Plus([0,2,1],	[4,2,3]));
	 my @result = $other->Minus($doubled);
	 $unit = NewVec(NewVec(@result)->UnitVector());

       The vector objects are simply blessed array references.	This makes for
       a fairly	limited	amount of manipulation,	but vector math	is not
       complicated stuff.  Hopefully, you can save at least two	lines of code
       per calculation using this module.

       Returns the dot product of $vec 'dot' $othervec.


       Alias to	Dot()

	 $number = $vec->DotProduct($othervec);

       Returns $vec x $other_vec

	 @list = $vec->Cross($other_vec);
	 # or, to use the result as a vec:
	 $cvec = NewVec($vec->Cross($other_vec));

       Alias to	Cross()	(should	really strip out all of	this clunkiness	and go
       to operator overloading,	but that gets into other hairiness.)


       Returns the length of $vec

	 $length = $vec->Length();



       Factors each element of $vec by $factor.

	 @new =	$vec->ScalarMult($factor);

       Subtracts an arbitrary number of	vectors.

	 @result = $vec->Minus($other_vec, $another_vec?);

       This would be equivelant	to:

	 @result = $vec->Minus([$other_vec->Plus(@list_of_vectors)]);

       Alias to	Minus()


       Returns the acute angle (in radians) in the plane defined by the	two



       Adds an arbitrary number	of vectors.

	 @result = $vec->Plus($other_vec, $another_vec);

       If called in list context, returns the angle of the vector in each of
       the primary planes.  If called in scalar	context, returns only the
       angle in	the xy plane.  Angles are returned in radians counter-
       clockwise from the primary axis (the one	listed first in	the pairs

	 ($xy_ang, $xz_ang, $yz_ang) = $vec->PlanarAngles();

       A simpler alias to PlanarAngles() which eliminates the concerns about
       context and simply returns the angle in the xy plane.

	 $xy_ang = $vec->Ang();


       Returns a unit vector which points from $A to $B.


       Returns the InnerAngle()	between	the three points.  $Vert is the	vertex
       of the points.

	 $Vert->InnerAnglePoints($endA,	$endB);

       Returns a unit vector normal to the plane described by the three
       points.	The sense of this vector is according to the right-hand	rule
       and the order of	the given points.  The $Vert vector is taken as	the
       vertex of the three points.  e.g. if $Vert is the origin	of a
       coordinate system where the x-axis is $A	and the	y-axis is $B, then the
       return value would be a unit vector along the positive z-axis.

	 $Vert->PlaneUnitNormal($A, $B);

       Returns the angle of the	triangle formed	by the three points.

	 $A->TriAreaPoints($B, $C);

       Returns the scalar projection of	$B onto	$A (also called	the component
       of $B along $A.)


       Returns the vector projection of	$B onto	$A.


       Returns a point on line $A,$B which is as close to $pt as possible (and
       therefore perpendicular to the line.)

	 $pt->PerpFoot($A, $B);

Incomplete Methods
       The following have yet to be translated into this interface.  They are
       shown here simply because I intended to fully preserve the function
       names from the original Math::Vector module written by Wayne M.






perl v5.24.1			  2017-07-02			  Math::Vec(3)

NAME | SYNOPSIS | NOTICE | AUTHOR | DESCRIPTION | COPYRIGHT NOTICE | NO WARRANTY | LICENSE | SEE ALSO | Constructor | Terse Functions | Overloading | Chaining Operations | Precedence | Methods | Incomplete Methods

Want to link to this manual page? Use this URL:

home | help