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 +}