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