class Vector {
has Real $.x;
has Real $.y;
multi submethod BUILD (:$!x!, :$!y!) {
*
}
multi submethod BUILD (:$length!, :$angle!) {
$!x = $length * cos $angle;
$!y = $length * sin $angle;
}
multi submethod BUILD (:from([$x1, $y1])!, :to([$x2, $y2])!) {
$!x = $x2 - $x1;
$!y = $y2 - $y1;
}
method length { sqrt $.x ** 2 + $.y ** 2 }
method angle { atan2 $.y, $.x }
method add ($v) { Vector.new(x => $.x + $v.x, y => $.y + $v.y) }
method subtract ($v) { Vector.new(x => $.x - $v.x, y => $.y - $v.y) }
method multiply ($n) { Vector.new(x => $.x * $n, y => $.y * $n ) }
method divide ($n) { Vector.new(x => $.x / $n, y => $.y / $n ) }
method gist { "vec[$.x, $.y]" }
}
multi infix:<+> (Vector $v, Vector $w) is export { $v.add: $w }
multi infix:<-> (Vector $v, Vector $w) is export { $v.subtract: $w }
multi prefix:<-> (Vector $v) is export { $v.multiply: -1 }
multi infix:<*> (Vector $v, $n) is export { $v.multiply: $n }
multi infix:</> (Vector $v, $n) is export { $v.divide: $n }
#####[ Usage example: ]#####
say my $u = Vector.new(x => 3, y => 4); #: vec[3, 4]
say my $v = Vector.new(from => [1, 0], to => [2, 3]); #: vec[1, 3]
say my $w = Vector.new(length => 1, angle => pi/4);
say $u.length;
say $u.angle * 180/pi;
say $u + $v;
say $u - $v;
say -$u;
say $u * 10;
say $u / 2;