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
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! # Polygon
//!
//! A standard trait and set of implementations for managing polygons in rust.
//!
//! ## Output Angles
//! For return values 0 is north and the angle increases clockwise.
//! 
//! ## Output Gradients
//! For output gradients, f64::INFINITY is returned for north, and the gradient decreases
//! clockwise until f64::NEG_INFINITY.

/// Functions for manipulating a polygon.
pub trait Polygon: Sized {

    // Required Implementations

    /// `translate(x, y)`
    ///
    /// Translate polygon by (`x`, `y`).
    fn translate(&self, f64, f64) -> Self;

    /// `rotate_radians(r)`
    ///
    /// Rotate polygon about (0, 0) by `r` radians.
    fn rotate_radians(&self, f64) -> Self;

    /// `angles_radians()`
    ///
    /// Get a slice of all of the angles of lines present in the polygon in radians
    fn angles_radians(&self) -> Vec<f64>;
    
    /// `collides_with(&rhs)`
    ///
    /// Check if polygon collides with another polygon (`rhs`).
    fn collides_with<P: Polygon>(&self, &P) -> Self;

    /// `shadow(r)`
    ///
    /// Returns the shadow cast by the polygon by a light source incident at angle `r` as an initial 
    /// and final position relative to the origin across the normal of `r`.
    fn shadow(&self, f64) -> [f64; 2];

    /// `enlarge(s)`
    ///
    /// Enlarge about (0, 0) with scale factor `s`.
    fn enlarge(&self, f64) -> Self;

    // Derived Implementations

    /// Translate polygon by (`x`, 0)
    fn translate_x(&self, x: f64) -> Self { self.translate(x, 0.0) }

    /// Translate polygon by (0, `y`)
    fn translate_y(&self, y: f64) -> Self { self.translate(0.0, y) }

    /// Rotate polygon about (0, 0) by `r` degrees.
    fn rotate_degrees(&self, r: f64) -> Self { self.rotate_radians(r.to_radians()) }

    /// Get a slice of all the angles of lines present in the polygon in degrees
    fn angles_degrees(& self) -> Vec<f64> { 
        self.angles_radians().iter().map(|a| a.to_degrees()).collect() 
    }

    /// Get a slice of all of the angles of lines present in the polygon as a gradients
    fn angles_gradients(&self) -> Vec<f64> {
        self.angles_radians().iter().map(|a| a.tan().powi(-1)).collect()
    }

    /// Get a slice of all of the angles of normals to lines present in the polygon in radians
    fn normals_radians(&self) -> Vec<f64> {
        self.angles_radians().iter().map(|a| a + std::f64::consts::PI).collect()
    }

    /// Get a slice of all of the angles of normals to lines present in the polygon in degrees
    fn normals_degrees(&self) -> Vec<f64> {
        self.normals_radians().iter().map(|a| a.to_degrees()).collect()   
    }

    /// Get a slice of all of the angles of normals to lines present in the polygon as a gradients
    fn normals_gradients(&self) -> Vec<f64> {
        self.normals_radians().iter().map(|a| -a.tan()).collect()
    }

    /// Rotate polygon about (`x`, `y`) by `r` radians.
    fn rotate_about_radians(&self, x: f64, y: f64, r: f64) -> Self {
        self.translate(-x, -y).rotate_radians(r).translate(x, y)
    }

    /// Rotate polygon about (`x`, `y`) by `r` degrees.
    fn rotate_about_degrees(&self, x: f64, y: f64, r: f64) -> Self {
        self.rotate_about_radians(x, y, r.to_radians())
    }

    /// Enlarge polygon about (`x`, `y`) by a scale factor `s`.
    fn enlarge_about(&self, x: f64, y: f64, s: f64) -> Self {
        self.translate(-x, -y).enlarge(s).translate(x, y)
    }

    // Aliases

    /// Alias for Polygon::translate
    fn trans(&self, x: f64, y: f64) -> Self { self.translate(x, y) }
    /// Alias for Polygon::rotate_radians
    fn rot_rad(&self, r: f64) -> Self { self.rotate_radians(r) }
    /// Alias for Polygon::translate_x
    fn trans_x(&self, x: f64) -> Self { self.translate_x(x) }
    /// Alias for Polygon::translate_y
    fn trans_y(&self, y: f64) -> Self { self.translate_y(y) }
    /// Alias for Polygon::rotate_degrees
    fn rot_deg(&self, r: f64) -> Self { self.rotate_degrees(r) }
    /// Alias for Polygon::rotate_about_radians
    fn rot_about_rad(&self, x: f64, y: f64, r: f64) -> Self { self.rotate_about_radians(x, y, r) }
    /// Alias for Polygon::rotate_about_degrees
    fn rot_about_deg(&self, x: f64, y: f64, r: f64) -> Self { self.rotate_about_degrees(x, y, r) }
    /// Alias for Polygon::angles_radians
    fn ang_rad(&self) -> Vec<f64> { self.angles_radians() }
    /// Alias for Polygon::angles_degrees
    fn ang_deg(&self) -> Vec<f64> { self.angles_degrees() }
    /// Alias for Polygon::angles_gradients
    fn ang_grad(&self) -> Vec<f64> { self.angles_gradients() }
    /// Alias for Polygon::normals_radians
    fn norm_rad(&self) -> Vec<f64> { self.normals_radians() }
    /// Alias for Polygon::normals_degrees
    fn norm_deg(&self) -> Vec<f64> { self.normals_degrees() }
    /// Alias for Polygon::normals_gradients
    fn norm_grad(&self) -> Vec<f64> { self.normals_gradients() }


}