pizarra 0.6.3

The backend for a simple vector hand-drawing application
Documentation
use crate::draw_commands::DrawCommand;
use super::{ShapeTrait, ShapeFinished};
use crate::color::Color;
use crate::ShapeType;
use crate::point::Point;

pub struct Ellipse {
    corner_1: Point,
    corner_2: Point,
    color: Color,
}

impl Ellipse {
    pub fn new(color: Color, initial: Point) -> Ellipse {
        Ellipse {
            corner_1: initial,
            corner_2: initial,
            color,
        }
    }

    pub fn from_corners([corner_1, corner_2]: [Point; 2]) -> Ellipse {
        Ellipse {
            corner_1, corner_2,
            color: Color::green(),
        }
    }
}

impl ShapeTrait for Ellipse {
    fn handle_mouse_moved(&mut self, pos: Point) {
        self.corner_2 = pos;
    }

    fn handle_button_pressed(&mut self, _pos: Point) {
        unreachable!();
    }

    fn handle_button_released(&mut self, pos: Point) -> ShapeFinished {
        self.corner_2 = pos;
        ShapeFinished::Yes
    }

    fn draw_commands(&self) -> DrawCommand {
        DrawCommand::Ellipse{
            corner_1: self.corner_1,
            corner_2: self.corner_2,
            color: self.color,
        }
    }

    fn bbox(&self) -> [[f64; 2]; 2] {
        let x2 = self.corner_2.x;
        let y2 = self.corner_2.y;

        [
            [
                self.corner_1.x.min(x2),
                self.corner_1.y.min(y2),
            ],
            [
                self.corner_1.x.max(x2),
                self.corner_1.y.max(y2),
            ],
        ]
    }

    fn shape_type(&self) -> ShapeType {
        ShapeType::Ellipse
    }

    fn intersects_circle(&self, center: Point, radius: f64) -> bool {
        unimplemented!()
    }

    fn color(&self) -> Color {
        self.color
    }
}

#[cfg(test)]
mod tests {
    use super::Ellipse;
    use crate::point::Point;
    use crate::shape::ShapeTrait;

    #[test]
    fn test_bbox() {
        let shape1 = Ellipse::from_corners([Point::new(-1.0, -2.0), Point::new(5.0, 2.0)]);
        let shape2 = Ellipse::from_corners([Point::new(-1.0, 2.0), Point::new(5.0, -2.0)]);

        assert_eq!(shape1.bbox(), [[-1.0, -2.0], [5.0, 2.0]]);
        assert_eq!(shape2.bbox(), [[-1.0, -2.0], [5.0, 2.0]]);
    }

    #[test]
    fn test_bbox_extended() {
        let rectangles = vec![
            Ellipse::from_corners([Point::new(15.0, -48.0), Point::new(37.0, -27.0)]),
            Ellipse::from_corners([Point::new(15.0, -27.0), Point::new(37.0, -48.0)]),
            Ellipse::from_corners([Point::new(37.0, -48.0), Point::new(15.0, -27.0)]),
            Ellipse::from_corners([Point::new(37.0, -27.0), Point::new(15.0, -48.0)]),
        ];

        for rectangle in rectangles.into_iter() {
            assert_eq!(rectangle.bbox(), [[15.0, -48.0], [37.0, -27.0]]);
        }

        let rectangles = vec![
            Ellipse::from_corners([Point::new(15.0, -24.0), Point::new(60.0, 6.0)]),
            Ellipse::from_corners([Point::new(15.0, 6.0), Point::new(60.0, -24.0)]),
            Ellipse::from_corners([Point::new(60.0, -24.0), Point::new(15.0, 6.0)]),
            Ellipse::from_corners([Point::new(60.0, 6.0), Point::new(15.0, -24.0)]),
        ];

        for rectangle in rectangles.into_iter() {
            assert_eq!(rectangle.bbox(), [[15.0, -24.0], [60.0, 6.0]]);
        }

        let rectangles = vec![
            Ellipse::from_corners([Point::new(-8.0, -32.0), Point::new(16.0, 0.0)]),
            Ellipse::from_corners([Point::new(-8.0, 0.0), Point::new(16.0, -32.0)]),
            Ellipse::from_corners([Point::new(16.0, -32.0), Point::new(-8.0, 0.0)]),
            Ellipse::from_corners([Point::new(16.0, 0.0), Point::new(-8.0, -32.0)]),
        ];

        for rectangle in rectangles.into_iter() {
            assert_eq!(rectangle.bbox(), [[-8.0, -32.0], [16.0, 0.0]]);
        }

        let rectangles = vec![
            Ellipse::from_corners([Point::new(48.0, -19.0), Point::new(78.0, 22.0)]),
            Ellipse::from_corners([Point::new(48.0, 22.0), Point::new(78.0, -19.0)]),
            Ellipse::from_corners([Point::new(78.0, -19.0), Point::new(48.0, 22.0)]),
            Ellipse::from_corners([Point::new(78.0, 22.0), Point::new(48.0, -19.0)]),
        ];

        for rectangle in rectangles.into_iter() {
            assert_eq!(rectangle.bbox(), [[48.0, -19.0], [78.0, 22.0]]);
        }
    }
}