plottery_lib 0.7.0

Core geometry library of Plottery, a creative coding framework for generative vector graphics and pen plotting.
Documentation
use crate::{Line, Rect, SampleSettings, V2};

use super::sample_triangle::{SamplePoint, SampleRect};

pub struct MarchingSquares {
    rects: Vec<SampleRect>,
}

impl MarchingSquares {
    pub fn new(bounds: Rect, sample_settings: SampleSettings, function: fn(V2) -> f32) -> Self {
        let num = (bounds.size() * sample_settings.points_per_unit).ceil_to_int();
        let mut rects: Vec<SampleRect> =
            Vec::with_capacity((num.x as usize + 1) * (num.y as usize + 1));

        let mut last_row: Vec<Option<SamplePoint>> = vec![None; num.x as usize + 1];
        for y in 0..(num.y as usize + 1) {
            let mut new_row: Vec<Option<SamplePoint>> = vec![None; num.x as usize + 1];
            for x in 0..(num.x as usize + 1) {
                let pos_br = (V2::new(x as f32, y as f32) / V2::new(num.x as f32, num.y as f32))
                    * bounds.size()
                    + bounds.bl();
                let br = SamplePoint {
                    pos: pos_br,
                    value: function(pos_br),
                };

                if y > 0 && x > 0 {
                    let pos_center = pos_br - V2::new(0.5, 0.5) / sample_settings.points_per_unit;
                    let center = SamplePoint {
                        pos: pos_center,
                        value: function(pos_center),
                    };

                    rects.push(SampleRect::new(
                        last_row[x - 1].unwrap(),
                        last_row[x].unwrap(),
                        br,
                        new_row[x - 1].unwrap(),
                        center,
                    ));
                }

                new_row[x] = Some(br);
            }
            last_row = new_row;
        }

        Self { rects }
    }

    pub fn get_lines(&self, target_value: f32) -> Vec<Line> {
        let mut lines = Vec::new();
        for rect in &self.rects {
            for triangle in &rect.triangles {
                if let Some(line) = triangle.get_intersection_line(target_value) {
                    lines.push(line);
                }
            }
        }
        lines
    }
}