vector2.nim 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # author: Ethosa
  2. import math
  3. {.used.}
  4. type
  5. Vector2Obj* = object
  6. x*, y*: float
  7. Vector2Ref* = ref Vector2Obj
  8. proc Vector2*(x, y: float): Vector2Ref {.inline.} =
  9. Vector2Ref(x: x, y: y)
  10. proc Vector2*(b: Vector2Ref): Vector2Ref {.inline.} =
  11. Vector2Ref(x: b.x, y: b.y)
  12. proc Vector2*(num: float): Vector2Ref {.inline.} =
  13. Vector2Ref(x: num, y: num)
  14. proc Vector2*(): Vector2Ref {.inline.} =
  15. Vector2Ref(x: 0, y: 0)
  16. proc abs*(a: Vector2Ref): Vector2Ref =
  17. Vector2(abs(a.x), abs(a.y))
  18. proc angle*(a: Vector2Ref): float =
  19. arctan2(a.y, a.x)
  20. proc cross*(a, b: Vector2Ref): float =
  21. a.x*b.x - a.y*b.y
  22. proc cross*(a: Vector2Ref, x, y: float): float =
  23. a.x*x - a.y*y
  24. proc dot*(a, b: Vector2Ref): float =
  25. a.x*b.x + a.y*b.y
  26. proc dot*(a: Vector2Ref, x, y: float): float =
  27. a.x*x + a.y*y
  28. proc angleTo*(a, b: Vector2Ref): float =
  29. arctan2(a.cross(b), a.dot(b))
  30. proc angleTo*(a: Vector2Ref, x, y: float): float =
  31. arctan2(a.cross(x, y), a.dot(x, y))
  32. proc angleToPoint*(a, b: Vector2Ref): float =
  33. arctan2(a.y - b.y, a.x - b.x)
  34. proc angleToPoint*(a: Vector2Ref, x, y: float): float =
  35. arctan2(a.y - y, a.x - x)
  36. proc length*(a: Vector2Ref): float =
  37. sqrt(a.x*a.x + a.y*a.y)
  38. proc normalize*(a: Vector2Ref) =
  39. var l: float = a.x*a.x + a.y*a.y
  40. if l != 0:
  41. l = sqrt(l)
  42. a.x /= l
  43. a.y /= l
  44. proc normalized*(a: Vector2Ref): Vector2Ref =
  45. result = Vector2(a)
  46. result.normalize()
  47. proc distance*(a, b: Vector2Ref): float =
  48. sqrt((b.x - a.x)*(b.x - a.x) + (b.y - a.y)*(b.y - a.y))
  49. proc distance*(a: Vector2Ref, x, y: float): float =
  50. sqrt((x - a.x)*(x - a.x) + (y - a.y)*(y - a.y))
  51. proc directionTo*(a, b: Vector2Ref): Vector2Ref =
  52. result = Vector2(b.x - a.x, b.y - a.y)
  53. result.normalize()
  54. proc directionTo*(a: Vector2Ref, x, y: float): Vector2Ref =
  55. result = Vector2(x - a.x, y - a.y)
  56. result.normalize()
  57. proc intersects*(a, b, c, d: Vector2Ref): bool =
  58. let
  59. uA = ((d.x-c.x)*(a.y-c.y) - (d.y-c.y)*(a.x-c.x)) / ((d.y-c.y)*(b.x-a.x) - (d.x-c.x)*(b.y-a.y))
  60. uB = ((b.x-a.x)*(a.y-c.y) - (b.y-a.y)*(a.x-c.x)) / ((d.y-c.y)*(b.x-a.x) - (d.x-c.x)*(b.y-a.y))
  61. return uA >= 0 and uA <= 1 and uB >= 0 and uB <= 1
  62. # --- Operators --- #
  63. proc `+`*(a, b: Vector2Ref): Vector2Ref =
  64. Vector2(a.x + b.x, a.y + b.y)
  65. proc `-`*(a, b: Vector2Ref): Vector2Ref =
  66. Vector2(a.x - b.x, a.y - b.y)
  67. proc `/`*(a, b: Vector2Ref): Vector2Ref =
  68. Vector2(a.x / b.x, a.y / b.y)
  69. proc `*`*(a, b: Vector2Ref): Vector2Ref =
  70. Vector2(a.x * b.x, a.y * b.y)
  71. proc `*`*(x: Vector2Ref, y: float): Vector2Ref =
  72. Vector2(x.x * y, x.y * y)
  73. proc `+`*(x: Vector2Ref, y: float): Vector2Ref =
  74. Vector2(x.x + y, x.y + y)
  75. proc `-`*(x: Vector2Ref, y: float): Vector2Ref =
  76. Vector2(x.x - y, x.y - y)
  77. proc `/`*(x: Vector2Ref, y: float): Vector2Ref =
  78. Vector2(x.x / y, x.y / y)
  79. proc `*=`*(x: var Vector2Ref, y: Vector2Ref) =
  80. x = x * y
  81. proc `+=`*(x: var Vector2Ref, y: Vector2Ref) =
  82. x = x + y
  83. proc `-=`*(x: var Vector2Ref, y: Vector2Ref) =
  84. x = x - y
  85. proc `/=`*(x: var Vector2Ref, y: Vector2Ref) =
  86. x = x / y
  87. proc `>`*(x, y: Vector2Ref): bool =
  88. x.x > y.x and x.y > y.y
  89. proc `<`*(x, y: Vector2Ref): bool =
  90. x.x < y.x and x.y < y.y
  91. proc `>=`*(x, y: Vector2Ref): bool =
  92. x.x >= y.x and x.y >= y.y
  93. proc `<=`*(x, y: Vector2Ref): bool =
  94. x.x <= y.x and x.y <= y.y
  95. proc `==`*(x, y: Vector2Ref): bool =
  96. x.x == y.x and x.y == y.y
  97. proc `!=`*(x, y: Vector2Ref): bool =
  98. x.x != y.x and x.y != y.y
  99. proc `$`*(a: Vector2Ref): string =
  100. "Vector2(" & $a.x & ", " & $a.y & ")"