types.rs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. use std::cmp::{max, min};
  2. #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
  3. pub struct Size {
  4. pub width: usize,
  5. pub height: usize,
  6. }
  7. impl specs::Component for Size {
  8. type Storage = specs::VecStorage<Self>;
  9. }
  10. impl From<[usize; 2]> for Size {
  11. fn from([width, height]: [usize; 2]) -> Size {
  12. Size { width, height }
  13. }
  14. }
  15. #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
  16. pub struct Coord {
  17. pub x: usize,
  18. pub y: usize,
  19. }
  20. impl Coord {
  21. pub fn new(x: usize, y: usize) -> Coord {
  22. Coord { x, y }
  23. }
  24. }
  25. impl specs::Component for Coord {
  26. type Storage = specs::VecStorage<Coord>;
  27. }
  28. impl From<[usize; 2]> for Coord {
  29. fn from([x, y]: [usize; 2]) -> Coord {
  30. Coord { x, y }
  31. }
  32. }
  33. impl std::ops::Add for Coord {
  34. type Output = Self;
  35. fn add(self, other: Self) -> Self {
  36. Coord {
  37. x: self.x + other.x,
  38. y: self.y + other.y,
  39. }
  40. }
  41. }
  42. impl std::ops::Add<usize> for Coord {
  43. type Output = Self;
  44. fn add(self, other: usize) -> Self {
  45. Coord {
  46. x: self.x + other,
  47. y: self.y + other,
  48. }
  49. }
  50. }
  51. impl std::ops::Add<isize> for Coord {
  52. type Output = Self;
  53. fn add(self, other: isize) -> Self {
  54. Coord {
  55. x: (self.x as isize + other) as usize,
  56. y: (self.y as isize + other) as usize,
  57. }
  58. }
  59. }
  60. impl std::ops::Add<(isize, isize)> for Coord {
  61. type Output = Self;
  62. fn add(self, other: (isize, isize)) -> Self {
  63. Coord {
  64. x: (self.x as isize + other.0) as usize,
  65. y: (self.y as isize + other.1) as usize,
  66. }
  67. }
  68. }
  69. impl std::ops::Sub for Coord {
  70. type Output = Self;
  71. fn sub(self, other: Self) -> Self {
  72. Coord {
  73. x: self.x - other.x,
  74. y: self.y - other.y,
  75. }
  76. }
  77. }
  78. impl std::ops::Sub<usize> for Coord {
  79. type Output = Self;
  80. fn sub(self, other: usize) -> Self {
  81. Coord {
  82. x: self.x - other,
  83. y: self.y - other,
  84. }
  85. }
  86. }
  87. #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
  88. pub struct Rect {
  89. pub origin: Coord,
  90. pub size: Size,
  91. }
  92. impl Rect {
  93. pub fn new(origin: impl Into<Coord>, size: impl Into<Size>) -> Rect {
  94. let origin = origin.into();
  95. let size = size.into();
  96. Rect { origin, size }
  97. }
  98. pub fn from_points(p1: impl Into<Coord>, p2: impl Into<Coord>) -> Rect {
  99. let p1 = p1.into();
  100. let p2 = p2.into();
  101. let origin = Coord {
  102. x: min(p1.x, p2.x),
  103. y: min(p1.y, p2.y),
  104. };
  105. let size = Size {
  106. width: max(max(p1.x, p2.x) - origin.x, 1),
  107. height: max(max(p1.y, p2.y) - origin.y, 1),
  108. };
  109. Rect { origin, size }
  110. }
  111. pub fn area(&self) -> usize {
  112. self.size.width * self.size.height
  113. }
  114. pub fn width(&self) -> usize {
  115. self.size.width
  116. }
  117. pub fn height(&self) -> usize {
  118. self.size.height
  119. }
  120. pub fn x(&self) -> usize {
  121. self.origin.x
  122. }
  123. pub fn y(&self) -> usize {
  124. self.origin.y
  125. }
  126. pub fn contains(&self, pt: impl Into<Coord>) -> bool {
  127. let pt = pt.into();
  128. pt.x >= self.origin.x
  129. && pt.y >= self.origin.y
  130. && pt.x < self.origin.x + self.size.width
  131. && pt.y < self.origin.y + self.size.height
  132. }
  133. pub fn overlaps(&self, other: Rect) -> bool {
  134. if self.x() > other.x() + other.width() || other.x() > self.x() + self.width() {
  135. return false;
  136. }
  137. if self.y() > other.y() + other.height() || other.y() > self.y() + self.height() {
  138. return false;
  139. }
  140. true
  141. }
  142. pub fn center(&self) -> Coord {
  143. Coord {
  144. x: self.x() + (self.width() / 2),
  145. y: self.y() + (self.height() / 2),
  146. }
  147. }
  148. }