MCPcopy Create free account
hub / github.com/davidrmiller/biosim4 / asDir

Method asDir

src/basicTypes.cpp:94–112  ·  view source on GitHub ↗

Effectively, we want to check if a coordinate lies in a 45 degree region (22.5 degrees each side) centered on each compass direction. By first rotating the system by 22.5 degrees clockwise the boundaries to these regions become much easier to work with as they just align with the 8 axes. (Thanks to @Asa-Hopkins for this optimization -- drm)

Source from the content-addressed store, hash-verified

92// the boundaries to these regions become much easier to work with as they just align with the 8 axes.
93// (Thanks to @Asa-Hopkins for this optimization -- drm)
94Dir Coord::asDir() const
95{
96 // tanN/tanD is the best rational approximation to tan(22.5) under the constraint that
97 // tanN + tanD < 2**16 (to avoid overflows). We don't care about the scale of the result,
98 // only the ratio of the terms. The actual rotation is (22.5 - 1.5e-8) degrees, whilst
99 // the closest a pair of int16_t's come to any of these lines is 8e-8 degrees, so the result is exact
100 constexpr uint16_t tanN = 13860;
101 constexpr uint16_t tanD = 33461;
102 const Dir conversion[16] { S, C, SW, N, SE, E, N,
103 N, N, N, W, NW, N, NE, N, N};
104
105 const int32_t xp = x * tanD + y * tanN;
106 const int32_t yp = y * tanD - x * tanN;
107
108 // We can easily check which side of the four boundary lines
109 // the point now falls on, giving 16 cases, though only 9 are
110 // possible.
111 return conversion[(yp > 0) * 8 + (xp > 0) * 4 + (yp > xp) * 2 + (yp >= -xp)];
112}
113
114
115Polar Coord::asPolar() const

Callers 2

drainMoveQueueMethod · 0.80
unitTestBasicTypesFunction · 0.80

Calls

no outgoing calls

Tested by 1

unitTestBasicTypesFunction · 0.64