circle.nim 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. # author: Ethosa
  2. ## Provides Circle type.
  3. import
  4. math,
  5. vector2
  6. {.used.}
  7. type
  8. CircleObj* = object
  9. x*, y*, r*: float
  10. proc Circle*(x, y, r: float): CircleObj =
  11. ## Creates a new Circle object.
  12. ##
  13. ## Arguments:
  14. ## - `x` is a center circle point at X axis.
  15. ## - `y` is a center circle point at Y axis.
  16. ## - `r` is a circle radius.
  17. runnableExamples:
  18. var obj = Circle(10, 10, 5)
  19. CircleObj(x: x, y: y, r: r)
  20. proc Circle*(vec: Vector2Obj, r: float): CircleObj =
  21. ## Creates a new Circle object.
  22. ##
  23. ## Arguments:
  24. ## - `vec` is a circle center position.
  25. ## - `r` is a circle radius.
  26. CircleObj(x: vec.x, y: vec.y, r: r)
  27. proc contains*(self: CircleObj, x, y: float): bool =
  28. ## Returns true, if `x`,`y` in the circle.
  29. let
  30. dx = x - self.x
  31. dy = y - self.y
  32. dx*dx + dy*dy <= self.r*self.r
  33. proc contains*(self: CircleObj, vec2: Vector2Obj): bool {.inline.} =
  34. ## Returns true, if `vec2` in the circle.
  35. self.contains(vec2.x, vec2.y)
  36. proc contains*(self, other: CircleObj): bool =
  37. ## Returns true, if `self` intersects with `other` circle.
  38. let
  39. dx = other.x - self.x
  40. dy = other.y - self.y
  41. r = other.r + self.r
  42. dx*dx + dy*dy <= r*r
  43. proc contains*(self: CircleObj, a, b: Vector2Obj): bool =
  44. let
  45. dx = b.x - a.x
  46. dy = b.y - a.y
  47. d = sqrt(dx*dx + dy*dy)
  48. if d == 0:
  49. return false
  50. let
  51. nx = dx/d
  52. ny = dy/d
  53. mx = a.x - self.x
  54. my = a.y - self.y
  55. b = mx*nx + my*ny
  56. c = mx*mx + my*my - self.r*self.r
  57. if c > 0 and b > 0:
  58. return false
  59. var discr = b*b - c
  60. if discr < 0:
  61. return false
  62. discr = sqrt(discr)
  63. let tmin = if -b - discr > 0: -b - discr else: 0
  64. if tmin > d:
  65. return false
  66. return true
  67. # --- Operators --- #
  68. proc `$`*(self: CircleObj): string {.inline.} =
  69. "Circle(x:" & $self.x & ", y:" & $self.y & ", r:" & $self.r & ")"