use diaphragm_core::{ core_shapes::StraightPath, types::{Float, Point2D, ShapeContext}, ComplexShape, DrawResult, Drawable, SolverContext, }; #[derive(Clone)] pub struct Explode { pub top_left: Point2D, pub top_right: Point2D, pub bottom_left: Point2D, pub bottom_right: Point2D, pub arm_length: Float, } impl ComplexShape for Explode { fn draw(&self, context: &ShapeContext, solver: &mut dyn SolverContext) -> DrawResult { let mut result = DrawResult::new(); let wanted_top = solver.float_min(&[self.top_left.y(), self.top_right.y()]); let wanted_left = solver.float_min(&[self.top_left.x(), self.bottom_left.x()]); let wanted_bottom = solver.float_max(&[self.bottom_left.x(), self.bottom_right.x()]); let wanted_right = solver.float_max(&[self.top_right.y(), self.bottom_right.y()]); let bounds_top = context.bounds().top(solver); let bounds_left = context.bounds().left(solver); let bounds_bottom = context.bounds().bottom(solver); let bounds_right = context.bounds().right(solver); // TODO: add a facility to help this? let bounds_top_constraint = solver.float_eq(bounds_top, wanted_top); solver.constrain(bounds_top_constraint); let bounds_left_constraint = solver.float_eq(bounds_left, wanted_left); solver.constrain(bounds_left_constraint); let bounds_bottom_constraint = solver.float_eq(bounds_bottom, wanted_bottom); solver.constrain(bounds_bottom_constraint); let bounds_right_constraint = solver.float_eq(bounds_right, wanted_right); solver.constrain(bounds_right_constraint); let top_left_arm_bottom = Point2D::new( self.top_left.x(), solver.float_add(&[self.top_left.y(), self.arm_length]), ); let bottom_left_arm_top = Point2D::new( self.bottom_left.x(), solver.float_sub(&[self.bottom_left.y(), self.arm_length]), ); result.push(Drawable::new( StraightPath::new(vec![ self.top_left.clone(), top_left_arm_bottom, bottom_left_arm_top, self.bottom_left.clone(), ]), context.clone(), )); let top_right_arm_bottom = Point2D::new( self.top_right.x(), solver.float_add(&[self.top_right.y(), self.arm_length]), ); let bottom_right_arm_top = Point2D::new( self.bottom_right.x(), solver.float_sub(&[self.bottom_right.y(), self.arm_length]), ); result.push(Drawable::new( StraightPath::new(vec![ self.top_right.clone(), top_right_arm_bottom, bottom_right_arm_top, self.bottom_right.clone(), ]), context.clone(), )); result } }