Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
#
# # An object oriented module for working with vectors. # Note that 'scalar' refers to the mathmatical definition, not Perl's +;) # package Math::Vector; use strict; use Carp; use Math::Trig; use vars qw($VERSION); $VERSION = '0.01'; use overload "=" => \&assign, "+=" => \&add_assign, "-=" => \&subtract_assign, "+" => \&add, "-" => \&subtract, "x" => \&cross_product, "." => \&dot_product, "*" => \&multiply_scalar, "/" => \&divide_scalar, "*=" => \&multiply_scalar_assign, "/=" => \&divide_scalar_assign; sub new { my ($package, %args) = @_; return bless { _i => $args{i} || 0, _j => $args{j} || 0, _k => $args{k} || 0, }, $package; } # $v_1 = $v_2; sub assign { my ($self, $other) = @_; carp ('Operation only permitted on Math::Vector objects') && retur +n undef unless (ref $other eq 'Math::Vector'); $self->set_i($other->i); $self->set_j($other->j); $self->set_k($other->k); return $self; } # $v_1 += $v_2; sub add_assign { my ($self, $other) = @_; carp ('Operation only permitted on Math::Vector objects') && retur +n undef unless (ref $other eq 'Math::Vector'); $self->set_i($other->i + $self->i); $self->set_j($other->j + $self->j); $self->set_k($other->k + $self->k); return $self; } # $v_1 -= $v_2; sub subtract_assign { my ($self, $other) = @_; carp ('Operation only permitted on Math::Vector objects') && retur +n undef unless (ref $other eq 'Math::Vector'); $self->set_i($other->i - $self->i); $self->set_j($other->j - $self->j); $self->set_k($other->k - $self->k); return $self; } # $v_new = $v_1 + $v_2; # $v_new = $v_1->add($v_2); sub add { my ($self, $other) = @_; carp ('Operation only permitted on Math::Vector objects') && retur +n undef unless (ref $other eq 'Math::Vector'); return new Math::Vector ( i => $self->i + $other->i, j => $self->j + $other->j, k => $self->k + $other->k, ); } # $v_new = $v_1 - $v_2; # $v_new = $v_1->subtract($v_2); sub subtract { my ($self, $other) = @_; carp ('Operation only permitted on Math::Vector objects') && retur +n undef unless (ref $other eq 'Math::Vector'); return new Math::Vector ( i => $self->i - $other->i, j => $self->j - $other->j, k => $self->k - $other->k, ); } # $v *= $scalar; sub multiply_scalar_assign { my ($self, $scalar) = @_; $self->set_i($self->i * $scalar); $self->set_j($self->j * $scalar); $self->set_k($self->k * $scalar); return $self; } # $v /= $scalar; sub divide_scalar_assign { my ($self, $scalar) = @_; carp ('Cannot divide by zero') && return undef unless ($scalar); $self->set_i($self->i / $scalar); $self->set_j($self->j / $scalar); $self->set_k($self->k / $scalar); return $self; } # $v_new = $v_1 * $scalar; # $v_new = $v_1->multiply_scalar($scalar); sub multiply_scalar { my ($self, $scalar) = @_; return new Math::Vector ( i => $self->i * $scalar, j => $self->j * $scalar, k => $self->k * $scalar, ); } # $v_new = $v_1 / $scalar; # $v_new = $v_1->divide_scalar($scalar); sub divide_scalar { my ($self, $scalar) = @_; carp ('Cannot divide by zero') && return undef unless ($scalar); return new Math::Vector ( i => $self->i / $scalar, j => $self->j / $scalar, k => $self->k / $scalar, ); } # $v_new = $v_1 x $v_2; # $v_new = $v_1->cross_product($v_2); sub cross_product { my ($self, $other) = @_; carp ('Operation only permitted on Math::Vector objects') && retur +n undef unless (ref $other eq 'Math::Vector'); return new Math::Vector ( i => $self->j * $other->k - $self->k * $other->j, j => $self->k * $other->i - $self->i * $other->k, z => $self->i * $other->j - $self->j * $other->i, ); } # $dot_product = $v_1 . $v_2; # $v_new = $v_1->dot_product($v_2); sub dot_product { my ($self, $other) = @_; carp ('Operation only permitted on Math::Vector objects') && retur +n undef unless (ref $other eq 'Math::Vector'); return $self->i * $other->i + $self->j * $other->j + $self->k * $o +ther->k; } # $magnitude = $v->magnitude(); sub magnitude { my $self = shift; return sqrt($self->i * $self->i + $self->j * $self->j + $self->k * + $self->k); } # Converts the vector to its normal # $v->normalize(); sub normalize { my $self = shift; my $m = $self->magnitude; carp('Cannot normalize a zero vector') && return undef unless ($m) +; $self->set_i( $self->i / $m ); $self->set_j( $self->j / $m ); $self->set_k( $self->k / $m ); } # $v_normalized = $v->normal(); sub normal { my $self = shift; my $normal = new Math::Vector (i=>$self->i, j=>$self->j, k=>$self- +>k); $normal->normalize(); return $normal; } # $angle_in_radians = $v_1->angle($v_2); sub angle { my ($self, $other) = @_; carp ('Operation only permitted on Math::Vector objects') && retur +n undef unless (ref $other eq 'Math::Vector'); my $self_m = $self->magnitude; my $other_m = $other->magnitude; carp('Vectors must be non-zero') && return undef unless ($self_m && $other_m); return (acos ( $self->dot_product($other) / ($self_m * $other_m) )); } sub orthogonal { my ($self, $other) = @_; carp ('Operation only permitted on Math::Vector objects') && retur +n undef unless (ref $other eq 'Math::Vector'); carp('Vectors must be non-zero') && return undef unless ($self->magnitude && $other->magnitude); # v1 is perpendicular to v2 if (v1 . v2 == 0) return ($self->dot_product($other) ? 0 : 1); } sub i { return $_[0]->{_i}; } sub j { return $_[0]->{_j}; } sub k { return $_[0]->{_k}; } sub set_i { my $self = shift; $self->{_i} = shift || 0; } sub set_j { my $self = shift; $self->{_j} = shift || 0; } sub set_k { my $self = shift; $self->{_k} = shift || 0; } 1; __END__ =head1 NAME Math::Vector - Object oriented vectors =head1 SYNOPSIS use Math::Vector; my $vector = new Math::Vector (i => $i, j => $j, k => $k); =head1 DESCRIPTION C<Math::Vector> provides an object oriented approach to working with v +ectors. Vectors created with this module are three-dimentional, although two-dimentional vectors are effectively achieved by omitting the 'k' c +omponent (which simply sets it to zero). It is important to note that this module will carp() if operations inv +olving division are attempted on zero values. A basic understanding of vecto +rs is expected, and the programmer should check the magnitude of a vector be +fore performing operations such as normalization or finding the angle. =head2 Conventions used in this document =over 10 The term 'scalar' is used in the mathmatical sense, and is a number re +presenting the amount by which a vector is scaled. Vector objects will always begin with a 'v'. (Example: $v, $v_1, $v_ne +w) =back =head1 OPERATORS C<Math::Vector> objects override many default operators. =item '=' $v_1 = $v_2; =item '+' $v_new = $v_1 + $v_2; =item '+=' $v_1 += $v_2 =item '-' $v_new = $v_1 - $v_2; =item '-=' $v_1 -= $v_2; =item 'x' $v_cross_product = $v_1 x $v_2; =item '.' $dot_product = $v_1 . $v_2; =item '*' $v_new = $v_1 * $scalar_multiple =item '*=' $v_1 *= $scalar_multiple; =item '/' $v_new = $v_1 / $scalar_multiple =item '/=' $v_1 /= $scalar_multiple; =head1 METHODS =head2 Creation =over 4 =item new Math::Vector (i => $i, j => $j, k => $k) Creates a new vector object with components ($i, $j, $k). =back =head2 Access =over 4 =item i Returns the value of the 'i' (first) component of the vector. =item j Returns the value of the 'j' (second) component of the vector. =item k Returns the value of the 'k' (third) component of the vector. =item ijk Returns a list of the three component values. This is included for co +nvenience, and is the same as: ($v->i, $v->j, $v->k); =back =head2 Direct Modifications =over 4 =item set_i (I) Sets the value for the 'i' component of the vector. $v->set_i($new_i_value) =item set_j (J) Sets the value for the 'j' component of the vector. $v->set_j($new_j_value) =item set_k (K) Sets the value for the 'k' component of the vector. $v->set_k($new_k_value) =back =head2 Calculations =over 4 =item dot_product (VECTOR) Returns the dot product of two vectors. $dot_product = $v_1->dot_product( $v_2 ); # Note this is equivalent: $dot_product = $v_1 . $v_2; =item cross_product (VECTOR) Returns the cross product of two vectors as a vector object. Note: yo +u cannot take the cross product of 2d vectors. $v_cross = $v_1->cross_product( $v_2 ); # Note this is equivalent: $v_cross = $v_1 x $v_2; =item magnitude Returns the magnitude of the vector. $magnitude = $v->magnitude; =item normalize Normalizes the vector. $v->normalize; =item normal Returns the normal of a vector as a new vector object. $v_normalized = $v->normal; # Note the following is similar, but does not preserve $v : $v->normalize; $v_normalized = $v; =item angle (VECTOR) Returns the angle in radians between two vectors. $angle = $v_1->angle( $v_2 ); =item orthogonal (VECTOR) Returns 1 if vectors are orthogonal (or perpendicular), 0 if they are not, and undef if either is a zero vector. $orthogonal = $v_1->orthogonal( $v_2 ); if ($orthogonal) { # $v_1 and $v_2 are perpendicular } elsif (defined $orthogonal) { # they are not } else { # you tried to test a zero vector } =back =head1 SEE ALSO Math::Trig, Carp =head1 BUGS Please email the author (E<lt>mark@sporkstorms.orgE<gt>) with any. =head1 FEEDBACK Feel free to email the author with any questions, comments, or request +s. This module was initially written for personal use, and may be lacking some desired features. I (Mark) would be glad to add anything to it that you might need. =head1 AUTHOR Mark Stratman, E<lt>mark@sporkstorms.orgE<gt> =head1 COPYRIGHT Copyright (c) 2001, Mark Stratman. All Rights Reserved. This modules is free software. It may be used, redistributed and/or modified under the same terms as Perl itself. =cut #

In reply to Math::Vector - request for comments by count0

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others contemplating the Monastery: (4)
    As of 2015-07-05 21:55 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









      Results (68 votes), past polls