⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 draw.c

📁 sgl数值计算函数库
💻 C
字号:
#include <math.h>
#include "sgltype.h"
#include "sglutility.h"

extern sglDevice sgl;

void draw_line( int x0, int y0, int x1, int y1, 
			   void (*pixel)(int, int), 
			   void (*hline)(int, int, int),
			   void (*vline)(int, int, int) )
{
	int xdiff = x1 - x0;	
	int ydiff = y1 - y0;
	int xadd, yadd;
	int xinc, yinc;
	int x,y;
	int sum = 0;

	if ( xdiff > 0 )
	{
		xinc=1;
		xadd=xdiff;
	}
	else if ( xdiff < 0 )
	{
		xinc=-1;
		xadd=-xdiff;
	}
	else
	{
		xinc = xadd = 0;
	}

	if ( ydiff > 0 )
	{
		yinc=1;
		yadd=ydiff;
	}
	else if ( ydiff < 0 )
	{
		yinc=-1;
		yadd=-ydiff;
	}
	else
	{
		yinc = yadd = 0;
	}

	x=x0;
	y=y0;

	if ( xadd==0 && yadd==0 )
	{
		pixel(x,y);
	}
	else if ( xadd==0 )
	{
		vline(x,y,ydiff>0 ? ydiff+1:ydiff-1);
	}
	else if ( yadd==0 )
	{
		hline(x,y,xdiff>0? xdiff+1:xdiff-1);
	}
	else if ( xadd > yadd )
	{
		while(x!=x1)
		{
			pixel(x,y);
			x+=xinc;
			sum+=yadd;
			if ( sum>=xadd )
			{
				y+=yinc;
				sum-=xadd;
			}
		}
		pixel(x,y);
	}
	else if ( xadd < yadd )
	{
		while(y!=y1)
		{
			pixel(x,y);
			y+=yinc;
			sum+=xadd;
			if ( sum>=yadd )
			{
				x+=xinc;
				sum-=yadd;
			}
		}
		pixel(x,y);
	}
	else /* xadd = yadd */
	{
		while(x!=x1)
		{
			pixel(x,y);
			x+=xinc;
			y+=yinc;
		}
		pixel(x,y);
	}
}

static void _symetry(int xs, int ys, int x, int y, void (*pixel)(int,int))
{
	pixel(xs + x, ys + y);
	pixel(xs - x, ys + y);
	pixel(xs + x, ys - y);
	pixel(xs - x, ys - y);
	pixel(xs + y, ys + x);
	pixel(xs - y, ys + x);
	pixel(xs + y, ys - x);
	pixel(xs - y, ys - x);
}

void draw_circle( int xs, int ys, int r, void (*pixel)(int,int) )
{
	int	x =	0;
	int	y =	r;
	int	p =	3 -	2 *	r;

	if ((ys	+ r) < 0 || 
		(xs + r) < 0 ||	
		(ys	- r) >=	sgl.Height || 
		(xs - r) >= sgl.Width  ||
		 r < 1 ) 
		return;

	while (x < y)
	{
		_symetry(xs, ys, x,	y, pixel);
		if (p <	0)
			p += 4 * (x++) + 6;
		else
			p += 4 * ((x++)	- (y--)) + 10;
	}
	if (x == y)
		_symetry(xs, ys, x,	y, pixel);
}

static void _symetry2(int xs, int ys, int x, int y, void (*hline)(int,int,int) )
{
	hline(xs-x,ys+y,x+x);
	hline(xs-x,ys-y,x+x);
	hline(xs-y,ys+x,y+y);
	hline(xs-y,ys-x,y+y);
}

void draw_filled_circle(int xs, int	ys, int	r, void (*hline)(int,int,int) )
{
	int	x =	0;
	int	y =	r;
	int	p =	3 -	2 *	r;

	if ((ys	+ r) < 0 || 
		(xs + r) < 0 ||	
		(ys	- r) >= sgl.Height || 
		(xs - r) >= sgl.Width  ||
		 r < 1) 
		 return;

	while (x < y)
	{
		_symetry2(xs, ys, x, y, hline);
		if (p <	0)
			p += 4 * (x++) + 6;
		else
			p += 4 * ((x++)	- (y--)) + 10;
	}
	if (x == y)
		_symetry2(xs, ys, x, y, hline);
}

void draw_ellipse(int x, int y, int rx, int ry, void (*pixel)(int,int) )
{
	int ix, iy;
	int h, i, j, k;
	int oh, oi, oj, ok;
	
	if (rx < 1) rx = 1;
	if (ry < 1) ry = 1;

	h = i = j = k = 0xFFFF;

	if (rx > ry)
	{
		ix = 0;
		iy = rx * 64;
		do
		{
			oh = h;
			oi = i;
			oj = j;
			ok = k;
			h = (ix + 32) >> 6;
			i = (iy + 32) >> 6;
			j = (h * ry) / rx;
			k = (i * ry) / rx;
			if (((h != oh) || (k != ok)) && (h < oi))
			{
				pixel(x + h, y + k);
				if (h) pixel(x - h, y + k);
				if (k)
				{
					pixel(x + h, y - k);
					if (h) pixel(x - h, y - k);
				}
			}

			if (((i != oi) || (j != oj)) && (h < i))
			{
				pixel(x + i, y + j);
				if (i)
					pixel(x - i, y + j);
				if (j)
				{
					pixel(x + i, y - j);
					if (i)
						pixel(x - i, y - j);
				}
			}

			ix = ix + iy / rx;
			iy = iy - ix / rx;

		}
		while (i > h);
	}
	else
	{
		ix = 0;
		iy = ry * 64;

		do
		{
			oh = h;
			oi = i;
			oj = j;
			ok = k;

			h = (ix + 32) >> 6;
			i = (iy + 32) >> 6;
			j = (h * rx) / ry;
			k = (i * rx) / ry;

			if (((j != oj) || (i != oi)) && (h < i))
			{
				pixel(x + j, y + i);
				if (j) pixel(x - j, y + i);
				if (i) 
				{
					pixel(x + j, y - i);
					if (j) pixel(x - j, y - i);
				}
			}

			if (((k != ok) || (h != oh)) && (h < oi))
			{
				pixel(x + k, y + h);
				if (k) pixel(x - k, y + h);
				if (h)
				{
					pixel(x + k, y - h);
					if (k) pixel(x - k, y - h);
				}
			}
			ix = ix + iy / ry;
			iy = iy - ix / ry;
		}
		while (i > h);
	}
}

void draw_filled_ellipse(int x, int y, int rx, int ry, void (*hline)(int,int,int) )
{
	int ix, iy;
	int a, b, c, d;
	int da, db, dc, dd;
	int na, nb, nc, nd;

	if (rx > ry)
	{
		dc = -1;
		dd = 0xFFFF;
		ix = 0;
		iy = rx * 64;
		na = 0;
		nb = (iy + 32) >> 6;
		nc = 0;
		nd = (nb * ry) / rx;

		do
		{
			a = na;
			b = nb;
			c = nc;
			d = nd;

			ix = ix + (iy / rx);
			iy = iy - (ix / rx);
			na = (ix + 32) >> 6;
			nb = (iy + 32) >> 6;
			nc = (na * ry) / rx;
			nd = (nb * ry) / rx;

			if ((c > dc) && (c < dd))
			{
				hline(x - b, y + c, b * 2);
				if (c)
					hline(x - b, y - c, b * 2);
				dc = c;
			}

			if ((d < dd) && (d > dc))
			{
				hline(x - a, y + d, a * 2);
				hline(x - a, y - d, a * 2);
				dd = d;
			}

		}
		while (b > a);
	}
	else
	{
		da = -1;
		db = 0xFFFF;
		ix = 0;
		iy = ry * 64;
		na = 0;
		nb = (iy + 32) >> 6;
		nc = 0;
		nd = (nb * rx) / ry;

		do
		{
			a = na;
			b = nb;
			c = nc;
			d = nd;

			ix = ix + (iy / ry);
			iy = iy - (ix / ry);
			na = (ix + 32) >> 6;
			nb = (iy + 32) >> 6;
			nc = (na * rx) / ry;
			nd = (nb * rx) / ry;

			if ((a > da) && (a < db))
			{
				hline(x - d, y + a, d * 2);
				if (a)
					hline(x - d, y - a, d * 2);
				da = a;
			}

			if ((b < db) && (b > da))
			{
				hline(x - c, y + b, c * 2);
				hline(x - c, y - b, c * 2);
				db = b;
			}

		}
		while (b > a);
	}
}

void draw_arc(int x, int y, int r, float ang1, float ang2, void (*pixel)(int,int) )
{
	int px, py;
	int ex, ey;
	int px1, px2, px3;
	int py1, py2, py3;
	int d1, d2, d3;
	int ax, ay;
	int q, qe;
	float tg_cur, tg_end;
	int done = 0;
	double rr1, rr2, rr3;
	int rr = (r * r);

	rr1 = r;
	rr2 = x;
	rr3 = y;

	/* evaluate the start point and the end point */
	px = (int) (rr2 + rr1 * sglcos(ang1));
	py = (int) (rr3 - rr1 * sglsin(ang1));
	ex = (int) (rr2 + rr1 * sglcos(ang2));
	ey = (int) (rr3 - rr1 * sglsin(ang2));

	/* start quadrant */
	if (px >= x)
	{
		if (py <= y)
			q = 1;				/* quadrant 1 */
		else
			q = 4;				/* quadrant 4 */
	}
	else
	{
		if (py < y)
			q = 2;				/* quadrant 2 */
		else
			q = 3;				/* quadrant 3 */
	}

	/* end quadrant */
	if (ex >= x)
	{
		if (ey <= y)
			qe = 1;				/* quadrant 1 */
		else
			qe = 4;				/* quadrant 4 */
	}
	else
	{
		if (ey < y)
			qe = 2;				/* quadrant 2 */
		else
			qe = 3;				/* quadrant 3 */
	}

#define loc_tg(_y, _x)  (_x-x) ? (float)(_y-y)/(_x-x) : (float)(_y-y)

	tg_end = loc_tg(ey, ex);

	while (!done)
	{
		pixel(px, py);

		/* from here, we have only 3 possible direction of movement, eg.
		 * for the first quadrant:
		 *
		 *    OOOOOOOOO
		 *    OOOOOOOOO
		 *    OOOOOO21O
		 *    OOOOOO3*O
		 */

		/* evaluate the 3 possible points */
		switch (q)
		{

			case 1:
				px1 = px;
				py1 = py - 1;
				px2 = px - 1;
				py2 = py - 1;
				px3 = px - 1;
				py3 = py;

				/* 2nd quadrant check */
				if (px != x)
				{
					break;
				}
				else
				{
					/* we were in the end quadrant, changing is illegal. Exit. */
					if (qe == q)
						done = 1;
					q++;
				}
				/* fall through */

			case 2:
				px1 = px - 1;
				py1 = py;
				px2 = px - 1;
				py2 = py + 1;
				px3 = px;
				py3 = py + 1;

				/* 3rd quadrant check */
				if (py != y)
				{
					break;
				}
				else
				{
					/* we were in the end quadrant, changing is illegal. Exit. */
					if (qe == q)
						done = 1;
					q++;
				}
				/* fall through */

			case 3:
				px1 = px;
				py1 = py + 1;
				px2 = px + 1;
				py2 = py + 1;
				px3 = px + 1;
				py3 = py;

				/* 4th quadrant check */
				if (px != x)
				{
					break;
				}
				else
				{
					/* we were in the end quadrant, changing is illegal. Exit. */
					if (qe == q)
						done = 1;
					q++;
				}
				/* fall through */

			case 4:
				px1 = px + 1;
				py1 = py;
				px2 = px + 1;
				py2 = py - 1;
				px3 = px;
				py3 = py - 1;

				/* 1st quadrant check */
				if (py == y)
				{
					/* we were in the end quadrant, changing is illegal. Exit. */
					if (qe == q)
						done = 1;

					q = 1;
					px1 = px;
					py1 = py - 1;
					px2 = px - 1;
					py2 = py - 1;
					px3 = px - 1;
					py3 = py;
				}
				break;

			default:
				return;
		}

		/* now, we must decide which of the 3 points is the right point.
		 * We evaluate the distance from center and, then, choose the
		 * nearest point.
		 */
		ax = x - px1;
		ay = y - py1;
		rr1 = ax * ax + ay * ay;

		ax = x - px2;
		ay = y - py2;
		rr2 = ax * ax + ay * ay;

		ax = x - px3;
		ay = y - py3;
		rr3 = ax * ax + ay * ay;

		/* difference from the main radius */
		if (rr1 > rr)
			d1 = (int) (rr1 - rr);
		else
			d1 = (int) (rr - rr1);
		if (rr2 > rr)
			d2 = (int) (rr2 - rr);
		else
			d2 = (int) (rr - rr2);
		if (rr3 > rr)
			d3 = (int) (rr3 - rr);
		else
			d3 = (int) (rr - rr3);

		/* what is the minimum? */
		if (d1 <= d2)
		{
			px = px1;
			py = py1;
		}
		else if (d2 <= d3)
		{
			px = px2;
			py = py2;
		}
		else
		{
			px = px3;
			py = py3;
		}

		/* are we in the final quadrant? */
		if (qe == q)
		{
			tg_cur = loc_tg(py, px);

			/* is the arc finished? */
			switch (q)
			{

				case 1:
					/* end quadrant = 1? */
					if (tg_cur <= tg_end)
						done = 1;
					break;

				case 2:
					/* end quadrant = 2? */
					if (tg_cur <= tg_end)
						done = 1;
					break;

				case 3:
					/* end quadrant = 3? */
					if (tg_cur <= tg_end)
						done = 1;
					break;

				case 4:
					/* end quadrant = 4? */
					if (tg_cur <= tg_end)
						done = 1;
					break;
			}
		}
	}

	/* draw the last evaluated point */
	pixel(px, py);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -