rust/land2d/src/lib.rs
changeset 14078 bf40b5f938b0
parent 14076 e5904ead4864
child 14101 ceda58e398e0
equal deleted inserted replaced
14077:5ade484f3351 14078:bf40b5f938b0
     1 extern crate integral_geometry;
     1 extern crate integral_geometry;
     2 extern crate vec2d;
     2 extern crate vec2d;
     3 
     3 
     4 use std::cmp;
     4 use std::cmp;
     5 
     5 
     6 use integral_geometry::{
     6 use integral_geometry::{ArcPoints, EquidistantPoints, Line, Point, Rect, Size, SizeMask};
     7     ArcPoints, EquidistantPoints,
       
     8     Point, Size, SizeMask, Line
       
     9 };
       
    10 
     7 
    11 pub struct Land2D<T> {
     8 pub struct Land2D<T> {
    12     pixels: vec2d::Vec2D<T>,
     9     pixels: vec2d::Vec2D<T>,
    13     play_size: Size,
    10     play_size: Size,
    14     mask: SizeMask
    11     play_box: Rect,
       
    12 
       
    13     mask: SizeMask,
    15 }
    14 }
    16 
    15 
    17 impl<T: Copy + PartialEq> Land2D<T> {
    16 impl<T: Copy + PartialEq> Land2D<T> {
    18     pub fn new(play_size: Size, fill_value: T) -> Self {
    17     pub fn new(play_size: Size, fill_value: T) -> Self {
    19         let real_size = play_size.next_power_of_two();
    18         let real_size = play_size.next_power_of_two();
       
    19         let top_left = Point::new(
       
    20             (real_size.width - play_size.width / 2) as i32,
       
    21             (real_size.height - play_size.height) as i32,
       
    22         );
       
    23         let play_box = Rect::from_size(top_left, play_size);
    20         Self {
    24         Self {
    21             play_size,
    25             play_size,
       
    26             play_box,
    22             pixels: vec2d::Vec2D::new(real_size, fill_value),
    27             pixels: vec2d::Vec2D::new(real_size, fill_value),
    23             mask: real_size.to_mask()
    28             mask: real_size.to_mask(),
    24         }
    29         }
    25     }
    30     }
    26 
    31 
    27     #[inline]
    32     #[inline]
    28     pub fn width(&self) -> usize {
    33     pub fn width(&self) -> usize {
    50     }
    55     }
    51 
    56 
    52     #[inline]
    57     #[inline]
    53     pub fn play_size(&self) -> Size {
    58     pub fn play_size(&self) -> Size {
    54         self.play_size
    59         self.play_size
       
    60     }
       
    61 
       
    62     #[inline]
       
    63     pub fn play_box(&self) -> Rect {
       
    64         self.play_box
    55     }
    65     }
    56 
    66 
    57     #[inline]
    67     #[inline]
    58     pub fn is_valid_x(&self, x: i32) -> bool {
    68     pub fn is_valid_x(&self, x: i32) -> bool {
    59         self.mask.contains_x(x as usize)
    69         self.mask.contains_x(x as usize)
   243         let row_index = center.y + offset.y;
   253         let row_index = center.y + offset.y;
   244         if self.is_valid_y(row_index) {
   254         if self.is_valid_y(row_index) {
   245             let from_x = cmp::max(0, center.x - offset.x) as usize;
   255             let from_x = cmp::max(0, center.x - offset.x) as usize;
   246             let to_x = cmp::min(self.width() - 1, (center.x + offset.x) as usize);
   256             let to_x = cmp::min(self.width() - 1, (center.x + offset.x) as usize);
   247             self.pixels[row_index as usize][from_x..=to_x]
   257             self.pixels[row_index as usize][from_x..=to_x]
   248                 .iter_mut().for_each(|v| *v = value);
   258                 .iter_mut()
       
   259                 .for_each(|v| *v = value);
   249             to_x - from_x + 1
   260             to_x - from_x + 1
   250         } else {
   261         } else {
   251             0
   262             0
   252         }
   263         }
   253     }
   264     }
   254 
   265 
   255     pub fn fill_circle(&mut self, center: Point, radius: i32, value: T) -> usize {
   266     pub fn fill_circle(&mut self, center: Point, radius: i32, value: T) -> usize {
   256         let transforms =
   267         let transforms = [[0, 1, 1, 0], [0, 1, -1, 0], [1, 0, 0, 1], [1, 0, 0, -1]];
   257             [[0, 1, 1, 0], [0, 1, -1, 0],
   268         ArcPoints::new(radius)
   258              [1, 0, 0, 1], [1, 0, 0, -1]];
   269             .map(|vector| {
   259         ArcPoints::new(radius).map(|vector| {
   270                 transforms
   260             transforms.iter().map(|m|
   271                     .iter()
   261                 self.fill_row(center, vector.transform(m), value)
   272                     .map(|m| self.fill_row(center, vector.transform(m), value))
   262             ).sum::<usize>()
   273                     .sum::<usize>()
   263         }).sum()
   274             }).sum()
   264     }
   275     }
   265 
   276 
   266     pub fn draw_thick_line(&mut self, line: Line, radius: i32, value: T) -> usize {
   277     pub fn draw_thick_line(&mut self, line: Line, radius: i32, value: T) -> usize {
   267         let mut result = 0;
   278         let mut result = 0;
   268 
   279