gbasys
diff src/gfx.c @ 12:a6ddf338a111
line clipping
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 01 Feb 2016 04:41:27 +0200 |
parents | 85f219fcdc82 |
children |
line diff
1.1 --- a/src/gfx.c Mon Feb 01 02:36:25 2016 +0200 1.2 +++ b/src/gfx.c Mon Feb 01 04:41:27 2016 +0200 1.3 @@ -245,3 +245,66 @@ 1.4 } 1.5 } 1.6 } 1.7 + 1.8 +enum { 1.9 + OUT_L = 1, 1.10 + OUT_R = 2, 1.11 + OUT_T = 4, 1.12 + OUT_B = 8 1.13 +}; 1.14 +static unsigned int outcode(int x, int y, int left, int top, int right, int bot) 1.15 +{ 1.16 + unsigned int res = 0; 1.17 + if(x < left) res |= OUT_L; 1.18 + if(x > right) res |= OUT_R; 1.19 + if(y < top) res |= OUT_T; 1.20 + if(y > bot) res |= OUT_B; 1.21 + return res; 1.22 +} 1.23 + 1.24 +int clip_line(int *x1, int *y1, int *x2, int *y2, int left, int top, int right, int bot) 1.25 +{ 1.26 + int i; 1.27 + unsigned int out1, out2; 1.28 + 1.29 + --right; 1.30 + --bot; 1.31 + out1 = outcode(*x1, *y1, left, top, right, bot); 1.32 + out2 = outcode(*x2, *y2, left, top, right, bot); 1.33 + 1.34 + for(;;) { 1.35 + int x, y; 1.36 + unsigned int outout; 1.37 + 1.38 + if((out1 | out2) == 0) 1.39 + return 1; /* both inside */ 1.40 + if(out1 & out2) 1.41 + return 0; /* both outside in the same area */ 1.42 + 1.43 + outout = out1 ? out1 : out2; 1.44 + if(outout & OUT_T) { 1.45 + x = *x1 + (float)(*x2 - *x1) * (float)(top - *y1) / (float)(*y2 - *y1); 1.46 + y = top; 1.47 + } else if(outout & OUT_B) { 1.48 + x = *x1 + (float)(*x2 - *x1) * (float)(bot - *y1) / (float)(*y2 - *y1); 1.49 + y = bot; 1.50 + } else if(outout & OUT_R) { 1.51 + y = *y1 + (float)(*y2 - *y1) * (float)(right - *x1) / (float)(*x2 - *x1); 1.52 + x = right; 1.53 + } else if(outout & OUT_L) { 1.54 + y = *y1 + (float)(*y2 - *y1) * (float)(left - *x1) / (float)(*x2 - *x1); 1.55 + x = left; 1.56 + } 1.57 + 1.58 + if(out1) { 1.59 + *x1 = x; 1.60 + *y1 = y; 1.61 + out1 = outcode(*x1, *y1, left, top, right, bot); 1.62 + } else { 1.63 + *x2 = x; 1.64 + *y2 = y; 1.65 + out2 = outcode(*x2, *y2, left, top, right, bot); 1.66 + } 1.67 + } 1.68 + return 1; 1.69 +}