1- use std:: fmt:: Debug ;
1+ use std:: { fmt:: Debug , ops :: Neg } ;
22
33use rand:: { prelude:: Distribution , distributions:: Standard } ;
44use serde:: { Deserialize , Serialize } ;
55
6- use super :: { Delta , Unity , Zero } ;
6+ use super :: { Vec2 , Unity , Zero } ;
77
88/// One of the four cardinal directions.
99#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Serialize , Deserialize ) ]
@@ -14,31 +14,54 @@ pub enum Direction {
1414 Right ,
1515}
1616
17- impl < T > TryFrom < Delta < T > > for Direction where T : Zero + Unity + PartialEq + Debug {
17+ impl Direction {
18+ pub fn approximate_from < T > ( vec2 : Vec2 < T > ) -> Option < Self > where T : Zero + Unity + PartialEq + Neg < Output = T > + PartialOrd + Copy {
19+ if vec2 == Vec2 :: ZERO {
20+ return None ;
21+ }
22+
23+ // See https://www.desmos.com/calculator/472pdoxzqa for visualization
24+ // Note that the y-axis is flipped here, per computer graphics conventions,
25+ // hence the sign flip (-y instead of y).
26+ let Vec2 { x, y } = vec2;
27+ let left_or_up = x < -y;
28+ let right_or_up = -x < -y;
29+ Some (
30+ match ( left_or_up, right_or_up) {
31+ ( true , true ) => Direction :: Up ,
32+ ( true , false ) => Direction :: Left ,
33+ ( false , true ) => Direction :: Right ,
34+ ( false , false ) => Direction :: Down ,
35+ }
36+ )
37+ }
38+ }
39+
40+ impl < T > TryFrom < Vec2 < T > > for Direction where T : Zero + Unity + PartialEq + Debug {
1841 type Error = String ;
1942
20- fn try_from ( delta : Delta < T > ) -> Result < Self , Self :: Error > {
21- if delta == Delta :: UP {
43+ fn try_from ( vec2 : Vec2 < T > ) -> Result < Self , Self :: Error > {
44+ if vec2 == Vec2 :: UP {
2245 Ok ( Direction :: Up )
23- } else if delta == Delta :: DOWN {
46+ } else if vec2 == Vec2 :: DOWN {
2447 Ok ( Direction :: Down )
25- } else if delta == Delta :: LEFT {
48+ } else if vec2 == Vec2 :: LEFT {
2649 Ok ( Direction :: Left )
27- } else if delta == Delta :: RIGHT {
50+ } else if vec2 == Vec2 :: RIGHT {
2851 Ok ( Direction :: Right )
2952 } else {
30- Err ( format ! ( "Not a direction: {:?}" , delta ) )
53+ Err ( format ! ( "Not a direction: {:?}" , vec2 ) )
3154 }
3255 }
3356}
3457
35- impl < T > From < Direction > for Delta < T > where T : Zero + Unity {
58+ impl < T > From < Direction > for Vec2 < T > where T : Zero + Unity {
3659 fn from ( direction : Direction ) -> Self {
3760 match direction {
38- Direction :: Up => Delta :: UP ,
39- Direction :: Down => Delta :: DOWN ,
40- Direction :: Left => Delta :: LEFT ,
41- Direction :: Right => Delta :: RIGHT ,
61+ Direction :: Up => Vec2 :: UP ,
62+ Direction :: Down => Vec2 :: DOWN ,
63+ Direction :: Left => Vec2 :: LEFT ,
64+ Direction :: Right => Vec2 :: RIGHT ,
4265 }
4366 }
4467}
0 commit comments