rust/integral-geometry/src/lib.rs
changeset 15751 a4558e2be08c
parent 15384 1c6d5656157c
child 15828 44b49f255e31
equal deleted inserted replaced
15750:036263d63b05 15751:a4558e2be08c
    22     pub const fn diag(v: i32) -> Self {
    22     pub const fn diag(v: i32) -> Self {
    23         Self::new(v, v)
    23         Self::new(v, v)
    24     }
    24     }
    25 
    25 
    26     #[inline]
    26     #[inline]
    27     pub fn signum(self) -> Self {
    27     pub const fn signum(self) -> Self {
    28         Self::new(self.x.signum(), self.y.signum())
    28         Self::new(self.x.signum(), self.y.signum())
    29     }
    29     }
    30 
    30 
    31     #[inline]
    31     #[inline]
    32     pub fn abs(self) -> Self {
    32     pub const fn abs(self) -> Self {
    33         Self::new(self.x.abs(), self.y.abs())
    33         Self::new(self.x.abs(), self.y.abs())
    34     }
    34     }
    35 
    35 
    36     #[inline]
    36     #[inline]
    37     pub const fn dot(self, other: Point) -> i32 {
    37     pub const fn dot(self, other: Point) -> i32 {
   134     pub const fn linear_index(&self, x: usize, y: usize) -> usize {
   134     pub const fn linear_index(&self, x: usize, y: usize) -> usize {
   135         y * self.width + x
   135         y * self.width + x
   136     }
   136     }
   137 
   137 
   138     #[inline]
   138     #[inline]
   139     pub fn is_power_of_two(&self) -> bool {
   139     pub const fn is_power_of_two(&self) -> bool {
   140         self.width.is_power_of_two() && self.height.is_power_of_two()
   140         self.width.is_power_of_two() && self.height.is_power_of_two()
   141     }
   141     }
   142 
   142 
   143     #[inline]
   143     #[inline]
   144     pub fn next_power_of_two(&self) -> Self {
   144     pub fn next_power_of_two(&self) -> Self {
   166     pub fn to_grid_index(&self) -> GridIndex {
   166     pub fn to_grid_index(&self) -> GridIndex {
   167         GridIndex::new(*self)
   167         GridIndex::new(*self)
   168     }
   168     }
   169 
   169 
   170     #[inline]
   170     #[inline]
   171     pub fn contains(&self, other: Self) -> bool {
   171     pub const fn contains(&self, other: Self) -> bool {
   172         self.width >= other.width && self.height >= other.height
   172         self.width >= other.width && self.height >= other.height
   173     }
   173     }
   174 
   174 
   175     #[inline]
   175     #[inline]
   176     pub fn join(&self, other: Self) -> Self {
   176     pub fn join(&self, other: Self) -> Self {
   217     shift: Point,
   217     shift: Point,
   218 }
   218 }
   219 
   219 
   220 impl GridIndex {
   220 impl GridIndex {
   221     pub fn new(size: Size) -> Self {
   221     pub fn new(size: Size) -> Self {
   222         assert!(size.is_power_of_two());
   222         debug_assert!(size.is_power_of_two());
   223         let shift = Point::new(
   223         let shift = Point::new(
   224             size.width.trailing_zeros() as i32,
   224             size.width.trailing_zeros() as i32,
   225             size.height.trailing_zeros() as i32,
   225             size.height.trailing_zeros() as i32,
   226         );
   226         );
   227         Self { shift }
   227         Self { shift }
   228     }
   228     }
   229 
   229 
   230     pub fn map(&self, position: Point) -> Point {
   230     pub const fn map(&self, position: Point) -> Point {
   231         Point::new(position.x >> self.shift.x, position.y >> self.shift.y)
   231         Point::new(position.x >> self.shift.x, position.y >> self.shift.y)
   232     }
   232     }
   233 }
   233 }
   234 
   234 
   235 macro_rules! bin_op_impl {
   235 macro_rules! bin_op_impl {
   412         let offset = Point::diag(margin);
   412         let offset = Point::diag(margin);
   413         Self::new(self.top_left() + offset, self.bottom_right() - offset)
   413         Self::new(self.top_left() + offset, self.bottom_right() - offset)
   414     }
   414     }
   415 
   415 
   416     #[inline]
   416     #[inline]
   417     pub fn x_range(&self) -> RangeInclusive<i32> {
   417     pub const fn x_range(&self) -> RangeInclusive<i32> {
   418         self.left()..=self.right()
   418         self.left()..=self.right()
   419     }
   419     }
   420 
   420 
   421     #[inline]
   421     #[inline]
   422     pub fn y_range(&self) -> RangeInclusive<i32> {
   422     pub const fn y_range(&self) -> RangeInclusive<i32> {
   423         self.top()..=self.bottom()
   423         self.top()..=self.bottom()
   424     }
   424     }
   425 
   425 
   426     #[inline]
   426     #[inline]
   427     pub fn contains(&self, point: Point) -> bool {
   427     pub fn contains(&self, point: Point) -> bool {
   428         self.x_range().contains(&point.x) && self.y_range().contains(&point.y)
   428         self.x_range().contains(&point.x) && self.y_range().contains(&point.y)
   429     }
   429     }
   430 
   430 
   431     #[inline]
   431     #[inline]
   432     pub fn contains_inside(&self, point: Point) -> bool {
   432     pub const fn contains_inside(&self, point: Point) -> bool {
   433         point.x > self.left()
   433         point.x > self.left()
   434             && point.x < self.right()
   434             && point.x < self.right()
   435             && point.y > self.top()
   435             && point.y > self.top()
   436             && point.y < self.bottom()
   436             && point.y < self.bottom()
   437     }
   437     }
   440     pub fn contains_rect(&self, other: &Self) -> bool {
   440     pub fn contains_rect(&self, other: &Self) -> bool {
   441         self.contains(other.top_left()) && self.contains(other.bottom_right())
   441         self.contains(other.top_left()) && self.contains(other.bottom_right())
   442     }
   442     }
   443 
   443 
   444     #[inline]
   444     #[inline]
   445     pub fn intersects(&self, other: &Rect) -> bool {
   445     pub const fn intersects(&self, other: &Rect) -> bool {
   446         self.left() <= other.right()
   446         self.left() <= other.right()
   447             && self.right() >= other.left()
   447             && self.right() >= other.left()
   448             && self.top() <= other.bottom()
   448             && self.top() <= other.bottom()
   449             && self.bottom() >= other.top()
   449             && self.bottom() >= other.top()
   450     }
   450     }
   451 
   451 
   452     #[inline]
   452     #[inline]
   453     pub fn split_at(&self, point: Point) -> [Rect; 4] {
   453     pub fn split_at(&self, point: Point) -> [Rect; 4] {
   454         assert!(self.contains_inside(point));
   454         debug_assert!(self.contains_inside(point));
   455         [
   455         [
   456             Self::from_box(self.left(), point.x, self.top(), point.y),
   456             Self::from_box(self.left(), point.x, self.top(), point.y),
   457             Self::from_box(point.x, self.right(), self.top(), point.y),
   457             Self::from_box(point.x, self.right(), self.top(), point.y),
   458             Self::from_box(point.x, self.right(), point.y, self.bottom()),
   458             Self::from_box(point.x, self.right(), point.y, self.bottom()),
   459             Self::from_box(self.left(), point.x, point.y, self.bottom()),
   459             Self::from_box(self.left(), point.x, point.y, self.bottom()),