# Vector2

Manipulate 2D vectors

## Synopsis

Example t/vector2.t

`````` #_ Vector _____________________________________________________________
# Test 2d vectors
#______________________________________________________________________

use Math::Zap::Vector2 vector2=>v, units=>u;
use Test::Simple tests=>7;

my (\$x, \$y) = u();

ok(!\$x                    == 1);
ok(2*\$x+3*\$y              == v( 2,  3));
ok(-\$x-\$y                 == v(-1, -1));
ok((2*\$x+3*\$y) + (-\$x-\$y) == v( 1,  2));
ok((2*\$x+3*\$y) * (-\$x-\$y) == -5);
ok(\$x*2                   == v( 2,  0));
ok(\$y/2                   == v( 0,  0.5));
``````

## Description

Manipulate 2D vectors

`````` package Math::Zap::Vector2;
\$VERSION=1.07;
use Math::Trig;
use Carp;
use constant debug => 0; # Debugging level

``````

## Constructors

### new

Create a vector from numbers

`````` sub new(\$\$)
{return bless {x=>\$_[0], y=>\$_[1]} unless debug;
my (\$x, \$y) = @_;
round(bless({x=>\$x, y=>\$y}));
}

``````

### vector2

Create a vector from numbers - synonym for "new"

`````` sub vector2(\$\$) {new(\$_[0],\$_[1])}

``````

### units

Unit vectors

`````` \$x = new(1,0);
\$y = new(0,1);

sub units() {(\$x, \$y)}

``````

## Methods

### check

Check its a vector

`````` sub check(@)
{if (debug)
{for my \$v(@_)
{confess "\$v is not a vector2" unless ref(\$v) eq __PACKAGE__;
}
}
return (@_)
}

``````

### is

Test its a vector

`````` sub is(@)
{for my \$v(@_)
{return 0 unless ref(\$v) eq __PACKAGE__;
}
1;
}

``````

### accuracy

Get/Set accuracy for comparisons

`````` my \$accuracy = 1e-10;

sub accuracy
{return \$accuracy unless scalar(@_);
\$accuracy = shift();
}

``````

### round

Round: round to nearest integer if within accuracy of that integer

`````` sub round(\$)
{unless (debug)
{return \$_[0];
}
else
{my (\$a) = @_;
for my \$k(keys(%\$a))
{my \$n = \$a->{\$k};
my \$N = int(\$n);
\$a->{\$k} = \$N if abs(\$n-\$N) < \$accuracy;
}
return \$a;
}
}

``````

### components

x,y components of vector

`````` sub x(\$) {check(@_) if debug; \$_[0]->{x}}
sub y(\$) {check(@_) if debug; \$_[0]->{y}}

``````

### clone

Create a vector from another vector

`````` sub clone(\$)
{my (\$v) = check(@_); # Vectors
round bless {x=>\$v->x, y=>\$v->y};
}

``````

### length

Length of a vector

`````` sub length(\$)
{check(@_[0..0]) if debug; # Vectors
sqrt(\$_[0]->{x}**2+\$_[0]->{y}**2);
}

``````

### print

Print vector

`````` sub print(\$)
{my (\$v) = check(@_); # Vectors
my (\$x, \$y) = (\$v->x, \$v->y);

"vector2(\$x, \$y)";
}

``````

### normalize

Normalize vector

`````` sub norm(\$)
{my (\$v) = check(@_); # Vectors
my \$l = \$v->length;

\$l > 0 or confess "Cannot normalize zero length vector \$v";

new(\$v->x / \$l, \$v->y / \$l);
}

``````

### rightAngle

At right angles

`````` sub rightAngle(\$)
{my (\$v) = check(@_); # Vectors
new(-\$v->y, \$v->x);
}

``````

### dot

Dot product

`````` sub dot(\$\$)
{my (\$a, \$b) = check(@_); # Vectors
\$a->x*\$b->x+\$a->y*\$b->y;
}

``````

### angle

Angle between two vectors

`````` sub angle(\$\$)
{my (\$a, \$b) = check(@_); # Vectors
acos(\$a->norm->dot(\$b->norm));
}

``````

`````` sub add(\$\$)
{my (\$a, \$b) = check(@_); # Vectors
new(\$a->x+\$b->x, \$a->y+\$b->y);
}

``````

### subtract

Subtract vectors

`````` sub subtract(\$\$)
{check(@_) if debug; # Vectors
new(\$_[0]->{x}-\$_[1]->{x}, \$_[0]->{y}-\$_[1]->{y});
}

``````

### multiply

Vector times a scalar

`````` sub multiply(\$\$)
{my (\$a) = check(@_[0..0]); # Vector
my (\$b) =       @_[1..1];  # Scalar

confess "\$b is not a scalar" if ref(\$b);
new(\$a->x*\$b, \$a->y*\$b);
}

``````

### divide

Vector divided by a non zero scalar

`````` sub divide(\$\$)
{my (\$a) = check(@_[0..0]); # Vector
my (\$b) =       @_[1..1];  # Scalar

confess "\$b is not a scalar" if ref(\$b);
confess "\$b is zero"         if \$b == 0;
new(\$a->x/\$b, \$a->y/\$b);
}

``````

### equals

Equals to within accuracy

`````` sub equals(\$\$)
{my (\$a, \$b) = check(@_); # Vectors
abs(\$a->x-\$b->x) < \$accuracy and
abs(\$a->y-\$b->y) < \$accuracy;
}

``````

## Operators

`````` use overload
'-'        => \&subtract3, # Subtract one vector from another
'*'        => \&multiply3, # Times by a scalar, or vector dot product
'/'        => \&divide3,   # Divide by a scalar
'<'        => \&angle3,    # Angle in radians between two vectors
'>'        => \&angle3,    # Angle in radians between two vectors
'=='       => \&equals3,   # Equals
'""'       => \&print3,    # Print
'!'        => \&length,    # Length
'fallback' => FALSE;

``````

`````` sub add3
{my (\$a, \$b) = @_;
}

``````

### subtract

Subtract operator.

`````` sub subtract3
{#my (\$a, \$b, \$c) = @_;
#return \$a->subtract(\$b) if ref(\$b);
return new(\$_[0]->{x}-\$_[1]->{x}, \$_[0]->{y}-\$_[1]->{y}) if ref(\$_[1]);
new(-\$_[0]->{x}, -\$_[0]->{y});
}

``````

### multiply

Multiply operator.

`````` sub multiply3
{my (\$a, \$b) = @_;
return \$a->dot     (\$b) if ref(\$b);
return \$a->multiply(\$b);
}

``````

### divide

Divide operator.

`````` sub divide3
{my (\$a, \$b, \$c) = @_;
return \$a->divide(\$b);
}

``````

### angle

Angle between two vectors.

`````` sub angle3
{my (\$a, \$b, \$c) = @_;
return \$a->angle(\$b);
}

``````

### equals

Equals operator.

`````` sub equals3
{my (\$a, \$b, \$c) = @_;
return \$a->equals(\$b);
}

``````

### print

Print a vector.

`````` sub print3
{my (\$a) = @_;
return \$a->print;
}

``````

## Exports

Export "vector2", "units", "check", "is"

`````` use Math::Zap::Exports qw(
vector2 (\$\$)
units   ()
check   (@)
is      (@)
);

#_ Vector2 ____________________________________________________________
#______________________________________________________________________

1;

``````

## Credits

### Author

philiprbrenan@yahoo.com

philiprbrenan@yahoo.com, 2004