1 /**
2  * @file lv_area.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "../lv_conf_internal.h"
10 
11 #include "lv_area.h"
12 #include "lv_math.h"
13 
14 /*********************
15  *      DEFINES
16  *********************/
17 
18 /**********************
19  *      TYPEDEFS
20  **********************/
21 
22 /**********************
23  *  STATIC PROTOTYPES
24  **********************/
25 
26 static bool lv_point_within_circle(const lv_area_t * area, const lv_point_t * p);
27 
28 /**********************
29  *  STATIC VARIABLES
30  **********************/
31 
32 /**********************
33  *      MACROS
34  **********************/
35 
36 /**********************
37  *   GLOBAL FUNCTIONS
38  **********************/
39 
40 /**
41  * Initialize an area
42  * @param area_p pointer to an area
43  * @param x1 left coordinate of the area
44  * @param y1 top coordinate of the area
45  * @param x2 right coordinate of the area
46  * @param y2 bottom coordinate of the area
47  */
lv_area_set(lv_area_t * area_p,lv_coord_t x1,lv_coord_t y1,lv_coord_t x2,lv_coord_t y2)48 void lv_area_set(lv_area_t * area_p, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2)
49 {
50     area_p->x1 = x1;
51     area_p->y1 = y1;
52     area_p->x2 = x2;
53     area_p->y2 = y2;
54 }
55 
56 /**
57  * Set the width of an area
58  * @param area_p pointer to an area
59  * @param w the new width of the area (w == 1 makes x1 == x2)
60  */
lv_area_set_width(lv_area_t * area_p,lv_coord_t w)61 void lv_area_set_width(lv_area_t * area_p, lv_coord_t w)
62 {
63     area_p->x2 = area_p->x1 + w - 1;
64 }
65 
66 /**
67  * Set the height of an area
68  * @param area_p pointer to an area
69  * @param h the new height of the area (h == 1 makes y1 == y2)
70  */
lv_area_set_height(lv_area_t * area_p,lv_coord_t h)71 void lv_area_set_height(lv_area_t * area_p, lv_coord_t h)
72 {
73     area_p->y2 = area_p->y1 + h - 1;
74 }
75 
76 /**
77  * Set the position of an area (width and height will be kept)
78  * @param area_p pointer to an area
79  * @param x the new x coordinate of the area
80  * @param y the new y coordinate of the area
81  */
_lv_area_set_pos(lv_area_t * area_p,lv_coord_t x,lv_coord_t y)82 void _lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y)
83 {
84     lv_coord_t w = lv_area_get_width(area_p);
85     lv_coord_t h = lv_area_get_height(area_p);
86     area_p->x1   = x;
87     area_p->y1   = y;
88     lv_area_set_width(area_p, w);
89     lv_area_set_height(area_p, h);
90 }
91 
92 /**
93  * Return with area of an area (x * y)
94  * @param area_p pointer to an area
95  * @return size of area
96  */
lv_area_get_size(const lv_area_t * area_p)97 uint32_t lv_area_get_size(const lv_area_t * area_p)
98 {
99     uint32_t size;
100 
101     size = (uint32_t)(area_p->x2 - area_p->x1 + 1) * (area_p->y2 - area_p->y1 + 1);
102 
103     return size;
104 }
105 
lv_area_increase(lv_area_t * area,lv_coord_t w_extra,lv_coord_t h_extra)106 void lv_area_increase(lv_area_t * area, lv_coord_t w_extra, lv_coord_t h_extra)
107 {
108     area->x1 -= w_extra;
109     area->x2 += w_extra;
110     area->y1 -= h_extra;
111     area->y2 += h_extra;
112 }
113 
lv_area_move(lv_area_t * area,lv_coord_t x_ofs,lv_coord_t y_ofs)114 void lv_area_move(lv_area_t * area, lv_coord_t x_ofs, lv_coord_t y_ofs)
115 {
116     area->x1 += x_ofs;
117     area->x2 += x_ofs;
118     area->y1 += y_ofs;
119     area->y2 += y_ofs;
120 }
121 
122 /**
123  * Get the common parts of two areas
124  * @param res_p pointer to an area, the result will be stored here
125  * @param a1_p pointer to the first area
126  * @param a2_p pointer to the second area
127  * @return false: the two area has NO common parts, res_p is invalid
128  */
_lv_area_intersect(lv_area_t * res_p,const lv_area_t * a1_p,const lv_area_t * a2_p)129 bool _lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)
130 {
131     /*Get the smaller area from 'a1_p' and 'a2_p'*/
132     res_p->x1 = LV_MAX(a1_p->x1, a2_p->x1);
133     res_p->y1 = LV_MAX(a1_p->y1, a2_p->y1);
134     res_p->x2 = LV_MIN(a1_p->x2, a2_p->x2);
135     res_p->y2 = LV_MIN(a1_p->y2, a2_p->y2);
136 
137     /*If x1 or y1 greater than x2 or y2 then the areas union is empty*/
138     bool union_ok = true;
139     if((res_p->x1 > res_p->x2) || (res_p->y1 > res_p->y2)) {
140         union_ok = false;
141     }
142 
143     return union_ok;
144 }
145 
146 /**
147  * Get resulting sub areas after removing the common parts of two areas from the first area
148  * @param res_p pointer to an array of areas with a count of 4, the resulting areas will be stored here
149  * @param a1_p pointer to the first area
150  * @param a2_p pointer to the second area
151  * @return number of results or -1 if no intersect
152  */
_lv_area_diff(lv_area_t * res_p,const lv_area_t * a1_p,const lv_area_t * a2_p)153 int8_t _lv_area_diff(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)
154 {
155     /*Areas have no common parts*/
156     if(!_lv_area_is_on(a1_p, a2_p)) return -1;
157 
158     /*No remaining areas after removing common parts*/
159     if(_lv_area_is_in(a1_p, a2_p, 0)) return 0;
160 
161     /*Result counter*/
162     int8_t res_c = 0;
163 
164     /*Get required information*/
165     lv_area_t n;
166     lv_coord_t a1_w = lv_area_get_width(a1_p) - 1;
167     lv_coord_t a1_h = lv_area_get_height(a1_p) - 1;
168 
169     /*Compute top rectangle*/
170     lv_coord_t th = a2_p->y1 - a1_p->y1;
171     if(th > 0) {
172         n.x1 = a1_p->x1;
173         n.y1 = a1_p->y1;
174         n.x2 = a1_p->x2;
175         n.y2 = a1_p->y1 + th;
176         res_p[res_c++] = n;
177     }
178 
179     /*Compute the bottom rectangle*/
180     lv_coord_t bh = a1_h - (a2_p->y2 - a1_p->y1);
181     if(bh > 0 && a2_p->y2 < a1_p->y2) {
182         n.x1 = a1_p->x1;
183         n.y1 = a2_p->y2;
184         n.x2 = a1_p->x2;
185         n.y2 = a2_p->y2 + bh;
186         res_p[res_c++] = n;
187     }
188 
189     /*Compute side height*/
190     lv_coord_t y1 = a2_p->y1 > a1_p->y1 ? a2_p->y1 : a1_p->y1;
191     lv_coord_t y2 = a2_p->y2 < a1_p->y2 ? a2_p->y2 : a1_p->y2;
192     lv_coord_t sh = y2 - y1;
193 
194     /*Compute the left rectangle*/
195     lv_coord_t lw = a2_p->x1 - a1_p->x1;
196     if(lw > 0 && sh > 0) {
197         n.x1 = a1_p->x1;
198         n.y1 = y1;
199         n.x2 = a1_p->x1 + lw;
200         n.y2 = y1 + sh;
201         res_p[res_c++] = n;
202     }
203 
204     /*Compute the right rectangle*/
205     lv_coord_t rw = a1_w - (a2_p->x2 - a1_p->x1);
206     if(rw > 0) {
207         n.x1 = a2_p->x2;
208         n.y1 = y1;
209         n.x2 = a2_p->x2 + rw;
210         n.y2 = y1 + sh;
211         res_p[res_c++] = n;
212     }
213 
214     //Return number of results
215     return res_c;
216 }
217 
218 /**
219  * Join two areas into a third which involves the other two
220  * @param res_p pointer to an area, the result will be stored here
221  * @param a1_p pointer to the first area
222  * @param a2_p pointer to the second area
223  */
_lv_area_join(lv_area_t * a_res_p,const lv_area_t * a1_p,const lv_area_t * a2_p)224 void _lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)
225 {
226     a_res_p->x1 = LV_MIN(a1_p->x1, a2_p->x1);
227     a_res_p->y1 = LV_MIN(a1_p->y1, a2_p->y1);
228     a_res_p->x2 = LV_MAX(a1_p->x2, a2_p->x2);
229     a_res_p->y2 = LV_MAX(a1_p->y2, a2_p->y2);
230 }
231 
232 /**
233  * Check if a point is on an area
234  * @param a_p pointer to an area
235  * @param p_p pointer to a point
236  * @param radius radius of area (e.g. for rounded rectangle)
237  * @return false:the point is out of the area
238  */
_lv_area_is_point_on(const lv_area_t * a_p,const lv_point_t * p_p,lv_coord_t radius)239 bool _lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, lv_coord_t radius)
240 {
241     /*First check the basic area*/
242     bool is_on_rect = false;
243     if((p_p->x >= a_p->x1 && p_p->x <= a_p->x2) && ((p_p->y >= a_p->y1 && p_p->y <= a_p->y2))) {
244         is_on_rect = true;
245     }
246     if(!is_on_rect)
247         return false;
248     /*Now handle potential rounded rectangles*/
249     if(radius <= 0) {
250         /*No radius, it is within the rectangle*/
251         return true;
252     }
253     lv_coord_t w = lv_area_get_width(a_p) / 2;
254     lv_coord_t h = lv_area_get_height(a_p) / 2;
255     lv_coord_t max_radius = LV_MIN(w, h);
256     if(radius > max_radius)
257         radius = max_radius;
258 
259     /*Check if it's in one of the corners*/
260     lv_area_t corner_area;
261     /*Top left*/
262     corner_area.x1 = a_p->x1;
263     corner_area.x2 = a_p->x1 + radius;
264     corner_area.y1 = a_p->y1;
265     corner_area.y2 = a_p->y1 + radius;
266     if(_lv_area_is_point_on(&corner_area, p_p, 0)) {
267         corner_area.x2 += radius;
268         corner_area.y2 += radius;
269         return lv_point_within_circle(&corner_area, p_p);
270     }
271     /*Bottom left*/
272     corner_area.y1 = a_p->y2 - radius;
273     corner_area.y2 = a_p->y2;
274     if(_lv_area_is_point_on(&corner_area, p_p, 0)) {
275         corner_area.x2 += radius;
276         corner_area.y1 -= radius;
277         return lv_point_within_circle(&corner_area, p_p);
278     }
279     /*Bottom right*/
280     corner_area.x1 = a_p->x2 - radius;
281     corner_area.x2 = a_p->x2;
282     if(_lv_area_is_point_on(&corner_area, p_p, 0)) {
283         corner_area.x1 -= radius;
284         corner_area.y1 -= radius;
285         return lv_point_within_circle(&corner_area, p_p);
286     }
287     /*Top right*/
288     corner_area.y1 = a_p->y1;
289     corner_area.y2 = a_p->y1 + radius;
290     if(_lv_area_is_point_on(&corner_area, p_p, 0)) {
291         corner_area.x1 -= radius;
292         corner_area.y2 += radius;
293         return lv_point_within_circle(&corner_area, p_p);
294     }
295     /*Not within corners*/
296     return true;
297 }
298 
299 /**
300  * Check if two area has common parts
301  * @param a1_p pointer to an area.
302  * @param a2_p pointer to an other area
303  * @return false: a1_p and a2_p has no common parts
304  */
_lv_area_is_on(const lv_area_t * a1_p,const lv_area_t * a2_p)305 bool _lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p)
306 {
307     if((a1_p->x1 <= a2_p->x2) && (a1_p->x2 >= a2_p->x1) && (a1_p->y1 <= a2_p->y2) && (a1_p->y2 >= a2_p->y1)) {
308         return true;
309     }
310     else {
311         return false;
312     }
313 }
314 
315 /**
316  * Check if an area is fully on an other
317  * @param ain_p pointer to an area which could be in 'aholder_p'
318  * @param aholder_p pointer to an area which could involve 'ain_p'
319  * @param radius radius of `aholder_p` (e.g. for rounded rectangle)
320  * @return true: `ain_p` is fully inside `aholder_p`
321  */
_lv_area_is_in(const lv_area_t * ain_p,const lv_area_t * aholder_p,lv_coord_t radius)322 bool _lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, lv_coord_t radius)
323 {
324     bool is_in = false;
325 
326     if(ain_p->x1 >= aholder_p->x1 && ain_p->y1 >= aholder_p->y1 && ain_p->x2 <= aholder_p->x2 &&
327        ain_p->y2 <= aholder_p->y2) {
328         is_in = true;
329     }
330 
331     if(!is_in) return false;
332     if(radius == 0) return true;
333 
334     /*Check if the corner points are inside the radius or not*/
335     lv_point_t p;
336 
337     p.x = ain_p->x1;
338     p.y = ain_p->y1;
339     if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
340 
341     p.x = ain_p->x2;
342     p.y = ain_p->y1;
343     if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
344 
345     p.x = ain_p->x1;
346     p.y = ain_p->y2;
347     if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
348 
349     p.x = ain_p->x2;
350     p.y = ain_p->y2;
351     if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false;
352 
353     return true;
354 }
355 
356 /**
357  * Check if an area is fully out of an other
358  * @param aout_p pointer to an area which could be in 'aholder_p'
359  * @param aholder_p pointer to an area which could involve 'ain_p'
360  * @param radius radius of `aholder_p` (e.g. for rounded rectangle)
361  * @return true: `aout_p` is fully outside `aholder_p`
362  */
_lv_area_is_out(const lv_area_t * aout_p,const lv_area_t * aholder_p,lv_coord_t radius)363 bool _lv_area_is_out(const lv_area_t * aout_p, const lv_area_t * aholder_p, lv_coord_t radius)
364 {
365     if(aout_p->x2 < aholder_p->x1 || aout_p->y2 < aholder_p->y1 || aout_p->x1 > aholder_p->x2 ||
366        aout_p->y1 > aholder_p->y2) {
367         return true;
368     }
369 
370     if(radius == 0) return false;
371 
372     /*Check if the corner points are outside the radius or not*/
373     lv_point_t p;
374 
375     p.x = aout_p->x1;
376     p.y = aout_p->y1;
377     if(_lv_area_is_point_on(aholder_p, &p, radius)) return false;
378 
379     p.x = aout_p->x2;
380     p.y = aout_p->y1;
381     if(_lv_area_is_point_on(aholder_p, &p, radius)) return false;
382 
383     p.x = aout_p->x1;
384     p.y = aout_p->y2;
385     if(_lv_area_is_point_on(aholder_p, &p, radius)) return false;
386 
387     p.x = aout_p->x2;
388     p.y = aout_p->y2;
389     if(_lv_area_is_point_on(aholder_p, &p, radius)) return false;
390 
391     return true;
392 }
393 
_lv_area_is_equal(const lv_area_t * a,const lv_area_t * b)394 bool _lv_area_is_equal(const lv_area_t * a, const lv_area_t * b)
395 {
396     return a->x1 == b->x1 && a->x2 == b->x2 && a->y1 == b->y1 && a->y2 == b->y2;
397 }
398 
399 /**
400  * Align an area to an other
401  * @param base an are where the other will be aligned
402  * @param to_align the area to align
403  * @param align `LV_ALIGN_...`
404  * @param res x/y coordinates where `to_align` align area should be placed
405  */
lv_area_align(const lv_area_t * base,lv_area_t * to_align,lv_align_t align,lv_coord_t ofs_x,lv_coord_t ofs_y)406 void lv_area_align(const lv_area_t * base, lv_area_t * to_align, lv_align_t align, lv_coord_t ofs_x, lv_coord_t ofs_y)
407 {
408 
409     lv_coord_t x;
410     lv_coord_t y;
411     switch(align) {
412         case LV_ALIGN_CENTER:
413             x = lv_area_get_width(base) / 2 - lv_area_get_width(to_align) / 2;
414             y = lv_area_get_height(base) / 2 - lv_area_get_height(to_align) / 2;
415             break;
416 
417         case LV_ALIGN_TOP_LEFT:
418             x = 0;
419             y = 0;
420             break;
421         case LV_ALIGN_TOP_MID:
422             x = lv_area_get_width(base) / 2 - lv_area_get_width(to_align) / 2;
423             y = 0;
424             break;
425 
426         case LV_ALIGN_TOP_RIGHT:
427             x = lv_area_get_width(base) - lv_area_get_width(to_align);
428             y = 0;
429             break;
430 
431         case LV_ALIGN_BOTTOM_LEFT:
432             x = 0;
433             y = lv_area_get_height(base) - lv_area_get_height(to_align);
434             break;
435         case LV_ALIGN_BOTTOM_MID:
436             x = lv_area_get_width(base) / 2 - lv_area_get_width(to_align) / 2;
437             y = lv_area_get_height(base) - lv_area_get_height(to_align);
438             break;
439 
440         case LV_ALIGN_BOTTOM_RIGHT:
441             x = lv_area_get_width(base) - lv_area_get_width(to_align);
442             y = lv_area_get_height(base) - lv_area_get_height(to_align);
443             break;
444 
445         case LV_ALIGN_LEFT_MID:
446             x = 0;
447             y = lv_area_get_height(base) / 2 - lv_area_get_height(to_align) / 2;
448             break;
449 
450         case LV_ALIGN_RIGHT_MID:
451             x = lv_area_get_width(base) - lv_area_get_width(to_align);
452             y = lv_area_get_height(base) / 2 - lv_area_get_height(to_align) / 2;
453             break;
454 
455         case LV_ALIGN_OUT_TOP_LEFT:
456             x = 0;
457             y = -lv_area_get_height(to_align);
458             break;
459 
460         case LV_ALIGN_OUT_TOP_MID:
461             x = lv_area_get_width(base) / 2 - lv_area_get_width(to_align) / 2;
462             y = -lv_area_get_height(to_align);
463             break;
464 
465         case LV_ALIGN_OUT_TOP_RIGHT:
466             x = lv_area_get_width(base) - lv_area_get_width(to_align);
467             y = -lv_area_get_height(to_align);
468             break;
469 
470         case LV_ALIGN_OUT_BOTTOM_LEFT:
471             x = 0;
472             y = lv_area_get_height(base);
473             break;
474 
475         case LV_ALIGN_OUT_BOTTOM_MID:
476             x = lv_area_get_width(base) / 2 - lv_area_get_width(to_align) / 2;
477             y = lv_area_get_height(base);
478             break;
479 
480         case LV_ALIGN_OUT_BOTTOM_RIGHT:
481             x = lv_area_get_width(base) - lv_area_get_width(to_align);
482             y = lv_area_get_height(base);
483             break;
484 
485         case LV_ALIGN_OUT_LEFT_TOP:
486             x = -lv_area_get_width(to_align);
487             y = 0;
488             break;
489 
490         case LV_ALIGN_OUT_LEFT_MID:
491             x = -lv_area_get_width(to_align);
492             y = lv_area_get_height(base) / 2 - lv_area_get_height(to_align) / 2;
493             break;
494 
495         case LV_ALIGN_OUT_LEFT_BOTTOM:
496             x = -lv_area_get_width(to_align);
497             y = lv_area_get_height(base) - lv_area_get_height(to_align);
498             break;
499 
500         case LV_ALIGN_OUT_RIGHT_TOP:
501             x = lv_area_get_width(base);
502             y = 0;
503             break;
504 
505         case LV_ALIGN_OUT_RIGHT_MID:
506             x = lv_area_get_width(base);
507             y = lv_area_get_height(base) / 2 - lv_area_get_height(to_align) / 2;
508             break;
509 
510         case LV_ALIGN_OUT_RIGHT_BOTTOM:
511             x = lv_area_get_width(base);
512             y = lv_area_get_height(base) - lv_area_get_height(to_align);
513             break;
514         default:
515             x = 0;
516             y = 0;
517             break;
518     }
519 
520     x += base->x1;
521     y += base->y1;
522 
523     lv_coord_t w = lv_area_get_width(to_align);
524     lv_coord_t h = lv_area_get_height(to_align);
525     to_align->x1 = x + ofs_x;
526     to_align->y1 = y + ofs_y;
527     to_align->x2 = to_align->x1 + w - 1;
528     to_align->y2 = to_align->y1 + h - 1;
529 }
530 
531 #define _LV_TRANSFORM_TRIGO_SHIFT 10
lv_point_transform(lv_point_t * p,int32_t angle,int32_t zoom,const lv_point_t * pivot)532 void lv_point_transform(lv_point_t * p, int32_t angle, int32_t zoom, const lv_point_t * pivot)
533 {
534     if(angle == 0 && zoom == 256) {
535         return;
536     }
537 
538     p->x -= pivot->x;
539     p->y -= pivot->y;
540 
541     if(angle == 0) {
542         p->x = (((int32_t)(p->x) * zoom) >> 8) + pivot->x;
543         p->y = (((int32_t)(p->y) * zoom) >> 8) + pivot->y;
544         return;
545     }
546 
547     static int32_t angle_prev = INT32_MIN;
548     static int32_t sinma;
549     static int32_t cosma;
550     if(angle_prev != angle) {
551         int32_t angle_limited = angle;
552         if(angle_limited > 3600) angle_limited -= 3600;
553         if(angle_limited < 0) angle_limited += 3600;
554 
555         int32_t angle_low = angle_limited / 10;
556         int32_t angle_high = angle_low + 1;
557         int32_t angle_rem = angle_limited  - (angle_low * 10);
558 
559         int32_t s1 = lv_trigo_sin(angle_low);
560         int32_t s2 = lv_trigo_sin(angle_high);
561 
562         int32_t c1 = lv_trigo_sin(angle_low + 90);
563         int32_t c2 = lv_trigo_sin(angle_high + 90);
564 
565         sinma = (s1 * (10 - angle_rem) + s2 * angle_rem) / 10;
566         cosma = (c1 * (10 - angle_rem) + c2 * angle_rem) / 10;
567         sinma = sinma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT);
568         cosma = cosma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT);
569         angle_prev = angle;
570     }
571     int32_t x = p->x;
572     int32_t y = p->y;
573     if(zoom == 256) {
574         p->x = ((cosma * x - sinma * y) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x;
575         p->y = ((sinma * x + cosma * y) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y;
576     }
577     else {
578         p->x = (((cosma * x - sinma * y) * zoom) >> (_LV_TRANSFORM_TRIGO_SHIFT + 8)) + pivot->x;
579         p->y = (((sinma * x + cosma * y) * zoom) >> (_LV_TRANSFORM_TRIGO_SHIFT + 8)) + pivot->y;
580     }
581 }
582 
583 
584 /**********************
585  *   STATIC FUNCTIONS
586  **********************/
587 
lv_point_within_circle(const lv_area_t * area,const lv_point_t * p)588 static bool lv_point_within_circle(const lv_area_t * area, const lv_point_t * p)
589 {
590     lv_coord_t r = (area->x2 - area->x1) / 2;
591 
592     /*Circle center*/
593     lv_coord_t cx = area->x1 + r;
594     lv_coord_t cy = area->y1 + r;
595 
596     /*Simplify the code by moving everything to (0, 0)*/
597     lv_coord_t px = p->x - cx;
598     lv_coord_t py = p->y - cy;
599 
600     uint32_t r_sqrd = r * r;
601     uint32_t dist = (px * px) + (py * py);
602 
603     if(dist <= r_sqrd)
604         return true;
605     else
606         return false;
607 }
608