Blender V4.3
rct.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include <math.h>
12#include <stdio.h>
13#include <stdlib.h>
14
15#include <float.h>
16#include <limits.h>
17
18#include "BLI_math_base.h"
19#include "BLI_rect.h"
20#include "BLI_utildefines.h"
21
22#include "DNA_vec_types.h"
23
24/* avoid including BLI_math */
25static void unit_m4(float m[4][4]);
26
27bool BLI_rcti_is_empty(const rcti *rect)
28{
29 return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
30}
31
32bool BLI_rctf_is_empty(const rctf *rect)
33{
34 return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
35}
36
37bool BLI_rcti_isect_x(const rcti *rect, const int x)
38{
39 if (x < rect->xmin) {
40 return false;
41 }
42 if (x > rect->xmax) {
43 return false;
44 }
45 return true;
46}
47
48bool BLI_rcti_isect_y(const rcti *rect, const int y)
49{
50 if (y < rect->ymin) {
51 return false;
52 }
53 if (y > rect->ymax) {
54 return false;
55 }
56 return true;
57}
58
59bool BLI_rcti_isect_pt(const rcti *rect, const int x, const int y)
60{
61 if (x < rect->xmin) {
62 return false;
63 }
64 if (x > rect->xmax) {
65 return false;
66 }
67 if (y < rect->ymin) {
68 return false;
69 }
70 if (y > rect->ymax) {
71 return false;
72 }
73 return true;
74}
75
76bool BLI_rcti_isect_pt_v(const rcti *rect, const int xy[2])
77{
78 if (xy[0] < rect->xmin) {
79 return false;
80 }
81 if (xy[0] > rect->xmax) {
82 return false;
83 }
84 if (xy[1] < rect->ymin) {
85 return false;
86 }
87 if (xy[1] > rect->ymax) {
88 return false;
89 }
90 return true;
91}
92
93bool BLI_rctf_isect_x(const rctf *rect, const float x)
94{
95 if (x < rect->xmin) {
96 return false;
97 }
98 if (x > rect->xmax) {
99 return false;
100 }
101 return true;
102}
103
104bool BLI_rctf_isect_y(const rctf *rect, const float y)
105{
106 if (y < rect->ymin) {
107 return false;
108 }
109 if (y > rect->ymax) {
110 return false;
111 }
112 return true;
113}
114
115bool BLI_rctf_isect_pt(const rctf *rect, const float x, const float y)
116{
117 if (x < rect->xmin) {
118 return false;
119 }
120 if (x > rect->xmax) {
121 return false;
122 }
123 if (y < rect->ymin) {
124 return false;
125 }
126 if (y > rect->ymax) {
127 return false;
128 }
129 return true;
130}
131
132bool BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2])
133{
134 if (xy[0] < rect->xmin) {
135 return false;
136 }
137 if (xy[0] > rect->xmax) {
138 return false;
139 }
140 if (xy[1] < rect->ymin) {
141 return false;
142 }
143 if (xy[1] > rect->ymax) {
144 return false;
145 }
146 return true;
147}
148
149int BLI_rcti_length_x(const rcti *rect, const int x)
150{
151 if (x < rect->xmin) {
152 return rect->xmin - x;
153 }
154 if (x > rect->xmax) {
155 return x - rect->xmax;
156 }
157 return 0;
158}
159
160int BLI_rcti_length_y(const rcti *rect, const int y)
161{
162 if (y < rect->ymin) {
163 return rect->ymin - y;
164 }
165 if (y > rect->ymax) {
166 return y - rect->ymax;
167 }
168 return 0;
169}
170
171float BLI_rctf_length_x(const rctf *rect, const float x)
172{
173 if (x < rect->xmin) {
174 return rect->xmin - x;
175 }
176 if (x > rect->xmax) {
177 return x - rect->xmax;
178 }
179 return 0.0f;
180}
181
182float BLI_rctf_length_y(const rctf *rect, const float y)
183{
184 if (y < rect->ymin) {
185 return rect->ymin - y;
186 }
187 if (y > rect->ymax) {
188 return y - rect->ymax;
189 }
190 return 0.0f;
191}
192
193bool BLI_rctf_inside_rctf(const rctf *rct_a, const rctf *rct_b)
194{
195 return ((rct_a->xmin <= rct_b->xmin) && (rct_a->xmax >= rct_b->xmax) &&
196 (rct_a->ymin <= rct_b->ymin) && (rct_a->ymax >= rct_b->ymax));
197}
198bool BLI_rcti_inside_rcti(const rcti *rct_a, const rcti *rct_b)
199{
200 return ((rct_a->xmin <= rct_b->xmin) && (rct_a->xmax >= rct_b->xmax) &&
201 (rct_a->ymin <= rct_b->ymin) && (rct_a->ymax >= rct_b->ymax));
202}
203
204/* based closely on 'isect_seg_seg_v2_int',
205 * but in modified so corner cases are treated as intersections */
206static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], const int v4[2])
207{
208 const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) -
209 (v2[1] - v1[1]) * (v4[0] - v3[0]));
210 if (div == 0.0) {
211 return 1; /* co-linear */
212 }
213
214 const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
215 (v1[0] - v3[0]) * (v4[1] - v3[1])) /
216 div;
217 const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
218 (v1[0] - v3[0]) * (v2[1] - v1[1])) /
219 div;
220 return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
221}
222static int isect_segments_fl(const float v1[2],
223 const float v2[2],
224 const float v3[2],
225 const float v4[2])
226{
227 const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) -
228 (v2[1] - v1[1]) * (v4[0] - v3[0]));
229 if (div == 0.0) {
230 return 1; /* co-linear */
231 }
232
233 const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
234 (v1[0] - v3[0]) * (v4[1] - v3[1])) /
235 div;
236 const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
237 (v1[0] - v3[0]) * (v2[1] - v1[1])) /
238 div;
239 return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
240}
241
242bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
243{
244 /* first do outside-bounds check for both points of the segment */
245 if (s1[0] < rect->xmin && s2[0] < rect->xmin) {
246 return false;
247 }
248 if (s1[0] > rect->xmax && s2[0] > rect->xmax) {
249 return false;
250 }
251 if (s1[1] < rect->ymin && s2[1] < rect->ymin) {
252 return false;
253 }
254 if (s1[1] > rect->ymax && s2[1] > rect->ymax) {
255 return false;
256 }
257
258 /* if either points intersect then we definitely intersect */
259 if (BLI_rcti_isect_pt_v(rect, s1) || BLI_rcti_isect_pt_v(rect, s2)) {
260 return true;
261 }
262
263 /* both points are outside but may intersect the rect */
264 int tvec1[2];
265 int tvec2[2];
266 /* diagonal: [/] */
267 tvec1[0] = rect->xmin;
268 tvec1[1] = rect->ymin;
269 tvec2[0] = rect->xmax;
270 tvec2[1] = rect->ymax;
271 if (isect_segments_i(s1, s2, tvec1, tvec2)) {
272 return true;
273 }
274
275 /* diagonal: [\] */
276 tvec1[0] = rect->xmin;
277 tvec1[1] = rect->ymax;
278 tvec2[0] = rect->xmax;
279 tvec2[1] = rect->ymin;
280 if (isect_segments_i(s1, s2, tvec1, tvec2)) {
281 return true;
282 }
283
284 /* no intersection */
285 return false;
286}
287
288bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2])
289{
290 /* first do outside-bounds check for both points of the segment */
291 if (s1[0] < rect->xmin && s2[0] < rect->xmin) {
292 return false;
293 }
294 if (s1[0] > rect->xmax && s2[0] > rect->xmax) {
295 return false;
296 }
297 if (s1[1] < rect->ymin && s2[1] < rect->ymin) {
298 return false;
299 }
300 if (s1[1] > rect->ymax && s2[1] > rect->ymax) {
301 return false;
302 }
303
304 /* if either points intersect then we definitely intersect */
305 if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) {
306 return true;
307 }
308
309 /* both points are outside but may intersect the rect */
310 float tvec1[2];
311 float tvec2[2];
312 /* diagonal: [/] */
313 tvec1[0] = rect->xmin;
314 tvec1[1] = rect->ymin;
315 tvec2[0] = rect->xmax;
316 tvec2[1] = rect->ymax;
317 if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
318 return true;
319 }
320
321 /* diagonal: [\] */
322 tvec1[0] = rect->xmin;
323 tvec1[1] = rect->ymax;
324 tvec2[0] = rect->xmax;
325 tvec2[1] = rect->ymin;
326 if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
327 return true;
328 }
329
330 /* no intersection */
331 return false;
332}
333
334bool BLI_rcti_isect_circle(const rcti *rect, const float xy[2], const float radius)
335{
336 float dx, dy;
337
338 if (xy[0] >= rect->xmin && xy[0] <= rect->xmax) {
339 dx = 0;
340 }
341 else {
342 dx = (xy[0] < rect->xmin) ? (rect->xmin - xy[0]) : (xy[0] - rect->xmax);
343 }
344
345 if (xy[1] >= rect->ymin && xy[1] <= rect->ymax) {
346 dy = 0;
347 }
348 else {
349 dy = (xy[1] < rect->ymin) ? (rect->ymin - xy[1]) : (xy[1] - rect->ymax);
350 }
351
352 return dx * dx + dy * dy <= radius * radius;
353}
354
355bool BLI_rctf_isect_circle(const rctf *rect, const float xy[2], const float radius)
356{
357 float dx, dy;
358
359 if (xy[0] >= rect->xmin && xy[0] <= rect->xmax) {
360 dx = 0;
361 }
362 else {
363 dx = (xy[0] < rect->xmin) ? (rect->xmin - xy[0]) : (xy[0] - rect->xmax);
364 }
365
366 if (xy[1] >= rect->ymin && xy[1] <= rect->ymax) {
367 dy = 0;
368 }
369 else {
370 dy = (xy[1] < rect->ymin) ? (rect->ymin - xy[1]) : (xy[1] - rect->ymax);
371 }
372
373 return dx * dx + dy * dy <= radius * radius;
374}
375
376void BLI_rctf_union(rctf *rct_a, const rctf *rct_b)
377{
378 if (rct_a->xmin > rct_b->xmin) {
379 rct_a->xmin = rct_b->xmin;
380 }
381 if (rct_a->xmax < rct_b->xmax) {
382 rct_a->xmax = rct_b->xmax;
383 }
384 if (rct_a->ymin > rct_b->ymin) {
385 rct_a->ymin = rct_b->ymin;
386 }
387 if (rct_a->ymax < rct_b->ymax) {
388 rct_a->ymax = rct_b->ymax;
389 }
390}
391
392void BLI_rcti_union(rcti *rct_a, const rcti *rct_b)
393{
394 if (rct_a->xmin > rct_b->xmin) {
395 rct_a->xmin = rct_b->xmin;
396 }
397 if (rct_a->xmax < rct_b->xmax) {
398 rct_a->xmax = rct_b->xmax;
399 }
400 if (rct_a->ymin > rct_b->ymin) {
401 rct_a->ymin = rct_b->ymin;
402 }
403 if (rct_a->ymax < rct_b->ymax) {
404 rct_a->ymax = rct_b->ymax;
405 }
406}
407
408void BLI_rctf_init(rctf *rect, float xmin, float xmax, float ymin, float ymax)
409{
410 rect->xmin = xmin;
411 rect->xmax = xmax;
412 rect->ymin = ymin;
413 rect->ymax = ymax;
414
415 BLI_rctf_sanitize(rect);
416}
417
418void BLI_rcti_init(rcti *rect, int xmin, int xmax, int ymin, int ymax)
419{
420 rect->xmin = xmin;
421 rect->xmax = xmax;
422 rect->ymin = ymin;
423 rect->ymax = ymax;
424
425 BLI_rcti_sanitize(rect);
426}
427
428bool BLI_rctf_is_valid(const rctf *rect)
429{
430 return (rect->xmin <= rect->xmax) && (rect->ymin <= rect->ymax);
431}
432
433bool BLI_rcti_is_valid(const rcti *rect)
434{
435 return (rect->xmin <= rect->xmax) && (rect->ymin <= rect->ymax);
436}
437
439{
440 if (rect->xmin > rect->xmax) {
441 SWAP(float, rect->xmin, rect->xmax);
442 }
443 if (rect->ymin > rect->ymax) {
444 SWAP(float, rect->ymin, rect->ymax);
445 }
446
448}
449
451{
452 if (rect->xmin > rect->xmax) {
453 SWAP(int, rect->xmin, rect->xmax);
454 }
455 if (rect->ymin > rect->ymax) {
456 SWAP(int, rect->ymin, rect->ymax);
457 }
458
460}
461
462void BLI_rctf_init_pt_radius(rctf *rect, const float xy[2], float size)
463{
464 rect->xmin = xy[0] - size;
465 rect->xmax = xy[0] + size;
466 rect->ymin = xy[1] - size;
467 rect->ymax = xy[1] + size;
468}
469
470void BLI_rcti_init_pt_radius(rcti *rect, const int xy[2], int size)
471{
472 rect->xmin = xy[0] - size;
473 rect->xmax = xy[0] + size;
474 rect->ymin = xy[1] - size;
475 rect->ymax = xy[1] + size;
476}
477
479{
480 rect->xmin = rect->ymin = INT_MAX;
481 rect->xmax = rect->ymax = INT_MIN;
482}
483
485{
486 rect->xmin = rect->ymin = FLT_MAX;
487 rect->xmax = rect->ymax = -FLT_MAX;
488}
489
490void BLI_rcti_do_minmax_v(rcti *rect, const int xy[2])
491{
492 if (xy[0] < rect->xmin) {
493 rect->xmin = xy[0];
494 }
495 if (xy[0] > rect->xmax) {
496 rect->xmax = xy[0];
497 }
498 if (xy[1] < rect->ymin) {
499 rect->ymin = xy[1];
500 }
501 if (xy[1] > rect->ymax) {
502 rect->ymax = xy[1];
503 }
504}
505
506void BLI_rcti_do_minmax_rcti(rcti *rect, const rcti *other)
507{
508 rect->xmin = min_ii(rect->xmin, other->xmin);
509 rect->xmax = max_ii(rect->xmax, other->xmax);
510 rect->ymin = min_ii(rect->ymin, other->ymin);
511 rect->ymax = max_ii(rect->ymax, other->ymax);
512}
513
514void BLI_rctf_do_minmax_v(rctf *rect, const float xy[2])
515{
516 if (xy[0] < rect->xmin) {
517 rect->xmin = xy[0];
518 }
519 if (xy[0] > rect->xmax) {
520 rect->xmax = xy[0];
521 }
522 if (xy[1] < rect->ymin) {
523 rect->ymin = xy[1];
524 }
525 if (xy[1] > rect->ymax) {
526 rect->ymax = xy[1];
527 }
528}
529
531 const rctf *src,
532 float xy_dst[2],
533 const float xy_src[2])
534{
535 xy_dst[0] = ((xy_src[0] - src->xmin) / (src->xmax - src->xmin));
536 xy_dst[0] = dst->xmin + ((dst->xmax - dst->xmin) * xy_dst[0]);
537
538 xy_dst[1] = ((xy_src[1] - src->ymin) / (src->ymax - src->ymin));
539 xy_dst[1] = dst->ymin + ((dst->ymax - dst->ymin) * xy_dst[1]);
540}
541
543 const rctf *dst, const rctf *src, float matrix[4][4], uint x, uint y)
544{
545 BLI_assert(x < 3 && y < 3);
546
547 unit_m4(matrix);
548
549 matrix[x][x] = BLI_rctf_size_x(src) / BLI_rctf_size_x(dst);
550 matrix[y][y] = BLI_rctf_size_y(src) / BLI_rctf_size_y(dst);
551 matrix[3][x] = (src->xmin - dst->xmin) * matrix[x][x];
552 matrix[3][y] = (src->ymin - dst->ymin) * matrix[y][y];
553}
554
555void BLI_rctf_transform_calc_m4_pivot_min(const rctf *dst, const rctf *src, float matrix[4][4])
556{
557 BLI_rctf_transform_calc_m4_pivot_min_ex(dst, src, matrix, 0, 1);
558}
559
560void BLI_rcti_translate(rcti *rect, int x, int y)
561{
562 rect->xmin += x;
563 rect->ymin += y;
564 rect->xmax += x;
565 rect->ymax += y;
566}
567void BLI_rctf_translate(rctf *rect, float x, float y)
568{
569 rect->xmin += x;
570 rect->ymin += y;
571 rect->xmax += x;
572 rect->ymax += y;
573}
574
575void BLI_rcti_mul(rcti *rect, const int factor)
576{
577 rect->xmin *= factor;
578 rect->ymin *= factor;
579 rect->xmax *= factor;
580 rect->ymax *= factor;
581}
582void BLI_rctf_mul(rctf *rect, const float factor)
583{
584 rect->xmin *= factor;
585 rect->ymin *= factor;
586 rect->xmax *= factor;
587 rect->ymax *= factor;
588}
589
590void BLI_rcti_recenter(rcti *rect, int x, int y)
591{
592 const int dx = x - BLI_rcti_cent_x(rect);
593 const int dy = y - BLI_rcti_cent_y(rect);
594 BLI_rcti_translate(rect, dx, dy);
595}
596void BLI_rctf_recenter(rctf *rect, float x, float y)
597{
598 const float dx = x - BLI_rctf_cent_x(rect);
599 const float dy = y - BLI_rctf_cent_y(rect);
600 BLI_rctf_translate(rect, dx, dy);
601}
602
603void BLI_rcti_resize_x(rcti *rect, int x)
604{
605 rect->xmin = BLI_rcti_cent_x(rect) - (x / 2);
606 rect->xmax = rect->xmin + x;
607}
608
609void BLI_rcti_resize_y(rcti *rect, int y)
610{
611 rect->ymin = BLI_rcti_cent_y(rect) - (y / 2);
612 rect->ymax = rect->ymin + y;
613}
614
615void BLI_rcti_resize(rcti *rect, int x, int y)
616{
617 rect->xmin = BLI_rcti_cent_x(rect) - (x / 2);
618 rect->ymin = BLI_rcti_cent_y(rect) - (y / 2);
619 rect->xmax = rect->xmin + x;
620 rect->ymax = rect->ymin + y;
621}
622
623void BLI_rcti_pad(rcti *rect, int pad_x, int pad_y)
624{
625 rect->xmin -= pad_x;
626 rect->ymin -= pad_y;
627 rect->xmax += pad_x;
628 rect->ymax += pad_y;
629}
630
631void BLI_rctf_pad(rctf *rect, float pad_x, float pad_y)
632{
633 rect->xmin -= pad_x;
634 rect->ymin -= pad_y;
635 rect->xmax += pad_x;
636 rect->ymax += pad_y;
637}
638
639void BLI_rctf_resize_x(rctf *rect, float x)
640{
641 rect->xmin = BLI_rctf_cent_x(rect) - (x * 0.5f);
642 rect->xmax = rect->xmin + x;
643}
644
645void BLI_rctf_resize_y(rctf *rect, float y)
646{
647 rect->ymin = BLI_rctf_cent_y(rect) - (y * 0.5f);
648 rect->ymax = rect->ymin + y;
649}
650
651void BLI_rctf_resize(rctf *rect, float x, float y)
652{
653 rect->xmin = BLI_rctf_cent_x(rect) - (x * 0.5f);
654 rect->ymin = BLI_rctf_cent_y(rect) - (y * 0.5f);
655 rect->xmax = rect->xmin + x;
656 rect->ymax = rect->ymin + y;
657}
658
659void BLI_rcti_scale(rcti *rect, const float scale)
660{
661 const int cent_x = BLI_rcti_cent_x(rect);
662 const int cent_y = BLI_rcti_cent_y(rect);
663 const int size_x_half = BLI_rcti_size_x(rect) * (scale * 0.5f);
664 const int size_y_half = BLI_rcti_size_y(rect) * (scale * 0.5f);
665 rect->xmin = cent_x - size_x_half;
666 rect->ymin = cent_y - size_y_half;
667 rect->xmax = cent_x + size_x_half;
668 rect->ymax = cent_y + size_y_half;
669}
670
671void BLI_rctf_scale(rctf *rect, const float scale)
672{
673 const float cent_x = BLI_rctf_cent_x(rect);
674 const float cent_y = BLI_rctf_cent_y(rect);
675 const float size_x_half = BLI_rctf_size_x(rect) * (scale * 0.5f);
676 const float size_y_half = BLI_rctf_size_y(rect) * (scale * 0.5f);
677 rect->xmin = cent_x - size_x_half;
678 rect->ymin = cent_y - size_y_half;
679 rect->xmax = cent_x + size_x_half;
680 rect->ymax = cent_y + size_y_half;
681}
682
684 const float boundary_size,
685 const float pad_min,
686 const float pad_max)
687{
688 BLI_assert(pad_max >= 0.0f);
689 BLI_assert(pad_min >= 0.0f);
690 BLI_assert(boundary_size > 0.0f);
691
692 float total_pad = pad_max + pad_min;
693 if (total_pad == 0.0f) {
694 return;
695 }
696
697 /* To get the padding to work as intended, we have to calculate the
698 * new 'rect' y size that has the same ratio between its padding and size
699 * as our screen space ratio (total_pad / boundary_size).
700 *
701 * Here is how the equation was derived:
702 *
703 * ratio = local_pad / new_local_view_size = total_pad / boundary_size
704 * Where, new_local_view_size = local_view_size + local_pad
705 *
706 * ratio = local_pad / (local_view_size + local_pad) ->
707 * ratio * local_view_size + ratio * local_pad = local_pad ->
708 * ratio * local_view_size = local_pad * (1 - ratio) ->
709 * ratio * local_view_size / (1 - ratio) = local_pad ->
710 * total_pad * local_view_size / (boundary_size - total_pad) = local_pad
711 *
712 * We can then remove the first "total_pad" in the equation as we need to
713 * divide pad_(max/min) by "total_pad" when we are calculating the final ymax/ymin.
714 */
715
716 float local_view_size = BLI_rctf_size_y(rect);
717 float local_pad = local_view_size / (boundary_size - total_pad);
718
719 rect->ymax += local_pad * pad_max;
720 rect->ymin -= local_pad * pad_min;
721}
722
723void BLI_rctf_interp(rctf *rect, const rctf *rect_a, const rctf *rect_b, const float fac)
724{
725 const float ifac = 1.0f - fac;
726 rect->xmin = (rect_a->xmin * ifac) + (rect_b->xmin * fac);
727 rect->xmax = (rect_a->xmax * ifac) + (rect_b->xmax * fac);
728 rect->ymin = (rect_a->ymin * ifac) + (rect_b->ymin * fac);
729 rect->ymax = (rect_a->ymax * ifac) + (rect_b->ymax * fac);
730}
731
732/* BLI_rcti_interp() not needed yet */
733
734bool BLI_rctf_clamp_pt_v(const rctf *rect, float xy[2])
735{
736 bool changed = false;
737 if (xy[0] < rect->xmin) {
738 xy[0] = rect->xmin;
739 changed = true;
740 }
741 if (xy[0] > rect->xmax) {
742 xy[0] = rect->xmax;
743 changed = true;
744 }
745 if (xy[1] < rect->ymin) {
746 xy[1] = rect->ymin;
747 changed = true;
748 }
749 if (xy[1] > rect->ymax) {
750 xy[1] = rect->ymax;
751 changed = true;
752 }
753 return changed;
754}
755
756bool BLI_rcti_clamp_pt_v(const rcti *rect, int xy[2])
757{
758 bool changed = false;
759 if (xy[0] < rect->xmin) {
760 xy[0] = rect->xmin;
761 changed = true;
762 }
763 if (xy[0] > rect->xmax) {
764 xy[0] = rect->xmax;
765 changed = true;
766 }
767 if (xy[1] < rect->ymin) {
768 xy[1] = rect->ymin;
769 changed = true;
770 }
771 if (xy[1] > rect->ymax) {
772 xy[1] = rect->ymax;
773 changed = true;
774 }
775 return changed;
776}
777
778bool BLI_rctf_clamp(rctf *rect, const rctf *rect_bounds, float r_xy[2])
779{
780 bool changed = false;
781
782 r_xy[0] = 0.0f;
783 r_xy[1] = 0.0f;
784
785 if (rect->xmax > rect_bounds->xmax) {
786 float ofs = rect_bounds->xmax - rect->xmax;
787 rect->xmin += ofs;
788 rect->xmax += ofs;
789 r_xy[0] += ofs;
790 changed = true;
791 }
792
793 if (rect->xmin < rect_bounds->xmin) {
794 float ofs = rect_bounds->xmin - rect->xmin;
795 rect->xmin += ofs;
796 rect->xmax += ofs;
797 r_xy[0] += ofs;
798 changed = true;
799 }
800
801 if (rect->ymin < rect_bounds->ymin) {
802 float ofs = rect_bounds->ymin - rect->ymin;
803 rect->ymin += ofs;
804 rect->ymax += ofs;
805 r_xy[1] += ofs;
806 changed = true;
807 }
808
809 if (rect->ymax > rect_bounds->ymax) {
810 float ofs = rect_bounds->ymax - rect->ymax;
811 rect->ymin += ofs;
812 rect->ymax += ofs;
813 r_xy[1] += ofs;
814 changed = true;
815 }
816
817 return changed;
818}
819
820bool BLI_rcti_clamp(rcti *rect, const rcti *rect_bounds, int r_xy[2])
821{
822 bool changed = false;
823
824 r_xy[0] = 0;
825 r_xy[1] = 0;
826
827 if (rect->xmax > rect_bounds->xmax) {
828 int ofs = rect_bounds->xmax - rect->xmax;
829 rect->xmin += ofs;
830 rect->xmax += ofs;
831 r_xy[0] += ofs;
832 changed = true;
833 }
834
835 if (rect->xmin < rect_bounds->xmin) {
836 int ofs = rect_bounds->xmin - rect->xmin;
837 rect->xmin += ofs;
838 rect->xmax += ofs;
839 r_xy[0] += ofs;
840 changed = true;
841 }
842
843 if (rect->ymin < rect_bounds->ymin) {
844 int ofs = rect_bounds->ymin - rect->ymin;
845 rect->ymin += ofs;
846 rect->ymax += ofs;
847 r_xy[1] += ofs;
848 changed = true;
849 }
850
851 if (rect->ymax > rect_bounds->ymax) {
852 int ofs = rect_bounds->ymax - rect->ymax;
853 rect->ymin += ofs;
854 rect->ymax += ofs;
855 r_xy[1] += ofs;
856 changed = true;
857 }
858
859 return changed;
860}
861
862bool BLI_rctf_compare(const rctf *rect_a, const rctf *rect_b, const float limit)
863{
864 if (fabsf(rect_a->xmin - rect_b->xmin) <= limit) {
865 if (fabsf(rect_a->xmax - rect_b->xmax) <= limit) {
866 if (fabsf(rect_a->ymin - rect_b->ymin) <= limit) {
867 if (fabsf(rect_a->ymax - rect_b->ymax) <= limit) {
868 return true;
869 }
870 }
871 }
872 }
873
874 return false;
875}
876
877bool BLI_rcti_compare(const rcti *rect_a, const rcti *rect_b)
878{
879 if (rect_a->xmin == rect_b->xmin) {
880 if (rect_a->xmax == rect_b->xmax) {
881 if (rect_a->ymin == rect_b->ymin) {
882 if (rect_a->ymax == rect_b->ymax) {
883 return true;
884 }
885 }
886 }
887 }
888
889 return false;
890}
891
892bool BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
893{
894 float xmin, xmax;
895 float ymin, ymax;
896
897 xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin);
898 xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax);
899 ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin);
900 ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax);
901
902 if (xmax >= xmin && ymax >= ymin) {
903 if (dest) {
904 dest->xmin = xmin;
905 dest->xmax = xmax;
906 dest->ymin = ymin;
907 dest->ymax = ymax;
908 }
909 return true;
910 }
911
912 if (dest) {
913 dest->xmin = 0;
914 dest->xmax = 0;
915 dest->ymin = 0;
916 dest->ymax = 0;
917 }
918 return false;
919}
920
921bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
922{
923 int xmin, xmax;
924 int ymin, ymax;
925
926 xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin);
927 xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax);
928 ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin);
929 ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax);
930
931 if (xmax >= xmin && ymax >= ymin) {
932 if (dest) {
933 dest->xmin = xmin;
934 dest->xmax = xmax;
935 dest->ymin = ymin;
936 dest->ymax = ymax;
937 }
938 return true;
939 }
940
941 if (dest) {
942 dest->xmin = 0;
943 dest->xmax = 0;
944 dest->ymin = 0;
945 dest->ymax = 0;
946 }
947 return false;
948}
949
950bool BLI_rctf_isect_rect_x(const rctf *src1, const rctf *src2, float range_x[2])
951{
952 const float xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin);
953 const float xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax);
954
955 if (xmax >= xmin) {
956 if (range_x) {
957 range_x[0] = xmin;
958 range_x[1] = xmax;
959 }
960 return true;
961 }
962
963 if (range_x) {
964 range_x[0] = 0;
965 range_x[1] = 0;
966 }
967 return false;
968}
969
970bool BLI_rctf_isect_rect_y(const rctf *src1, const rctf *src2, float range_y[2])
971{
972 const float ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin);
973 const float ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax);
974
975 if (ymax >= ymin) {
976 if (range_y) {
977 range_y[0] = ymin;
978 range_y[1] = ymax;
979 }
980 return true;
981 }
982
983 if (range_y) {
984 range_y[0] = 0;
985 range_y[1] = 0;
986 }
987 return false;
988}
989
990bool BLI_rcti_isect_rect_x(const rcti *src1, const rcti *src2, int range_x[2])
991{
992 const int xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin);
993 const int xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax);
994
995 if (xmax >= xmin) {
996 if (range_x) {
997 range_x[0] = xmin;
998 range_x[1] = xmax;
999 }
1000 return true;
1001 }
1002
1003 if (range_x) {
1004 range_x[0] = 0;
1005 range_x[1] = 0;
1006 }
1007 return false;
1008}
1009
1010bool BLI_rcti_isect_rect_y(const rcti *src1, const rcti *src2, int range_y[2])
1011{
1012 const int ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin);
1013 const int ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax);
1014
1015 if (ymax >= ymin) {
1016 if (range_y) {
1017 range_y[0] = ymin;
1018 range_y[1] = ymax;
1019 }
1020 return true;
1021 }
1022
1023 if (range_y) {
1024 range_y[0] = 0;
1025 range_y[1] = 0;
1026 }
1027 return false;
1028}
1029
1030void BLI_rcti_rctf_copy(rcti *dst, const rctf *src)
1031{
1032 dst->xmin = floorf(src->xmin + 0.5f);
1033 dst->xmax = dst->xmin + floorf(BLI_rctf_size_x(src) + 0.5f);
1034 dst->ymin = floorf(src->ymin + 0.5f);
1035 dst->ymax = dst->ymin + floorf(BLI_rctf_size_y(src) + 0.5f);
1036}
1037
1038void BLI_rcti_rctf_copy_floor(rcti *dst, const rctf *src)
1039{
1040 dst->xmin = floorf(src->xmin);
1041 dst->xmax = floorf(src->xmax);
1042 dst->ymin = floorf(src->ymin);
1043 dst->ymax = floorf(src->ymax);
1044}
1045
1046void BLI_rcti_rctf_copy_round(rcti *dst, const rctf *src)
1047{
1048 dst->xmin = floorf(src->xmin + 0.5f);
1049 dst->xmax = floorf(src->xmax + 0.5f);
1050 dst->ymin = floorf(src->ymin + 0.5f);
1051 dst->ymax = floorf(src->ymax + 0.5f);
1052}
1053
1054void BLI_rctf_rcti_copy(rctf *dst, const rcti *src)
1055{
1056 dst->xmin = src->xmin;
1057 dst->xmax = src->xmax;
1058 dst->ymin = src->ymin;
1059 dst->ymax = src->ymax;
1060}
1061
1062void print_rctf(const char *str, const rctf *rect)
1063{
1064 printf("%s: xmin %.8f, xmax %.8f, ymin %.8f, ymax %.8f (%.12fx%.12f)\n",
1065 str,
1066 rect->xmin,
1067 rect->xmax,
1068 rect->ymin,
1069 rect->ymax,
1070 BLI_rctf_size_x(rect),
1071 BLI_rctf_size_y(rect));
1072}
1073
1074void print_rcti(const char *str, const rcti *rect)
1075{
1076 printf("%s: xmin %d, xmax %d, ymin %d, ymax %d (%dx%d)\n",
1077 str,
1078 rect->xmin,
1079 rect->xmax,
1080 rect->ymin,
1081 rect->ymax,
1082 BLI_rcti_size_x(rect),
1083 BLI_rcti_size_y(rect));
1084}
1085
1086/* Comprehensive math (float only) */
1087
1088/* -------------------------------------------------------------------- */
1092#define ROTATE_SINCOS(r_vec, mat2, vec) \
1093 { \
1094 (r_vec)[0] = (mat2)[1] * (vec)[0] + (+(mat2)[0]) * (vec)[1]; \
1095 (r_vec)[1] = (mat2)[0] * (vec)[0] + (-(mat2)[1]) * (vec)[1]; \
1096 } \
1097 ((void)0)
1098
1099void BLI_rctf_rotate_expand(rctf *dst, const rctf *src, const float angle)
1100{
1101 const float mat2[2] = {sinf(angle), cosf(angle)};
1102 const float cent[2] = {BLI_rctf_cent_x(src), BLI_rctf_cent_y(src)};
1103 float corner[2], corner_rot[2], corder_max[2];
1104
1105 /* x is same for both corners */
1106 corner[0] = src->xmax - cent[0];
1107 corner[1] = src->ymax - cent[1];
1108 ROTATE_SINCOS(corner_rot, mat2, corner);
1109 corder_max[0] = fabsf(corner_rot[0]);
1110 corder_max[1] = fabsf(corner_rot[1]);
1111
1112 corner[1] *= -1;
1113 ROTATE_SINCOS(corner_rot, mat2, corner);
1114 corder_max[0] = MAX2(corder_max[0], fabsf(corner_rot[0]));
1115 corder_max[1] = MAX2(corder_max[1], fabsf(corner_rot[1]));
1116
1117 dst->xmin = cent[0] - corder_max[0];
1118 dst->xmax = cent[0] + corder_max[0];
1119 dst->ymin = cent[1] - corder_max[1];
1120 dst->ymax = cent[1] + corder_max[1];
1121}
1122
1123#undef ROTATE_SINCOS
1124
1127static void unit_m4(float m[4][4])
1128{
1129 m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
1130 m[0][1] = m[0][2] = m[0][3] = 0.0f;
1131 m[1][0] = m[1][2] = m[1][3] = 0.0f;
1132 m[2][0] = m[2][1] = m[2][3] = 0.0f;
1133 m[3][0] = m[3][1] = m[3][2] = 0.0f;
1134}
#define BLI_assert(a)
Definition BLI_assert.h:50
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:193
BLI_INLINE float BLI_rctf_cent_y(const struct rctf *rct)
Definition BLI_rect.h:184
BLI_INLINE float BLI_rctf_cent_x(const struct rctf *rct)
Definition BLI_rect.h:180
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
BLI_INLINE int BLI_rcti_cent_y(const struct rcti *rct)
Definition BLI_rect.h:176
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition BLI_rect.h:197
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition BLI_rect.h:201
BLI_INLINE int BLI_rcti_cent_x(const struct rcti *rct)
Definition BLI_rect.h:172
unsigned int uint
#define SWAP(type, a, b)
#define MAX2(a, b)
typedef double(DMatrix)[4][4]
ATTR_WARN_UNUSED_RESULT const BMVert * v2
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
#define printf
#define sinf(x)
#define cosf(x)
#define floorf(x)
#define fabsf(x)
#define str(s)
#define ROTATE_SINCOS(r_vec, mat2, vec)
Definition rct.c:1092
bool BLI_rcti_compare(const rcti *rect_a, const rcti *rect_b)
Definition rct.c:877
void BLI_rctf_init(rctf *rect, float xmin, float xmax, float ymin, float ymax)
Definition rct.c:408
bool BLI_rcti_isect_circle(const rcti *rect, const float xy[2], const float radius)
Definition rct.c:334
void BLI_rctf_rcti_copy(rctf *dst, const rcti *src)
Definition rct.c:1054
void BLI_rcti_init(rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition rct.c:418
void BLI_rctf_init_pt_radius(rctf *rect, const float xy[2], float size)
Definition rct.c:462
void BLI_rcti_rctf_copy(rcti *dst, const rctf *src)
Definition rct.c:1030
bool BLI_rctf_isect_x(const rctf *rect, const float x)
Definition rct.c:93
bool BLI_rcti_isect_y(const rcti *rect, const int y)
Definition rct.c:48
bool BLI_rctf_isect_y(const rctf *rect, const float y)
Definition rct.c:104
bool BLI_rcti_is_empty(const rcti *rect)
Definition rct.c:27
bool BLI_rctf_is_valid(const rctf *rect)
Definition rct.c:428
bool BLI_rcti_is_valid(const rcti *rect)
Definition rct.c:433
void BLI_rctf_resize(rctf *rect, float x, float y)
Definition rct.c:651
void BLI_rcti_do_minmax_v(rcti *rect, const int xy[2])
Definition rct.c:490
bool BLI_rcti_isect_rect_y(const rcti *src1, const rcti *src2, int range_y[2])
Definition rct.c:1010
void BLI_rctf_mul(rctf *rect, const float factor)
Definition rct.c:582
bool BLI_rctf_is_empty(const rctf *rect)
Definition rct.c:32
void print_rctf(const char *str, const rctf *rect)
Definition rct.c:1062
void BLI_rctf_interp(rctf *rect, const rctf *rect_a, const rctf *rect_b, const float fac)
Definition rct.c:723
void BLI_rctf_transform_pt_v(const rctf *dst, const rctf *src, float xy_dst[2], const float xy_src[2])
Definition rct.c:530
void BLI_rcti_recenter(rcti *rect, int x, int y)
Definition rct.c:590
float BLI_rctf_length_y(const rctf *rect, const float y)
Definition rct.c:182
void BLI_rcti_init_minmax(rcti *rect)
Definition rct.c:478
void BLI_rcti_init_pt_radius(rcti *rect, const int xy[2], int size)
Definition rct.c:470
void BLI_rcti_do_minmax_rcti(rcti *rect, const rcti *other)
Definition rct.c:506
bool BLI_rctf_compare(const rctf *rect_a, const rctf *rect_b, const float limit)
Definition rct.c:862
void BLI_rcti_mul(rcti *rect, const int factor)
Definition rct.c:575
void BLI_rctf_rotate_expand(rctf *dst, const rctf *src, const float angle)
Definition rct.c:1099
bool BLI_rctf_clamp_pt_v(const rctf *rect, float xy[2])
Definition rct.c:734
bool BLI_rctf_isect_rect_x(const rctf *src1, const rctf *src2, float range_x[2])
Definition rct.c:950
bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
Definition rct.c:921
static void unit_m4(float m[4][4])
Definition rct.c:1127
void BLI_rcti_rctf_copy_floor(rcti *dst, const rctf *src)
Definition rct.c:1038
int BLI_rcti_length_x(const rcti *rect, const int x)
Definition rct.c:149
bool BLI_rctf_isect_rect_y(const rctf *src1, const rctf *src2, float range_y[2])
Definition rct.c:970
void BLI_rcti_union(rcti *rct_a, const rcti *rct_b)
Definition rct.c:392
bool BLI_rcti_clamp(rcti *rect, const rcti *rect_bounds, int r_xy[2])
Definition rct.c:820
void BLI_rcti_resize_x(rcti *rect, int x)
Definition rct.c:603
void BLI_rctf_transform_calc_m4_pivot_min(const rctf *dst, const rctf *src, float matrix[4][4])
Definition rct.c:555
void BLI_rctf_init_minmax(rctf *rect)
Definition rct.c:484
int BLI_rcti_length_y(const rcti *rect, const int y)
Definition rct.c:160
bool BLI_rcti_isect_x(const rcti *rect, const int x)
Definition rct.c:37
void BLI_rctf_transform_calc_m4_pivot_min_ex(const rctf *dst, const rctf *src, float matrix[4][4], uint x, uint y)
Definition rct.c:542
void BLI_rctf_union(rctf *rct_a, const rctf *rct_b)
Definition rct.c:376
void BLI_rcti_scale(rcti *rect, const float scale)
Definition rct.c:659
static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], const int v4[2])
Definition rct.c:206
void BLI_rctf_pad(rctf *rect, float pad_x, float pad_y)
Definition rct.c:631
void BLI_rctf_do_minmax_v(rctf *rect, const float xy[2])
Definition rct.c:514
bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2])
Definition rct.c:288
bool BLI_rcti_isect_rect_x(const rcti *src1, const rcti *src2, int range_x[2])
Definition rct.c:990
void BLI_rctf_pad_y(rctf *rect, const float boundary_size, const float pad_min, const float pad_max)
Definition rct.c:683
void BLI_rctf_recenter(rctf *rect, float x, float y)
Definition rct.c:596
void BLI_rcti_resize_y(rcti *rect, int y)
Definition rct.c:609
void BLI_rctf_translate(rctf *rect, float x, float y)
Definition rct.c:567
float BLI_rctf_length_x(const rctf *rect, const float x)
Definition rct.c:171
bool BLI_rcti_clamp_pt_v(const rcti *rect, int xy[2])
Definition rct.c:756
void BLI_rctf_resize_x(rctf *rect, float x)
Definition rct.c:639
bool BLI_rctf_clamp(rctf *rect, const rctf *rect_bounds, float r_xy[2])
Definition rct.c:778
bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
Definition rct.c:242
void BLI_rctf_scale(rctf *rect, const float scale)
Definition rct.c:671
void BLI_rctf_sanitize(rctf *rect)
Definition rct.c:438
bool BLI_rcti_isect_pt_v(const rcti *rect, const int xy[2])
Definition rct.c:76
void BLI_rcti_pad(rcti *rect, int pad_x, int pad_y)
Definition rct.c:623
void BLI_rcti_rctf_copy_round(rcti *dst, const rctf *src)
Definition rct.c:1046
bool BLI_rcti_isect_pt(const rcti *rect, const int x, const int y)
Definition rct.c:59
bool BLI_rctf_inside_rctf(const rctf *rct_a, const rctf *rct_b)
Definition rct.c:193
void print_rcti(const char *str, const rcti *rect)
Definition rct.c:1074
void BLI_rctf_resize_y(rctf *rect, float y)
Definition rct.c:645
static int isect_segments_fl(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
Definition rct.c:222
bool BLI_rcti_inside_rcti(const rcti *rct_a, const rcti *rct_b)
Definition rct.c:198
bool BLI_rctf_isect_circle(const rctf *rect, const float xy[2], const float radius)
Definition rct.c:355
void BLI_rcti_resize(rcti *rect, int x, int y)
Definition rct.c:615
bool BLI_rctf_isect_pt(const rctf *rect, const float x, const float y)
Definition rct.c:115
void BLI_rcti_translate(rcti *rect, int x, int y)
Definition rct.c:560
bool BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2])
Definition rct.c:132
bool BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
Definition rct.c:892
void BLI_rcti_sanitize(rcti *rect)
Definition rct.c:450
#define FLT_MAX
Definition stdcycles.h:14
float xmax
float xmin
float ymax
float ymin
int ymin
int ymax
int xmin
int xmax
int xy[2]
Definition wm_draw.cc:170