1 //! Draw Line 2 3 use {types, triangulation, DrawState, Graphics}; 4 use types::{Color, Radius}; 5 use math::{Matrix2d, Scalar}; 6 7 /// The shape of the line 8 #[derive(Copy, Clone)] 9 pub enum Shape { 10 /// Square edges 11 Square, 12 /// Round edges 13 Round, 14 /// Bevel edges 15 Bevel, 16 } 17 18 /// A colored line with a default border radius 19 #[derive(Copy, Clone)] 20 pub struct Line { 21 /// The line color 22 pub color: Color, 23 /// The line radius 24 pub radius: Radius, 25 /// The line shape 26 pub shape: Shape, 27 } 28 29 impl Line { 30 /// Creates a new line new(color: Color, radius: Radius) -> Line31 pub fn new(color: Color, radius: Radius) -> Line { 32 Line { 33 color: color, 34 radius: radius, 35 shape: Shape::Square, 36 } 37 } 38 39 /// Creates a new line new_round(color: Color, radius: Radius) -> Line40 pub fn new_round(color: Color, radius: Radius) -> Line { 41 Line { 42 color: color, 43 radius: radius, 44 shape: Shape::Round, 45 } 46 } 47 48 /// Sets color. color(mut self, value: Color) -> Self49 pub fn color(mut self, value: Color) -> Self { 50 self.color = value; 51 self 52 } 53 54 /// Sets radius. radius(mut self, value: Radius) -> Self55 pub fn radius(mut self, value: Radius) -> Self { 56 self.radius = value; 57 self 58 } 59 60 /// Sets width. width(mut self, value: types::Width) -> Self61 pub fn width(mut self, value: types::Width) -> Self { 62 self.radius = 0.5 * value; 63 self 64 } 65 66 /// Sets shape. shape(mut self, value: Shape) -> Self67 pub fn shape(mut self, value: Shape) -> Self { 68 self.shape = value; 69 self 70 } 71 72 /// Draws line using default method between points. 73 #[inline(always)] draw_from_to<P: Into<types::Vec2d>, G>(&self, from: P, to: P, draw_state: &DrawState, transform: Matrix2d, g: &mut G) where G: Graphics74 pub fn draw_from_to<P: Into<types::Vec2d>, G>(&self, 75 from: P, 76 to: P, 77 draw_state: &DrawState, 78 transform: Matrix2d, 79 g: &mut G) 80 where G: Graphics 81 { 82 let from: types::Vec2d = from.into(); 83 let to: types::Vec2d = to.into(); 84 g.line(self, [from[0], from[1], to[0], to[1]], draw_state, transform); 85 } 86 87 /// Draws line using default method. 88 #[inline(always)] draw<L: Into<types::Line>, G>(&self, line: L, draw_state: &DrawState, transform: Matrix2d, g: &mut G) where G: Graphics89 pub fn draw<L: Into<types::Line>, G>(&self, 90 line: L, 91 draw_state: &DrawState, 92 transform: Matrix2d, 93 g: &mut G) 94 where G: Graphics 95 { 96 g.line(self, line, draw_state, transform); 97 } 98 99 /// Draws line using triangulation. draw_tri<L: Into<types::Line>, G>(&self, line: L, draw_state: &DrawState, transform: Matrix2d, g: &mut G) where G: Graphics100 pub fn draw_tri<L: Into<types::Line>, G>(&self, 101 line: L, 102 draw_state: &DrawState, 103 transform: Matrix2d, 104 g: &mut G) 105 where G: Graphics 106 { 107 let line = line.into(); 108 match self.shape { 109 Shape::Square => { 110 g.tri_list(draw_state, &self.color, |f| { 111 triangulation::with_round_border_line_tri_list(2, 112 transform, 113 line, 114 self.radius, 115 |vertices| f(vertices)) 116 }); 117 } 118 Shape::Round => { 119 g.tri_list(draw_state, &self.color, |f| { 120 triangulation::with_round_border_line_tri_list(64, 121 transform, 122 line, 123 self.radius, 124 |vertices| f(vertices)) 125 }); 126 } 127 Shape::Bevel => { 128 g.tri_list(draw_state, &self.color, |f| { 129 triangulation::with_round_border_line_tri_list(3, 130 transform, 131 line, 132 self.radius, 133 |vertices| f(vertices)) 134 }); 135 } 136 } 137 } 138 139 /// Draws an arrow 140 /// 141 /// Head size is the sides of the triangle 142 /// between the arrow hooks and the line draw_arrow<L: Into<types::Line>, G>(&self, line: L, head_size: Scalar, draw_state: &DrawState, transform: Matrix2d, g: &mut G) where G: Graphics143 pub fn draw_arrow<L: Into<types::Line>, G>(&self, 144 line: L, 145 head_size: Scalar, 146 draw_state: &DrawState, 147 transform: Matrix2d, 148 g: &mut G) 149 where G: Graphics 150 { 151 use Transformed; 152 153 let line = line.into(); 154 self.draw(line, draw_state, transform, g); 155 let diff = [line[2] - line[0], line[3] - line[1]]; 156 let arrow_head = transform.trans(line[2], line[3]) 157 .orient(diff[0], diff[1]); 158 self.draw([-head_size, head_size, 0.0, 0.0], draw_state, arrow_head, g); 159 self.draw([-head_size, -head_size, 0.0, 0.0], 160 draw_state, 161 arrow_head, 162 g); 163 } 164 } 165 166 #[cfg(test)] 167 mod test { 168 use super::*; 169 170 #[test] test_line()171 fn test_line() { 172 use Colored; 173 174 let _line = Line::new([0.0; 4], 3.0) 175 .color([1.0; 4]) 176 .radius(3.0) 177 .shape(Shape::Round) 178 .hue_deg(1.0); 179 } 180 } 181