rust/integral-geometry/src/lib.rs
changeset 14139 37c99587825d
parent 14137 3119d665d3c6
child 14140 3078123e84ea
equal deleted inserted replaced
14138:417d81c72119 14139:37c99587825d
       
     1 #[macro_use]
     1 extern crate fpnum;
     2 extern crate fpnum;
     2 
     3 
     3 use fpnum::distance;
     4 use fpnum::{distance, FPNum, FPPoint};
     4 use std::{
     5 use std::{
     5     cmp::max,
     6     cmp::max,
     6     ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Range, RangeInclusive, Sub, SubAssign}
     7     ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Range, RangeInclusive, Sub, SubAssign}
     7 };
     8 };
     8 
       
     9 
     9 
    10 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    10 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    11 pub struct Point {
    11 pub struct Point {
    12     pub x: i32,
    12     pub x: i32,
    13     pub y: i32,
    13     pub y: i32,
    96     }
    96     }
    97 
    97 
    98     #[inline]
    98     #[inline]
    99     pub fn cotangent(self) -> i32 {
    99     pub fn cotangent(self) -> i32 {
   100         self.x / self.y
   100         self.x / self.y
       
   101     }
       
   102 
       
   103     #[inline]
       
   104     pub fn to_fppoint(&self) -> FPPoint {
       
   105         FPPoint::new(self.x.into(), self.y.into())
   101     }
   106     }
   102 }
   107 }
   103 
   108 
   104 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
   109 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
   105 pub struct Size {
   110 pub struct Size {
   723             }
   728             }
   724 
   729 
   725             self.iteration -= 1;
   730             self.iteration -= 1;
   726 
   731 
   727             Some(self.vector)
   732             Some(self.vector)
       
   733         } else {
       
   734             None
       
   735         }
       
   736     }
       
   737 }
       
   738 
       
   739 pub struct BezierCurveSegments {
       
   740     segment: Line,
       
   741     c1: FPPoint,
       
   742     c2: FPPoint,
       
   743     offset: FPNum,
       
   744     delta: FPNum,
       
   745 }
       
   746 
       
   747 impl BezierCurveSegments {
       
   748     pub fn new(segment: Line, p1: Point, p2: Point, delta: FPNum) -> Self {
       
   749         Self {
       
   750             segment,
       
   751             c1: (segment.start - p1).to_fppoint(),
       
   752             c2: (segment.end - p2).to_fppoint(),
       
   753             offset: fp!(0),
       
   754             delta,
       
   755         }
       
   756     }
       
   757 }
       
   758 
       
   759 impl Iterator for BezierCurveSegments {
       
   760     type Item = Point;
       
   761 
       
   762     fn next(&mut self) -> Option<Self::Item> {
       
   763         if self.offset < fp!(1) {
       
   764             let offset_sq = self.offset * self.offset;
       
   765             let offset_cub = offset_sq * self.offset;
       
   766 
       
   767             let r1 = fp!(1) - self.offset * 3 + offset_sq * 3 - offset_cub;
       
   768             let r2 = self.offset * 3 - offset_sq * 6 + offset_cub * 3;
       
   769             let r3 = offset_sq * 3 - offset_cub * 3;
       
   770 
       
   771             let x = r1 * self.segment.start.x
       
   772                 + r2 * self.c1.x()
       
   773                 + r3 * self.c2.x()
       
   774                 + offset_cub * self.segment.end.x;
       
   775             let y = r1 * self.segment.start.y
       
   776                 + r2 * self.c1.y()
       
   777                 + r3 * self.c2.y()
       
   778                 + offset_cub * self.segment.end.y;
       
   779 
       
   780             self.offset += self.delta;
       
   781 
       
   782             Some(Point::new(x.round(), y.round()))
   728         } else {
   783         } else {
   729             None
   784             None
   730         }
   785         }
   731     }
   786     }
   732 }
   787 }