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
}
}
|