vector.sf 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #!/usr/bin/ruby
  2. #
  3. ## https://rosettacode.org/wiki/Vector
  4. #
  5. class MyVector(:args) {
  6. has Number x
  7. has Number y
  8. method init {
  9. if ([:x, :y] ~~ args) {
  10. x = args{:x}
  11. y = args{:y}
  12. }
  13. elsif ([:length, :angle] ~~ args) {
  14. x = args{:length}*args{:angle}.cos
  15. y = args{:length}*args{:angle}.sin
  16. }
  17. elsif ([:from, :to] ~~ args) {
  18. x = args{:to}[0]-args{:from}[0]
  19. y = args{:to}[1]-args{:from}[1]
  20. }
  21. else {
  22. die "Invalid arguments: #{args}"
  23. }
  24. }
  25. method length { hypot(x, y) }
  26. method angle { atan2(y, x) }
  27. method +(MyVector v) { MyVector(x => x + v.x, y => y + v.y) }
  28. method -(MyVector v) { MyVector(x => x - v.x, y => y - v.y) }
  29. method *(Number n) { MyVector(x => x * n, y => y * n) }
  30. method /(Number n) { MyVector(x => x / n, y => y / n) }
  31. method neg { self * -1 }
  32. method to_s { "vec[#{x}, #{y}]" }
  33. }
  34. var u = MyVector(x => 3, y => 4)
  35. var v = MyVector(from => [1, 0], to => [2, 3])
  36. var w = MyVector(length => 1, angle => 45.deg2rad)
  37. say u #: vec[3, 4]
  38. say v #: vec[1, 3]
  39. say w #: vec[0.70710678118654752440084436210485, 0.70710678118654752440084436210485]
  40. say u.length #: 5
  41. say u.angle.rad2deg #: 53.13010235415597870314438744090659
  42. say u+v #: vec[4, 7]
  43. say u-v #: vec[2, 1]
  44. say -u #: vec[-3, -4]
  45. say u*10 #: vec[30, 40]
  46. say u/2 #: vec[1.5, 2]