Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #[derive(Debug)]
- struct Indexer {
- from: i64,
- to: i64,
- index: i64,
- }
- impl Indexer {
- fn new(from: i64, to: i64) -> Indexer {
- let index = from;
- Indexer { from, to, index }
- }
- }
- enum Mode {
- SetupTop,
- RenderTop,
- SetupBottom,
- RenderBottom,
- Done
- }
- struct Triangle {
- mode: Mode,
- v_scan: Indexer,
- h_scan: Indexer,
- v0: Point,
- v1: Point,
- v2: Point,
- height: i64,
- }
- impl Triangle {
- fn new(v0: Point, v1: Point, v2: Point) -> Triangle {
- let mut set = vec![v0, v1, v2];
- set.sort_by(|a, b| a.y.cmp(&b.y));
- let mode = Mode::SetupTop;
- let v0 = set[0].clone();
- let v1 = set[1].clone();
- let v2 = set[2].clone();
- let height = v2.y - v0.y;
- let v_scan = Indexer::new(0, 0);
- let h_scan = Indexer::new(0, 0);
- Triangle { mode, v_scan, h_scan, v0, v1, v2, height }
- }
- #[inline]
- fn set_horizontal_indexer_top(&mut self) {
- let y = self.v_scan.index;
- let height = self.v1.y - self.v0.y;
- let sx = (y - self.v0.y) as f32 / self.height as f32;
- let sy = (y - self.v0.y) as f32 / height as f32;
- let m0 = (self.v0.x + (self.v2.x - self.v0.x)) as f32 * sx;
- let m1 = (self.v0.x + (self.v1.x - self.v0.x)) as f32 * sy;
- let min = if m0 < m1 { m0 } else { m1 };
- let max = if m0 > m1 { m0 } else { m1 };
- self.h_scan = Indexer::new(min as i64, max as i64);
- }
- #[inline]
- fn set_horizontal_indexer_bottom(&mut self) {
- let y = self.v_scan.index;
- let height = self.v2.y - self.v1.y;
- let sx = (y - self.v0.y) as f32 / self.height as f32;
- let sy = (y - self.v1.y) as f32 / height as f32;
- let m0 = (self.v0.x + (self.v2.x - self.v0.x)) as f32 * sx;
- let m1 = (self.v1.x + (self.v1.x - self.v1.x)) as f32 * sy;
- let min = if m0 < m1 { m0 } else { m1 };
- let max = if m0 > m1 { m0 } else { m1 };
- self.h_scan = Indexer::new(min as i64, max as i64);
- }
- fn increment(&mut self) {
- match self.mode {
- Mode::Done => {
- panic!("increment called in done mode.")
- }
- Mode::SetupTop => {
- self.mode = Mode::RenderTop
- },
- Mode::RenderTop => {
- self.h_scan.index += 1;
- if self.h_scan.index > self.h_scan.to {
- self.v_scan.index += 1;
- if self.v_scan.index > self.v_scan.to {
- self.mode = Mode::SetupBottom;
- }
- }
- },
- Mode::SetupBottom => {
- self.mode = Mode::RenderBottom
- },
- Mode::RenderBottom => {
- self.h_scan.index += 1;
- if self.h_scan.index > self.h_scan.to {
- self.v_scan.index += 1;
- if self.v_scan.index > self.v_scan.to {
- self.mode = Mode::Done;
- }
- }
- }
- }
- }
- fn step(&mut self) -> Option<(i64, i64)> {
- match self.mode {
- Mode::SetupTop => {
- self.v_scan = Indexer::new(self.v0.y, self.v1.y);
- self.set_horizontal_indexer_top();
- let x = self.h_scan.index;
- let y = self.v_scan.index;
- self.increment();
- Some((x, y))
- },
- Mode::RenderTop => {
- let x = self.h_scan.index;
- let y = self.v_scan.index;
- self.increment();
- Some((x, y))
- },
- Mode::SetupBottom => {
- self.v_scan = Indexer::new(self.v1.y, self.v2.y);
- self.set_horizontal_indexer_bottom();
- let x = self.h_scan.index;
- let y = self.v_scan.index;
- self.increment();
- Some((x, y))
- },
- Mode::RenderBottom => {
- let x = self.h_scan.index;
- let y = self.v_scan.index;
- self.increment();
- Some((x, y))
- },
- Mode::Done => None
- }
- }
- }
- impl Iterator for Triangle {
- type Item = (i64, i64);
- fn next(&mut self) -> Option<(i64, i64)> {
- self.step()
- }
- }
- fn main() {
- let mut triangle = Triangle::new(
- Point::new( 0, 0),
- Point::new(-10, 10),
- Point::new( 10, 10)
- );
- for x in triangle {
- println!("{:?}", x);
- }
- // println!("{:?}", triangle.next());
- // println!("{:?}", triangle.next());
- // println!("{:?}", triangle.next());
- // println!("{:?}", triangle.next());
- // println!("{:?}", triangle.next());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement