mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
Kandinsky: KDRectUnion
Change-Id: Ib328275ab3a6fc6da9bc472dffe37c9948c727d5
This commit is contained in:
@@ -27,6 +27,9 @@ extern KDRect KDRectZero;
|
||||
bool KDRectIntersect(KDRect r1, KDRect r2);
|
||||
KDRect KDRectIntersection(KDRect r1, KDRect r2);
|
||||
|
||||
// Returns the smallest rectangle containing r1 and r2
|
||||
KDRect KDRectUnion(KDRect r1, KDRect r2);
|
||||
|
||||
bool KDRectContains(KDRect r, KDPoint p);
|
||||
KDRect KDRectTranslate(KDRect r, KDPoint p);
|
||||
|
||||
|
||||
@@ -42,6 +42,54 @@ KDRect KDRectIntersection(KDRect r1, KDRect r2) {
|
||||
return intersection;
|
||||
}
|
||||
|
||||
static void KDRectComputeUnionBound(KDCoordinate size1, KDCoordinate size2,
|
||||
KDCoordinate * outputMin, KDCoordinate * outputMax,
|
||||
KDCoordinate min1, KDCoordinate min2,
|
||||
KDCoordinate max1, KDCoordinate max2)
|
||||
{
|
||||
if (size1 != 0) {
|
||||
if (size2 != 0) {
|
||||
*outputMin = min(min1, min2);
|
||||
*outputMax = max(max1, max2);
|
||||
} else {
|
||||
*outputMin = min1;
|
||||
*outputMax = max1;
|
||||
}
|
||||
} else {
|
||||
if (size2 != 0) {
|
||||
*outputMin = min2;
|
||||
*outputMax = max2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KDRect KDRectUnion(KDRect r1, KDRect r2) {
|
||||
/* We should ignore coordinate whose size is zero
|
||||
* For example, if r1.height is zero, just ignore r1.y and r1.height. */
|
||||
|
||||
KDCoordinate resultLeft = 0;
|
||||
KDCoordinate resultTop = 0;
|
||||
KDCoordinate resultRight = 0;
|
||||
KDCoordinate resultBottom = 0;
|
||||
|
||||
KDRectComputeUnionBound(r1.width, r2.width,
|
||||
&resultLeft, &resultRight,
|
||||
left(r1), left(r2),
|
||||
right(r1), right(r2));
|
||||
|
||||
KDRectComputeUnionBound(r1.height, r2.height,
|
||||
&resultTop, &resultBottom,
|
||||
top(r1), top(r2),
|
||||
bottom(r1), bottom(r2));
|
||||
|
||||
return (KDRect){
|
||||
.x = resultLeft,
|
||||
.y = resultTop,
|
||||
.width = resultRight-resultLeft,
|
||||
.height = resultBottom-resultTop
|
||||
};
|
||||
}
|
||||
|
||||
bool KDRectContains(KDRect r, KDPoint p) {
|
||||
return (p.x >= r.x && p.x < (r.x+r.width) && p.y >= r.y && p.y < (r.y+r.height));
|
||||
}
|
||||
|
||||
@@ -24,3 +24,59 @@ QUIZ_CASE(kandinsky_rect_intersect) {
|
||||
assert(c.width == 5);
|
||||
assert(c.height == 5);
|
||||
}
|
||||
|
||||
QUIZ_CASE(kandinsky_rect_union) {
|
||||
KDRect a = {
|
||||
.x = -5, .y = -5,
|
||||
.width = 10, .height = 10
|
||||
};
|
||||
KDRect b = {
|
||||
.x = 0, .y = 0,
|
||||
.width = 10, .height = 10
|
||||
};
|
||||
|
||||
KDRect c = KDRectUnion(a,b);
|
||||
assert(c.x == -5);
|
||||
assert(c.y == -5);
|
||||
assert(c.width == 15);
|
||||
assert(c.height == 15);
|
||||
|
||||
c = KDRectUnion(a,b);
|
||||
assert(c.x == -5);
|
||||
assert(c.y == -5);
|
||||
assert(c.width == 15);
|
||||
assert(c.height == 15);
|
||||
}
|
||||
|
||||
QUIZ_CASE(kandinsky_rect_empty_union) {
|
||||
KDRect a = {
|
||||
.x = 1, .y = 2,
|
||||
.width = 3, .height = 4
|
||||
};
|
||||
KDRect b = {
|
||||
.x = 5, .y = 6,
|
||||
.width = 0, .height = 0
|
||||
};
|
||||
KDRect c = {
|
||||
.x = -2, .y = -1,
|
||||
.width = 0, .height = 1
|
||||
};
|
||||
|
||||
KDRect t = KDRectUnion(a,b);
|
||||
assert(t.x == a.x);
|
||||
assert(t.y == a.y);
|
||||
assert(t.width == a.width);
|
||||
assert(t.height == a.height);
|
||||
|
||||
t = KDRectUnion(b,a);
|
||||
assert(t.x == a.x);
|
||||
assert(t.y == a.y);
|
||||
assert(t.width == a.width);
|
||||
assert(t.height == a.height);
|
||||
|
||||
t = KDRectUnion(a,c);
|
||||
assert(t.x == a.x);
|
||||
assert(t.y == c.y);
|
||||
assert(t.width == a.width);
|
||||
assert(t.height == 7);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user