maker_panel/features/
r_mount.rs1use super::InnerAtom;
2use geo::{Coordinate, MultiPolygon};
3use std::fmt;
4
5#[derive(Debug, Clone)]
7pub struct RMount {
8 direction: crate::Direction,
9 rect: geo::Rect<f64>,
10 depth: f64,
11}
12
13impl RMount {
14 pub fn new(depth: f64) -> Self {
16 let direction = crate::Direction::Up;
17 let tl: Coordinate<f64> = [-3.15f64, -depth / 2. - 1.].into();
18 let br: Coordinate<f64> = [3.15f64, depth / 2. + 1.].into();
19 let rect = geo::Rect::new(tl, br);
20 Self {
21 direction,
22 rect,
23 depth,
24 }
25 }
26
27 pub fn direction(self, direction: crate::Direction) -> Self {
29 Self { direction, ..self }
30 }
31}
32
33impl fmt::Display for RMount {
34 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35 write!(f, "rmount({:?}, {:?})", self.rect.min(), self.rect.max(),)
36 }
37}
38
39impl super::Feature for RMount {
40 fn name(&self) -> &'static str {
41 "rmount"
42 }
43
44 fn edge_union(&self) -> Option<MultiPolygon<f64>> {
45 let out = self.rect.clone().to_polygon().into();
46 use geo::algorithm::rotate::Rotate;
47 match self.direction {
48 crate::Direction::Up => Some(out),
49 crate::Direction::Down => Some(out.rotate(180.)),
50 crate::Direction::Left => Some(out.rotate(-90.)),
51 crate::Direction::Right => Some(out.rotate(90.)),
52 }
53 }
54
55 fn edge_subtract(&self) -> Option<MultiPolygon<f64>> {
56 use geo_booleanop::boolean::BooleanOp;
57 let center = self.rect.center();
58
59 let channel = geo::Rect::new(
60 Coordinate::<f64>::from([-1.62f64, -self.depth / 2. - 1.]) + center,
61 Coordinate::<f64>::from([1.62f64, self.depth / 2.]) + center,
62 );
63 let nut = geo::Rect::new(
64 Coordinate::<f64>::from([-3.12f64, -1.4]) + center,
65 Coordinate::<f64>::from([3.12f64, 1.4]) + center,
66 );
67
68 let out = MultiPolygon::<f64>::from(channel.to_polygon()).union(&nut.to_polygon());
69
70 let origin = geo::Point::new(0., 0.);
71 use geo::algorithm::rotate::RotatePoint;
72 match self.direction {
73 crate::Direction::Up => Some(out),
74 crate::Direction::Down => Some(out.rotate_around_point(180., origin)),
75 crate::Direction::Left => Some(out.rotate_around_point(-90., origin)),
76 crate::Direction::Right => Some(out.rotate_around_point(90., origin)),
77 }
78 }
79
80 fn translate(&mut self, v: Coordinate<f64>) {
81 use geo::algorithm::translate::Translate;
82 self.rect.translate_inplace(v.x, v.y);
83 }
84
85 fn interior(&self) -> Vec<super::InnerAtom> {
86 let center = self.rect.center();
87 let angle = match self.direction {
88 crate::Direction::Up => 0.,
89 crate::Direction::Down => 180.,
90 crate::Direction::Left => -90.,
91 crate::Direction::Right => 90.,
92 };
93 let origin = geo::Point::new(0., 0.);
94
95 use geo::algorithm::rotate::RotatePoint;
96 vec![
97 InnerAtom::Drill {
98 center: (geo::Point::from([-3.08f64, -1.32]).rotate_around_point(angle, origin)
99 + center.into())
100 .into(),
101 radius: 0.15,
102 plated: false,
103 },
104 InnerAtom::Drill {
105 center: (geo::Point::from([3.08f64, -1.32]).rotate_around_point(angle, origin)
106 + center.into())
107 .into(),
108 radius: 0.15,
109 plated: false,
110 },
111 InnerAtom::Drill {
112 center: (geo::Point::from([-3.08f64, 1.32]).rotate_around_point(angle, origin)
113 + center.into())
114 .into(),
115 radius: 0.15,
116 plated: false,
117 },
118 InnerAtom::Drill {
119 center: (geo::Point::from([3.08f64, 1.32]).rotate_around_point(angle, origin)
120 + center.into())
121 .into(),
122 radius: 0.15,
123 plated: false,
124 },
125 ]
126 }
127}