Games::RailRoad::Vector - an opaque vector class.


Games-RailRoad documentation Contained in the Games-RailRoad distribution.

Index


Code Index:

NAME

Top

Games::RailRoad::Vector - an opaque vector class.

VERSION

Top

version 1.101330

SYNOPSIS

Top

    my $v1 = Games::RailRoad::Vector->new( \%params );

DESCRIPTION

Top

This class abstracts basic vector manipulation. It lets you pass around one argument to your functions, do vector arithmetic and various string representation.

ATTRIBUTES

Top

posx

The x coordinate of the vector. Default to 0.

posy

The y coordinate of the vector. Default to 0.

METHODS

Top

my $vec = GR::Vector->new( \%params );

Create and return a new vector. Accept a hash reference with the attribute values.

my $vec = GR::Vector->new_dir( $dir );

Create a new vector, from a given direction. The recognized directions are e, n, ne, nw, s, se, sw, w.

my $vec = $v->copy;

Return a new GRV object, which has the same coordinates as $v.

PUBLIC METHODS

Top

my $str = $vec->as_string;

Return the stringified form of $vec. For instance, a Befunge vector might look like (1,2).

This method is also applied to stringification, ie when one forces string context ("$vec").

my $str = $vec->as_dir;

Return the cardinal direction (n, sw, etc.) of $vec if it's a unit vector (ok, (1,1) is not a unit vector but you see my point).

MATHEMATICAL OPERATIONS

Top

Standard operations

One can do some maths on the vectors. Addition and substraction work as expected:

    my $v = $v1 + $v2;
    my $v = $v1 - $v2;

Either operation return a new GRV object, which is the result of $v1 plus / minus $v2.

The inversion is also supported: my $v2 = -$v1;

will subtracts $v1 from the origin, and effectively, gives the inverse of the original vector. The new vector is the same distance from the origin, in the opposite direction.

Inplace operations

GRV objects also supports inplace mathematical operations:

    $v1 += $v2;
    $v1 -= $v2;

effectively adds / substracts $v2 to / from $v1, and stores the result back into $v1.

Comparison

Finally, GRV objects can be tested for equality, ie whether two vectors both point at the same spot.

    print "same"   if $v1 == $v2;
    print "differ" if $v1 != $v2;

AUTHOR

Top

  Jerome Quelin

COPYRIGHT AND LICENSE

Top


Games-RailRoad documentation Contained in the Games-RailRoad distribution.

# 
# This file is part of Games-RailRoad
# 
# This software is copyright (c) 2008 by Jerome Quelin.
# 
# This is free software; you can redistribute it and/or modify it under
# the same terms as the Perl 5 programming language system itself.
# 
use 5.010;
use strict;
use warnings;

package Games::RailRoad::Vector;
BEGIN {
  $Games::RailRoad::Vector::VERSION = '1.101330';
}
# ABSTRACT: an opaque vector class.

use Moose;
use MooseX::Has::Sugar;
use MooseX::SemiAffordanceAccessor;
use Readonly;

use overload
    '='   => \&copy,
    '+'   => \&_add,
    '-'   => \&_substract,
    'neg' => \&_invert,
    '+='  => \&_add_inplace,
    '-='  => \&_substract_inplace,
    '<=>' => \&_compare,
    '""'  => \&as_string;



# -- attributes


has posx => ( rw, isa=>'Int', default=>0 );
has posy => ( rw, isa=>'Int', default=>0 );


# -- private vars

Readonly my %coords2dir => (
    '(-1,-1)' => 'nw',
    '(-1,0)'  => 'w',
    '(-1,1)'  => 'sw',
    '(0,-1)'  => 'n',
    '(0,1)'   => 's',
    '(1,-1)'  => 'ne',
    '(1,0)'   => 'e',
    '(1,1)'   => 'se',
);
Readonly my %dir2coords => (
    'nw' => [-1,-1],
    'w'  => [-1, 0],
    'sw' => [-1, 1],
    'n'  => [ 0,-1],
    's'  => [ 0, 1],
    'ne' => [ 1,-1],
    'e'  => [ 1, 0],
    'se' => [ 1, 1],
);


# -- constructors & initializers


# provided by moose



sub new_dir {
    my ($pkg, $dir) = @_;
    my ($x, $y) = @{ $dir2coords{$dir} };
    return $pkg->new( { posx=>$x, posy=>$y } );
}



sub copy {
    my $vec = shift;
    return bless {%$vec}, ref $vec;
}


# -- PUBLIC METHODS

#- accessors

#
# my $str = $vec->as_string;
# my $str = "$vec";
#
# Return the stringified form of $vec. For instance, a vector might look
# like "(1,2)".
#
sub as_string {
    my $self = shift;
    return '(' . $self->posx . ',' . $self->posy . ')';
}


#
# my $str = $vec->as_dir;
#
# Return the cardinal direction (n, sw, etc.) of $vec if it's a unit
# vector (ok, (1,1) is not a unit vector but you see my point).
#
sub as_dir {
    my $self = shift;
    return $coords2dir{"$self"};
}


# -- PRIVATE METHODS

#- math ops

#
# my $vec = $v1->_add($v2);
# my $vec = $v1 + $v2;
#
# Return a new GRV object, which is the result of $v1 plus $v2.
#
sub _add {
    my ($v1, $v2) = @_;
    my $rv = ref($v1)->new;
    $rv->set_posx( $v1->posx + $v2->posx );
    $rv->set_posy( $v1->posy + $v2->posy );
    return $rv;
}


#
# my $vec = $v1->_substract($v2);
# my $vec = $v1 - $v2;
#
# Return a new GRV object, which is the result of $v1 minus $v2.
#
sub _substract {
    my ($v1, $v2) = @_;
    my $rv = ref($v1)->new;
    $rv->set_posx( $v1->posx - $v2->posx );
    $rv->set_posy( $v1->posy - $v2->posy );
    return $rv;
}


 
#
# my $v2 = $v1->_invert;
# my $v2 = -$v1;
#
# Subtract $v1 from the origin. Effectively, gives the inverse of the
# original vector. The new vector is the same distance from the origin,
# in the opposite direction.
#
sub _invert {
    my ($v1) = @_;
    my $rv = ref($v1)->new;
    $rv->set_posx( - $v1->posx );
    $rv->set_posy( - $v1->posy );
    return $rv;
}


#- inplace math ops

#
# $v1->_add_inplace($v2);
# $v1 += $v2;
#
#
sub _add_inplace {
    my ($v1, $v2) = @_;
    $v1->set_posx( $v1->posx + $v2->posx );
    $v1->set_posy( $v1->posy + $v2->posy );
    return $v1;
}


#
# $v1->_substract_inplace($v2);
# $v1 -= $v2;
#
# Substract $v2 to $v1, and stores the result back into $v1.
#
sub _substract_inplace {
    my ($v1, $v2) = @_;
    $v1->set_posx( $v1->posx - $v2->posx );
    $v1->set_posy( $v1->posy - $v2->posy );
    return $v1;
}


#- comparison

#
# my $bool = $v1->_compare($v2);
# my $bool = $v1 <=> $v2;
#
# Check whether the vectors both point at the same spot. Return 0 if they
# do, 1 if they don't.
#
sub _compare {
    my ($v1, $v2) = @_;
    return 1 if $v1->posx != $v2->posx;
    return 1 if $v1->posy != $v2->posy;
    return 0;
}


1;



__END__