types.rs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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 specs::Component for Coord {
  21. type Storage = specs::VecStorage<Coord>;
  22. }
  23. impl From<[usize; 2]> for Coord {
  24. fn from([x, y]: [usize; 2]) -> Coord {
  25. Coord { x, y }
  26. }
  27. }
  28. #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
  29. pub struct Rect {
  30. pub origin: Coord,
  31. pub size: Size,
  32. }
  33. impl Rect {
  34. pub fn new(origin: impl Into<Coord>, size: impl Into<Size>) -> Rect {
  35. let origin = origin.into();
  36. let size = size.into();
  37. Rect { origin, size }
  38. }
  39. pub fn from_points(p1: impl Into<Coord>, p2: impl Into<Coord>) -> Rect {
  40. let p1 = p1.into();
  41. let p2 = p2.into();
  42. let origin = Coord {
  43. x: min(p1.x, p2.x),
  44. y: min(p1.y, p2.y),
  45. };
  46. let size = Size {
  47. width: max(max(p1.x, p2.x) - origin.x, 1),
  48. height: max(max(p1.y, p2.y) - origin.y, 1),
  49. };
  50. Rect { origin, size }
  51. }
  52. pub fn area(&self) -> usize {
  53. self.size.width * self.size.height
  54. }
  55. pub fn width(&self) -> usize {
  56. self.size.width
  57. }
  58. pub fn height(&self) -> usize {
  59. self.size.height
  60. }
  61. pub fn x(&self) -> usize {
  62. self.origin.x
  63. }
  64. pub fn y(&self) -> usize {
  65. self.origin.y
  66. }
  67. pub fn contains(&self, pt: impl Into<Coord>) -> bool {
  68. let pt = pt.into();
  69. pt.x >= self.origin.x
  70. && pt.y >= self.origin.y
  71. && pt.x < self.origin.x + self.size.width
  72. && pt.y < self.origin.y + self.size.height
  73. }
  74. pub fn overlaps(&self, other: Rect) -> bool {
  75. if self.x() > other.x() + other.width() || other.x() > self.x() + self.width() {
  76. return false;
  77. }
  78. if self.y() > other.y() + other.height() || other.y() > self.y() + self.height() {
  79. return false;
  80. }
  81. true
  82. }
  83. pub fn center(&self) -> Coord {
  84. Coord {
  85. x: self.x() + (self.width() / 2),
  86. y: self.y() + (self.height() / 2),
  87. }
  88. }
  89. }