class MyVector(:args) {
has Number x
has Number y
method init {
if ([:x, :y] ~~ args) {
x = args{:x}
y = args{:y}
}
elsif ([:length, :angle] ~~ args) {
x = args{:length}*args{:angle}.cos
y = args{:length}*args{:angle}.sin
}
elsif ([:from, :to] ~~ args) {
x = args{:to}[0]-args{:from}[0]
y = args{:to}[1]-args{:from}[1]
}
else {
die "Invalid arguments: #{args}"
}
}
method length { hypot(x, y) }
method angle { atan2(y, x) }
method +(MyVector v) { MyVector(x => x + v.x, y => y + v.y) }
method -(MyVector v) { MyVector(x => x - v.x, y => y - v.y) }
method *(Number n) { MyVector(x => x * n, y => y * n) }
method /(Number n) { MyVector(x => x / n, y => y / n) }
method neg { self * -1 }
method to_s { "vec[#{x}, #{y}]" }
}
var u = MyVector(x => 3, y => 4)
var v = MyVector(from => [1, 0], to => [2, 3])
var w = MyVector(length => 1, angle => 45.deg2rad)
say u
say v
say w
say u.length
say u.angle.rad2deg
say u+v
say u-v
say -u
say u*10
say u/2