1extern crate line_drawing;
2
3use line_drawing::{Point, Bresenham, BresenhamCircle};
4
5#[derive(Debug, Copy, Clone, Eq, PartialEq)]
8pub enum Material {
9 Wood,
10 Metal,
11 Rope
12}
13
14#[derive(Debug)]
16pub enum Part {
17 Beam(Beam),
18 Wheel(Wheel)
19}
20
21#[derive(Debug)]
23pub struct Beam {
24 pub start: Point<f64>,
25 pub end: Point<f64>,
26 pub material: Material
27}
28
29impl Beam {
30 pub fn new(start: (i32, i32), end: (i32, i32), material: Material) -> Self {
31 Beam {
32 material,
33
34 start: (start.0 as f64, start.1 as f64),
35 end: (end.0 as f64, end.1 as f64),
36 }
37 }
38
39 pub fn draw(&self, dst: &mut [u32], dst_width: usize, offset: (f64, f64)) {
40 let color = match self.material {
41 Material::Wood => 0x8F563B,
42 Material::Metal => 0x696A6A,
43 Material::Rope => 0xD9A066,
44 };
45
46 let start = ((self.start.0 + offset.0) as i32, (self.start.1 + offset.1) as i32);
47 let end = ((self.end.0 + offset.0) as i32, (self.end.1 + offset.1) as i32);
48 for (x, y) in Bresenham::new(start, end) {
49 dst[x as usize + y as usize * dst_width] = color;
50 }
51 }
52}
53
54#[derive(Debug)]
56pub struct Wheel {
57 pub pos: Point<f64>,
58 pub radius: f64,
59 pub material: Material
60}
61
62impl Wheel {
63 pub fn new(start: (i32, i32), end: (i32, i32), material: Material) -> Self {
64 let dx = (end.0 - start.0) as f64;
65 let dy = (end.1 - start.1) as f64;
66 Wheel {
67 material,
68
69 pos: (start.0 as f64, start.1 as f64),
70 radius: (dx * dx + dy * dy).sqrt()
71 }
72 }
73
74 pub fn draw(&self, dst: &mut [u32], dst_width: usize, offset: (f64, f64)) {
75 let color = match self.material {
76 Material::Wood => 0x8F563B,
77 Material::Metal => 0x696A6A,
78 Material::Rope => 0xD9A066,
79 };
80
81 let pos = ((self.pos.0 + offset.0) as i32, (self.pos.1 + offset.1) as i32);
82 for (x, y) in BresenhamCircle::new(pos.0, pos.1, self.radius as i32) {
83 dst[x as usize + y as usize * dst_width] = color;
84 }
85 }
86}
87
88#[derive(Debug)]
90pub struct Engine {
91 pub pos: Point<f64>,
92 pub parts: Vec<Part>
93}
94
95impl Engine {
96 pub fn new(x: f64, y: f64) -> Self {
98 Engine {
99 pos: (x, y),
100 parts: Vec::new()
101 }
102 }
103
104 pub fn render_to_buffer(&self, dst: &mut [u32], dst_width: usize) {
106 for part in self.parts.iter() {
107 if let &Part::Beam(ref beam) = part {
108 beam.draw(dst, dst_width, self.pos);
109 }
110 if let &Part::Wheel(ref wheel) = part {
111 wheel.draw(dst, dst_width, self.pos);
112 }
113 }
114 }
115
116 pub fn add_beam(&mut self, start: (i32, i32), end: (i32, i32), material: Material) {
118 self.parts.push(Part::Beam(Beam::new(start, end, material)));
119 }
120
121 pub fn add_wheel(&mut self, start: (i32, i32), end: (i32, i32), material: Material) {
123 self.parts.push(Part::Wheel(Wheel::new(start, end, material)));
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 #[test]
130 fn it_works() {
131 assert_eq!(2 + 2, 4);
132 }
133}