Mercurial > sdl-ios-xcode
comparison src/video/SDL_rect.c @ 2994:7563b99e9a49
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.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 04 Jan 2009 19:33:21 +0000 |
parents | cdb01906cb7e |
children | e4f025078c1c |
comparison
equal
deleted
inserted
replaced
2993:2fad80c77c17 | 2994:7563b99e9a49 |
---|---|
146 if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 && | 146 if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 && |
147 y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) { | 147 y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) { |
148 return SDL_TRUE; | 148 return SDL_TRUE; |
149 } | 149 } |
150 | 150 |
151 /* Check to see if entire line is outside rect */ | 151 /* Check to see if entire line is to one side of rect */ |
152 if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) || | 152 if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) || |
153 (y1 < recty1 && y2 < recty2) || (y1 > recty2 && y2 > recty2)) { | 153 (y1 < recty1 && y2 < recty2) || (y1 > recty2 && y2 > recty2)) { |
154 return SDL_FALSE; | 154 return SDL_FALSE; |
155 } | 155 } |
156 | 156 |
157 if (y1 = y2) { | 157 if (y1 == y2) { |
158 /* Horizontal line, easy to clip */ | 158 /* Horizontal line, easy to clip */ |
159 if (x1 < rectx1) { | 159 if (x1 < rectx1) { |
160 *X1 = rectx1; | 160 *X1 = rectx1; |
161 } else if (x1 > rectx2) { | 161 } else if (x1 > rectx2) { |
162 *X1 = rectx2; | 162 *X1 = rectx2; |
182 *Y2 = recty2; | 182 *Y2 = recty2; |
183 } | 183 } |
184 return SDL_TRUE; | 184 return SDL_TRUE; |
185 } | 185 } |
186 | 186 |
187 /* FIXME: need code to clip diagonal line to rect */ | 187 else |
188 { | |
189 /* The task of clipping a line with finite slope ratios in a fixed- | |
190 * precision coordinate space is not as immediately simple as it is | |
191 * with coordinates of arbitrary precision. If the ratio of slopes | |
192 * between the input line segment and the result line segment is not | |
193 * a whole number, you have in fact *moved* the line segment a bit, | |
194 * and there can be no avoiding it without more precision | |
195 */ | |
196 int *x_result_[] = {X1, X2, NULL}, **x_result = x_result_; | |
197 int *y_result_[] = {Y1, Y2, NULL}, **y_result = y_result_; | |
198 SDL_bool intersection = SDL_FALSE; | |
199 double b, m, left, right, bottom, top; | |
200 int xl, xh, yl, yh; | |
201 | |
202 /* solve mx+b line formula */ | |
203 m = (double)(y1-y2) / (double)(x1-x2); | |
204 b = y2 - m * (double) x2; | |
205 | |
206 /* find some linear intersections */ | |
207 left = (m * (double) rectx1) + b; | |
208 right = (m * (double) rectx2) + b; | |
209 top = (recty1 - b) / m; | |
210 bottom = (recty2 - b) / m; | |
211 | |
212 /* sort end-points' x and y components individually */ | |
213 if (x1 < x2) { | |
214 xl = x1; | |
215 xh = x2; | |
216 } else { | |
217 xl = x2; | |
218 xh = x1; | |
219 } | |
220 if (y1 < y2) { | |
221 yl = y1; | |
222 yh = y2; | |
223 } else { | |
224 yl = y2; | |
225 yh = y1; | |
226 } | |
227 | |
228 #define RISING(a, b, c) (((a)<=(b))&&((b)<=(c))) | |
229 | |
230 /* check for a point that's entirely inside the rect */ | |
231 if (RISING(rectx1, x1, rectx2) && RISING(recty1, y1, recty2)) { | |
232 x_result++; | |
233 y_result++; | |
234 intersection = SDL_TRUE; | |
235 } else /* it was determined earlier that *both* end-points are not contained */ | |
236 | |
237 if (RISING(rectx1, x2, rectx2) && RISING(recty1, y2, recty2)) { | |
238 **(x_result++) = x2; | |
239 **(y_result++) = y2; | |
240 intersection = SDL_TRUE; | |
241 } | |
242 | |
243 if (RISING(recty1, left, recty2) && RISING(xl, rectx1, xh)) { | |
244 **(x_result++) = rectx1; | |
245 **(y_result++) = (int) left; | |
246 intersection = SDL_TRUE; | |
247 } | |
248 | |
249 if (*x_result == NULL) return intersection; | |
250 if (RISING(recty1, right, recty2) && RISING(xl, rectx2, xh)) { | |
251 **(x_result++) = rectx2; | |
252 **(y_result++) = (int) right; | |
253 intersection = SDL_TRUE; | |
254 } | |
255 | |
256 if (*x_result == NULL) return intersection; | |
257 if (RISING(rectx1, top, rectx2) && RISING(yl, recty1, yh)) { | |
258 **(x_result++) = (int) top; | |
259 **(y_result++) = recty1; | |
260 intersection = SDL_TRUE; | |
261 } | |
262 | |
263 if (*x_result == NULL) return intersection; | |
264 if (RISING(rectx1, bottom, rectx2) && RISING(yl, recty2, yh)) { | |
265 **(x_result++) = (int) bottom; | |
266 **(y_result++) = recty2; | |
267 intersection = SDL_TRUE; | |
268 } | |
269 | |
270 return intersection; | |
271 } | |
272 | |
188 return SDL_FALSE; | 273 return SDL_FALSE; |
189 } | 274 } |
190 | 275 |
191 void | 276 void |
192 SDL_AddDirtyRect(SDL_DirtyRectList * list, const SDL_Rect * rect) | 277 SDL_AddDirtyRect(SDL_DirtyRectList * list, const SDL_Rect * rect) |