Circle equal division coordinate calculation program
- mathematical principles
- programming
-
- Make a table of trigonometric functions
- Calculate coordinates
- demo program
Principles of mathematics
Assume that the circle N
with a radius of R
is equally divided. The index k
starts at 12 o’clock and is arranged clockwise, then each coordinate point The general calculation formula is:
x
[
k
]
=
R
?
sin
?
(
k
?
2
π
N
)
the y
[
k
]
=
R
?
cos
?
(
k
?
2
π
N
)
x[k] = R\cdot \sin (\frac{k\cdot 2\pi}{N})\ y[k] = R\cdot \cos(\frac{k\cdot 2\pi}{N })
x[k]=R?sin(Nk?2π?)y[k]=R?cos(Nk?2π?)
Assumptions:
- The center of the circle is the origin of coordinates
k
is always less thanN
.- The
k
variable counts from zero
Programming
Using the look-up table method can greatly speed up computers that are not equipped with hardware floating-point operations
Make a trigonometric function table
const unsigned char RH_UTIL__SINE_FUNC[256] = {<!-- --> 0,2,3,5,6,8,9,11,13,14,16,17,19,20,22,23,25,27,28,30,31,33,34,36,37, 39,\ 41,42,44,45,47,48,50,51,53,54,56,57,59,60,62,63,65,67,68,70,71,73,74,76,\ 77,79,80,81,83,84,86,87,89,90,92,93,95,96,98,99,100,102,103,105,106,108,\ 109,110,112,113,115,116,117,119,120,122,123,124,126,127,128,130,131,132,\ 134,135,136,138,139,140,142,143,144,146,147,148,149,151,152,153,154,156,\ 157,158,159,161,162,163,164,165,167,168,169,170,171,172,174,175,176,177,\ 178,179,180,181,183,184,185,186,187,188,189,190,191,192,193,194,195,196,\ 197,198,199,200,201,202,203,204,205,206,207,208,208,209,210,211,212,213,\ 214,215,215,216,217,218,219,220,220,221,222,223,223,224,225,226,226,227,\ 228,228,229,230,231,231,232,232,233,234,234,235,236,236,237,237,238,238,\ 239,240,240,241,241,242,242,243,243,244,244,244,245,245,246,246,247,247,\ 247,248,248,248,249,249,249,250,250,250,251,251,251,252,252,252,252,252,\ 253,253,253,253,253,254,254,254,254,254,254,254,255,255,255,255,255,255,\ 255,255,255,255 };
- Angle interval
deg
?
∈
[
0
,
90
)
?
rad
∈
[
0
,
π
2
)
\deg \in [0, 90) \Leftrightarrow \text{rad} \in [0, \frac{\pi}{2})
deg∈[0,90)?rad∈[0,2π?)
- Sampling accuracy A total of
256
uniform sampling points
It can be converted into arbitrary sine and cosine values by using the trigonometric induction formula, and the derivation process is omitted, see notes for details.
Calculate coordinates
typedef uint8_t u8; typedef int16_t i16; /** * @brief This function is to calculate widget position in a CW direction * @cond - Assume the clock panel size is 240x240 * - Assume ranking in clockwise diesel * - Assume (120,120) as original point * @param rank Item ranking in the list * @param totalNum Total number of items in the list * @param radius Radius of the circle * @return posX X position offset in pixel. If null, do nothing * @return posY Y position offset in pixel. If null, do nothing * @retval Return 0 if success * Return 1 if null pointer was given * Return 2 if parameters are wrong */ int rh_util__posCw( u8 rank, u8 totalNum, u8 radius, i16* posX, i16*posY){<!-- --> if( !posX & amp; & amp; !posY ) return 1; if( totalNum==0 ) return 2; u32 angle = (rank<<10)/totalNum; switch( angle>>8){<!-- --> case 0:{<!-- --> // sin(x) = sin(x); cos(x) = sin(pi/2-x) if(posX) *posX = (radius*RH_UTIL__SINE_FUNC[angle]>>8); if(posY) *posY = (radius*RH_UTIL__SINE_FUNC[0xff-angle]>>8); break; } case 1:{<!-- --> // sin(x + pi/2) = sin(pi/2-x); cos(x + pi/2) = -sin(x) angle & amp;= 0xff; if(posX) *posX = (radius*RH_UTIL__SINE_FUNC[0xff-angle]>>8); if(posY) *posY = -(radius*RH_UTIL__SINE_FUNC[angle]>>8); break; } case 2:{<!-- --> // sin(x + pi) = -sin(x); cos(x + pi) = -sin(pi/2-x) angle & amp;= 0xff; if(posX) *posX = -(radius*RH_UTIL__SINE_FUNC[angle]>>8); if(posY) *posY = -(radius*RH_UTIL__SINE_FUNC[0xff-angle]>>8); break; } case 3:{<!-- --> // sin(x + 2pi/3) = -sin(pi/2-x); cos(x + 2pi/3) = sin(x) angle & amp;= 0xff; if(posX) *posX = -(radius*RH_UTIL__SINE_FUNC[0xff-angle]>>8); if(posY) *posY = (radius*RH_UTIL__SINE_FUNC[angle]>>8); break; } default:{<!-- --> /* Error. rank is bigger than totalNum */ return 2; } } return 0; }
Demo program
int main(int argc, const char * argv[]) {<!-- --> i16 posX=0, posY=0; u8 totalPoints = 16; u8 radius = 120; for(int i=0; i<totalPoints; + + i){<!-- --> rh_util__posCw( i, totalPoints, radius, &posX, &posY); printf( "[%d]: (%d,%d)\ ", i, posX, posY); } return 0; }
[0]: (0,119) [1]: (45,110) [2]: (84,83) [3]: (110,45) [4]: (119,0) [5]: (110,-45) [6]: (83,-84) [7]: (45,-110) [8]: (0,-119) [9]: (-45,-110) [10]: (-84,-83) [11]: (-110,-45) [12]: (-119,0) [13]: (-110,45) [14]: (-83,84) [15]: (-45,110) Program ended with exit code: 0