Use 128-bit arithmetic to avoid overflow

This commit is contained in:
Erica Fischer
2024-03-18 11:37:47 -07:00
parent cc6135dd02
commit 3b948e0f20
4 changed files with 24 additions and 36 deletions
+5 -7
View File
@@ -177,28 +177,26 @@ int clip(long long *x0, long long *y0, long long *x1, long long *y1, long long x
} else {
// failed both tests, so calculate the line segment to clip
// from an outside point to an intersection with clip edge
long long x = *x0, y = *y0;
__int128 x = *x0, y = *y0;
// At least one endpoint is outside the clip rectangle; pick it.
int outcodeOut = outcode0 ? outcode0 : outcode1;
// XXX truncating division
long long shift = 1LL << (GLOBAL_DETAIL - 32);
// Now find the intersection point;
// use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
if (outcodeOut & TOP) { // point is above the clip rectangle
x = *x0 + ((*x1 - *x0) / shift) * ((ymax - *y0) / shift) / (*y1 - *y0) * shift * shift;
x = *x0 + ((__int128) (*x1 - *x0)) * ((ymax - *y0)) / (*y1 - *y0);
y = ymax;
} else if (outcodeOut & BOTTOM) { // point is below the clip rectangle
x = *x0 + ((*x1 - *x0) / shift) * ((ymin - *y0) / shift) / (*y1 - *y0) * shift * shift;
x = *x0 + ((__int128) (*x1 - *x0)) * ((ymin - *y0)) / (*y1 - *y0);
y = ymin;
} else if (outcodeOut & RIGHT) { // point is to the right of clip rectangle
y = *y0 + ((*y1 - *y0) / shift) * ((xmax - *x0) / shift) / (*x1 - *x0) * shift * shift;
y = *y0 + ((__int128) (*y1 - *y0)) * ((xmax - *x0)) / (*x1 - *x0);
x = xmax;
} else if (outcodeOut & LEFT) { // point is to the left of clip rectangle
y = *y0 + ((*y1 - *y0) / shift) * ((xmin - *x0) / shift) / (*x1 - *x0) * shift * shift;
y = *y0 + ((__int128) (*y1 - *y0)) * ((xmin - *x0)) / (*x1 - *x0);
x = xmin;
}