thanks, jk
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.1 KiB

  1. //! Some generic geometry routines used in atlas packing.
  2. use std::ops::{Add, Sub, Mul};
  3. use std::convert::From;
  4. use num_traits::cast::NumCast;
  5. use rusttype;
  6. /// A rectangle.
  7. #[derive(Debug, Hash, Eq, PartialEq, Copy, Clone)]
  8. pub struct Rect<T> {
  9. pub x: T, pub y: T,
  10. pub w: T, pub h: T,
  11. }
  12. #[allow(dead_code)]
  13. impl<T> Rect<T>
  14. where T: Copy + Add<Output=T> + Sub<Output=T> + Mul<Output=T>
  15. + PartialOrd
  16. {
  17. /// Returns a new rectangle given the upper-left corner and its width + height.
  18. pub fn new(x: T, y: T, w: T, h: T) -> Rect<T> {
  19. Rect {
  20. x: x, y: y,
  21. w: w, h: h,
  22. }
  23. }
  24. /// Returns a new rectangle given a pair of points in opposing corners.
  25. pub fn from_points(x1: T, y1: T, x2: T, y2: T) -> Rect<T> {
  26. Rect {
  27. x: x1, y: y1,
  28. w: x2 - x1, h: y2 - y1
  29. }
  30. }
  31. /// Return the position of the top edge of the rectangle.
  32. #[inline(always)]
  33. pub fn top(&self) -> T {self.y}
  34. /// Return the position of the left edge of the rectangle.
  35. #[inline(always)]
  36. pub fn left(&self) -> T {self.x}
  37. /// Return the position of the bottom edge of the rectangle (coord system with 0 at top).
  38. #[inline(always)]
  39. pub fn bottom(&self) -> T {self.y + self.h}
  40. /// Return the position of the bottom edge of the rectangle (gl/mathematical coord system).
  41. #[inline(always)]
  42. pub fn gl_bottom(&self) -> T {self.y - self.h}
  43. /// Return the position of the right edge of the rectangle.
  44. #[inline(always)]
  45. pub fn right(&self) -> T {self.x + self.w}
  46. /// Return the area of the rectangle.
  47. #[inline(always)]
  48. pub fn area(&self) -> T {self.x * self.y}
  49. /// Given this rectangle and another rectangle, return true if they intersect.
  50. pub fn intersects(&self, other: &Rect<T>) -> bool {
  51. self.left() < other.right() &&
  52. self.right() > other.left() &&
  53. self.top() < other.bottom() &&
  54. self.bottom() > other.top()
  55. }
  56. /// Return true if this rectangle completely contains another rectangle.
  57. pub fn contains(&self, other: &Rect<T>) -> bool {
  58. self.left() <= other.left() &&
  59. self.right() >= other.right() &&
  60. self.top() <= other.top() &&
  61. self.bottom() >= other.bottom()
  62. }
  63. }
  64. impl<T> From<rusttype::Rect<T>> for Rect<T> where T: Sub<Output=T> + Copy {
  65. fn from(rect: rusttype::Rect<T>) -> Self {
  66. Rect {
  67. x: rect.min.x,
  68. y: rect.min.y,
  69. w: rect.width(),
  70. h: rect.height(),
  71. }
  72. }
  73. }
  74. /// A 2D vector
  75. #[derive(Debug, Hash, Eq, PartialEq, Copy, Clone)]
  76. pub struct Vec2<T> {
  77. pub x: T, pub y: T
  78. }
  79. impl<T> Vec2<T> {
  80. pub fn new(x: T, y: T) -> Vec2<T> {
  81. Vec2 { x: x, y: y, }
  82. }
  83. }
  84. impl<T> From<(T, T)> for Vec2<T> {
  85. fn from(tuple: (T, T)) -> Self {
  86. Vec2 {
  87. x: tuple.0,
  88. y: tuple.1,
  89. }
  90. }
  91. }
  92. impl<S> Vec2<S> where S: NumCast + Copy {
  93. pub fn cast<T>(&self) -> Vec2<T> where T: NumCast {
  94. Vec2 {
  95. x: NumCast::from(self.x).unwrap(),
  96. y: NumCast::from(self.y).unwrap(),
  97. }
  98. }
  99. }