summaryrefslogtreecommitdiffstats
path: root/examples/lib-dfscq-log/src/explode.rs
blob: aeb85bdf32d4c96ce3efc080f18bb3191601eca8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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
    }
}