signed_distance_fields 1.0.6

A implementation of SDFs (signed distance fields) and some operators to play with these SDFs
Documentation
use math_vector::Vector;

/// SDF of a rectangle
pub struct Rectangle {
    /// Width
    pub w: f64,
    /// Height
    pub h: f64,
}
impl super::SignedDistanceField for Rectangle {
    fn call(&self, p: Vector<f64>) -> f64 {
        let half_size = Vector {
            x: 0.5 * self.w,
            y: 0.5 * self.h,
            z: 0.0,
        };
        let component_wise_edge_distance = Vector {
            x: p.x.abs() - half_size.x,
            y: p.y.abs() - half_size.y,
            z: 0.0,
        };
        let outside_distance = Vector {
            x: component_wise_edge_distance.x.max(0.0),
            y: component_wise_edge_distance.y.max(0.0),
            z: 0.0,
        }
        .length();
        let inside_distance = component_wise_edge_distance
            .x
            .max(component_wise_edge_distance.y);

        let distance = outside_distance + inside_distance;

        distance
    }
}

/// SDF for a circle
pub struct Circle {
    /// Radius
    pub r: f64,
}
impl super::SignedDistanceField for Circle {
    fn call(&self, p: Vector<f64>) -> f64 {
        p.length() - self.r
    }
}

/// SDF for a infinite line (straight)
pub struct Straight {}
impl super::SignedDistanceField for Straight {
    fn call(&self, p: Vector<f64>) -> f64 {
        p.x.abs()
    }
}

/// SDF for a line
pub struct Line {
    /// Length of the line
    pub l: f64
}
impl super::SignedDistanceField for Line {
    fn call(&self, p: Vector<f64>) -> f64 {
        if -0.5 * self.l < p.x {
            (Vector { x: -0.5 * self.l, y: 0.0, z: 0.0 } - p).length()
        } else if p.x < 0.5 * self.l {
            (Vector { x: 0.5 * self.l, y: 0.0, z: 0.0 } - p).length()
         } else {
            p.x.abs()
         }

    }
}