maker_panel/features/
rect.rs1use geo::{Coordinate, MultiPolygon};
2use std::fmt;
3
4#[derive(Debug, Clone)]
6pub struct Rect<U = super::Unit> {
7 rect: geo::Rect<f64>,
8 inner: U,
9}
10
11impl Rect {
12 pub fn new(top_left: Coordinate<f64>, bottom_right: Coordinate<f64>) -> Self {
14 Self {
15 rect: geo::Rect::new(top_left, bottom_right),
16 inner: super::Unit,
17 }
18 }
19
20 pub fn with_center(center: Coordinate<f64>, width: f64, height: f64) -> Self {
22 Self {
23 rect: geo::Rect::new(
24 center
25 + Coordinate {
26 x: -width / 2.,
27 y: -height / 2.,
28 },
29 center
30 + Coordinate {
31 x: width / 2.,
32 y: height / 2.,
33 },
34 ),
35 inner: super::Unit,
36 }
37 }
38}
39
40impl<U: super::InnerFeature + Clone + std::fmt::Debug> Rect<U> {
41 pub fn with_inner(inner: U) -> Self {
45 let tl: Coordinate<f64> = [-1f64, -1f64].into();
46 let br: Coordinate<f64> = [1f64, 1f64].into();
47 let rect = geo::Rect::new(tl, br);
48 Self { rect, inner }
49 }
50
51 pub fn dimensions(mut self, center: Coordinate<f64>, width: f64, height: f64) -> Self {
53 let rect = geo::Rect::new(
54 center
55 + Coordinate {
56 x: -width / 2.,
57 y: -height / 2.,
58 },
59 center
60 + Coordinate {
61 x: width / 2.,
62 y: height / 2.,
63 },
64 );
65 self.inner.translate(center);
66 Self {
67 rect,
68 inner: self.inner,
69 }
70 }
71
72 pub fn bounds(mut self, top_left: Coordinate<f64>, bottom_right: Coordinate<f64>) -> Self {
74 let rect = geo::Rect::new(top_left, bottom_right);
75 self.inner.translate(rect.center());
76 Self {
77 rect,
78 inner: self.inner,
79 }
80 }
81}
82
83impl<U: super::InnerFeature> fmt::Display for Rect<U> {
84 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85 write!(
86 f,
87 "rect({:?}, {:?}, U = {})",
88 self.rect.min(),
89 self.rect.max(),
90 self.inner
91 )
92 }
93}
94
95impl<U: super::InnerFeature + Clone + std::fmt::Debug> super::Feature for Rect<U> {
96 fn name(&self) -> &'static str {
97 "rect"
98 }
99
100 fn edge_union(&self) -> Option<MultiPolygon<f64>> {
101 Some(self.rect.clone().to_polygon().into())
102 }
103
104 fn translate(&mut self, v: Coordinate<f64>) {
105 use geo::algorithm::translate::Translate;
106 self.rect.translate_inplace(v.x, v.y);
107 self.inner.translate(v);
108 }
109
110 fn interior(&self) -> Vec<super::InnerAtom> {
111 self.inner.atoms()
112 }
113}