Commit 522eb2b9 authored by Sam Lantinga's avatar Sam Lantinga

Date: Sat, 3 Jan 2009 22:11:18 -0500

From: "Donny Viszneki"
Subject: Re: [SDL] Want to help with SDL 1.3?

>> > For example, here's a good quick project for someone from the TODO list:
>> > * Add diagonal line clipping to SDL_IntersectRectAndLine()

Just wanted to point out that the patch is available at
http://codebad.com/rect-line-ix.patch

I hereby grant Sam Lantinga an irrevocable non-exclusive distribution
license to this patch to do with as he wishes.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403456
parent 3ca7408d
...@@ -148,13 +148,13 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2, ...@@ -148,13 +148,13 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
return SDL_TRUE; return SDL_TRUE;
} }
/* Check to see if entire line is outside rect */ /* Check to see if entire line is to one side of rect */
if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) || if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
(y1 < recty1 && y2 < recty2) || (y1 > recty2 && y2 > recty2)) { (y1 < recty1 && y2 < recty2) || (y1 > recty2 && y2 > recty2)) {
return SDL_FALSE; return SDL_FALSE;
} }
if (y1 = y2) { if (y1 == y2) {
/* Horizontal line, easy to clip */ /* Horizontal line, easy to clip */
if (x1 < rectx1) { if (x1 < rectx1) {
*X1 = rectx1; *X1 = rectx1;
...@@ -184,7 +184,92 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2, ...@@ -184,7 +184,92 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
return SDL_TRUE; return SDL_TRUE;
} }
/* FIXME: need code to clip diagonal line to rect */ else
{
/* The task of clipping a line with finite slope ratios in a fixed-
* precision coordinate space is not as immediately simple as it is
* with coordinates of arbitrary precision. If the ratio of slopes
* between the input line segment and the result line segment is not
* a whole number, you have in fact *moved* the line segment a bit,
* and there can be no avoiding it without more precision
*/
int *x_result_[] = {X1, X2, NULL}, **x_result = x_result_;
int *y_result_[] = {Y1, Y2, NULL}, **y_result = y_result_;
SDL_bool intersection = SDL_FALSE;
double b, m, left, right, bottom, top;
int xl, xh, yl, yh;
/* solve mx+b line formula */
m = (double)(y1-y2) / (double)(x1-x2);
b = y2 - m * (double) x2;
/* find some linear intersections */
left = (m * (double) rectx1) + b;
right = (m * (double) rectx2) + b;
top = (recty1 - b) / m;
bottom = (recty2 - b) / m;
/* sort end-points' x and y components individually */
if (x1 < x2) {
xl = x1;
xh = x2;
} else {
xl = x2;
xh = x1;
}
if (y1 < y2) {
yl = y1;
yh = y2;
} else {
yl = y2;
yh = y1;
}
#define RISING(a, b, c) (((a)<=(b))&&((b)<=(c)))
/* check for a point that's entirely inside the rect */
if (RISING(rectx1, x1, rectx2) && RISING(recty1, y1, recty2)) {
x_result++;
y_result++;
intersection = SDL_TRUE;
} else /* it was determined earlier that *both* end-points are not contained */
if (RISING(rectx1, x2, rectx2) && RISING(recty1, y2, recty2)) {
**(x_result++) = x2;
**(y_result++) = y2;
intersection = SDL_TRUE;
}
if (RISING(recty1, left, recty2) && RISING(xl, rectx1, xh)) {
**(x_result++) = rectx1;
**(y_result++) = (int) left;
intersection = SDL_TRUE;
}
if (*x_result == NULL) return intersection;
if (RISING(recty1, right, recty2) && RISING(xl, rectx2, xh)) {
**(x_result++) = rectx2;
**(y_result++) = (int) right;
intersection = SDL_TRUE;
}
if (*x_result == NULL) return intersection;
if (RISING(rectx1, top, rectx2) && RISING(yl, recty1, yh)) {
**(x_result++) = (int) top;
**(y_result++) = recty1;
intersection = SDL_TRUE;
}
if (*x_result == NULL) return intersection;
if (RISING(rectx1, bottom, rectx2) && RISING(yl, recty2, yh)) {
**(x_result++) = (int) bottom;
**(y_result++) = recty2;
intersection = SDL_TRUE;
}
return intersection;
}
return SDL_FALSE; return SDL_FALSE;
} }
......
...@@ -7,7 +7,7 @@ EXE = @EXE@ ...@@ -7,7 +7,7 @@ EXE = @EXE@
CFLAGS = @CFLAGS@ CFLAGS = @CFLAGS@
LIBS = @LIBS@ LIBS = @LIBS@
TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testaudioinfo$(EXE) testmultiaudio$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testdraw2$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) testhaptic$(EXE) testmmousetablet$(EXE) TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testaudioinfo$(EXE) testmultiaudio$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testintersections$(EXE) testdraw2$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) testhaptic$(EXE) testmmousetablet$(EXE)
all: Makefile $(TARGETS) all: Makefile $(TARGETS)
...@@ -44,6 +44,9 @@ testcdrom$(EXE): $(srcdir)/testcdrom.c ...@@ -44,6 +44,9 @@ testcdrom$(EXE): $(srcdir)/testcdrom.c
testcursor$(EXE): $(srcdir)/testcursor.c testcursor$(EXE): $(srcdir)/testcursor.c
$(CC) -o $@ $? $(CFLAGS) $(LIBS) $(CC) -o $@ $? $(CFLAGS) $(LIBS)
testintersections$(EXE): $(srcdir)/testintersections.c $(srcdir)/common.c
$(CC) -o $@ $(srcdir)/testintersections.c $(srcdir)/common.c $(CFLAGS) $(LIBS)
testdraw2$(EXE): $(srcdir)/testdraw2.c $(srcdir)/common.c testdraw2$(EXE): $(srcdir)/testdraw2.c $(srcdir)/common.c
$(CC) -o $@ $(srcdir)/testdraw2.c $(srcdir)/common.c $(CFLAGS) $(LIBS) $(CC) -o $@ $(srcdir)/testdraw2.c $(srcdir)/common.c $(CFLAGS) $(LIBS)
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment