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

📄 drawgraph.c

📁 源程序是在VisualDSP环境下开发出来的
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************

** 文件名:drawgraph.c

** Copyright (c) 1998-1999 *********公司技术开发部

** 创建人:

** 日 期:2003.06.25

** 修改人:

** 日 期:2003.08.27

** 描 述:画图形的函数的定义

** 版 本:

******************************************************************/
#include "hddamacros.h"
#include "globalvar.h"
#include <math.h>
#include "drawgraph.h"

/*****************************************************************

** 函数名:DrawHorizontalLine

** 输 入: int x1,int x2,int y,int color,int nFlags

** x1---直线左端的横坐标

** x2---直线右端的横坐标

** y ---直线的纵坐标

** color---直线的颜色

** nFlags---属性标志,在此有用的只有BLINKING位,指明直线是否闪烁

** 输 出: 无

** 功能描述:在屏幕上输出一条水平直线

** 调用模块:无

** 全局变量:g_nNumOfHorizontalLine

** 作 者:

** 日 期:2003.01.29

** 修改人:

** 日 期:2003.08.10

** 版 本:

****************************************************************/
void DrawHorizontalLine(int x1,int x2,int y,int color,int nFlags)
{
//取得栈顶指针
int *p=g_nHorizontalLine+(g_nNumOfHorizontalLine++)*4;
//如果直线需要闪烁并正处于闪烁的消失阶段,则直接返回
if((nFlags&BLINKING)&&g_nBlinkCounter<0) return;
//分别将左右端点的横坐标和纵坐标以及颜色值压入堆栈
*(p++)=x1;
*(p++)=x2;
*(p++)=y;
*(p++)=color;
return;
}

/*****************************************************************

** 函数名:Rectangle

** 输 入: int x1,int y1,int x2,int y2,int color,int nFlags

** x1---矩形左上角的横坐标

** y1---矩形左上角的纵坐标

** x2---矩形右下角的横坐标

** y2---矩形右下角的纵坐标

** color---直线的颜色

** nFlags---属性标志,在此有用的只有BLINKING位,指明矩形是否闪烁

** 输 出: 无

** 功能描述:在屏幕上输出一实心矩形

** 调用模块:无

** 全局变量:g_nNumOfHorizontalLine

** 作 者:

** 日 期:2003.01.29

** 修改人:

** 日 期:2003.08.10

** 版 本:

****************************************************************/
void Rectangle(int x1,int y1,int x2,int y2,int color,int nFlags)
{
int *p;
//如果直线需要闪烁并正处于闪烁的消失阶段,则直接返回
if((nFlags&BLINKING)&&g_nBlinkCounter<0) return;
//参数错误的情况
if(x1>x2||y1>y2)	return;
//取得栈顶指针
p=g_nHorizontalLine+g_nNumOfHorizontalLine*4;
//更新堆栈中的元数个数
g_nNumOfHorizontalLine+=y2-y1+1;
//从上到下依次用水平直线填充
for(;y1<=y2;y1++)
{
//分别将左右端点的横坐标和纵坐标以及颜色值压入堆栈
	*(p++)=x1;
	*(p++)=x2;
	*(p++)=y1;
	*(p++)=color;
}
return;
}
/*****************************************************************

** 函数名:Arc

** 输 入: int Ox,int Oy,int r,int startangle,int spanangle,int color,int nFlags

** Ox---圆心横坐标

** Oy---圆心纵坐标

** r---半径

** startangle---起始角,单位是角度

** spanangle---弧线角度,单位是角度,大于零为逆时针,小于零为顺时针

** color---圆弧的颜色

** nFlags---属性标志,在此有用的只有BLINKING位,指明圆弧是否闪烁

** 输 出: 无

** 功能描述:在屏幕上输出一圆弧

** 调用模块:Ellipse(int Ox,int Oy,int r,int color,int nFlags)

** 全局变量:g_nNumOfRotatedResult

** 作 者:

** 日 期:2003.01.29

** 修改人:

** 日 期:2003.08.10

** 版 本:

****************************************************************/

void Arc(int Ox,int Oy,int r,int startangle,int spanangle,int color,int nFlags)
{
//取得栈顶指针
	int *p=g_nRotatedResult+g_nNumOfRotatedResult*7;
	float coordinate[r];
	float ftemp;int itemp;
	int x1,x2,x,rcos45,squareofr;
	int endangle;
	//如果圆弧需要闪烁并正处于闪烁的消失阶段,则直接返回
	if((nFlags&BLINKING)&&g_nBlinkCounter<0) return;
	//只考虑逆时针方向,如果弧线方向为顺时针则将其转换为逆时针
	if(spanangle<0)
	{
		startangle+=spanangle;spanangle=-spanangle;
	}
	//如果弧线的跨度大于360度则调用画圆的函数后返回
	if(spanangle>=360)
	{
		Ellipse(Ox,Oy,r,color,nFlags);
		return;
	}
	//将起始角限制在[45,405)之内
	while(startangle>=360+45)
		startangle-=360;
	while(startangle<45)
		startangle+=360;
	//计算出结束角,应在[45,765}内
	endangle=startangle+spanangle;
	//求出一个八分之一圆弧的副轴坐标
	coordinate[0]=r;
	rcos45=r*0.70710678;squareofr=r*r;
	for(x=1;x<=rcos45;x++)
	{
		coordinate[x]=sqrt(squareofr-x*x);
	}
	//求出弧线在各个象限中的部分
	//上四分之一圆
	//45--135范围内
	if(startangle<=45+90)
	{
/*		x1=startangle;//肯定比45大
		x2=min(45+90,endangle);*/
		//从右到左
		x1=r*cos(startangle*PI_180);
		x2=r*cos(min(45+90,endangle)*PI_180);
		for(x=x2;x<=x1;x++)
		{
			*(p++)=x+Ox;
			itemp=abs(x);
			*(p++)=itemp=ftemp=Oy-coordinate[itemp];
			*(p++)=color;
			*(p++)=256-(itemp=(ftemp-itemp)*256);
			*(p++)=0;
			*(p++)=itemp;
			*(p++)=0;
		}
		g_nNumOfRotatedResult+=x1-x2+1;	
	}
	//405--495范围内
	if(endangle>=45+360)
	{
		/*45+360;
		min(45+360+90,endangle);*/
		x1=r*cos((45+360)*PI_180);
		x2=r*cos(min(45+360+90,endangle)*PI_180);
		for(x=x2;x<=x1;x++)
		{
			*(p++)=x+Ox;
			itemp=abs(x);
			*(p++)=itemp=ftemp=Oy-coordinate[itemp];
			*(p++)=color;
			*(p++)=256-(itemp=(ftemp-itemp)*256);
			*(p++)=0;
			*(p++)=itemp;
			*(p++)=0;
		}
		g_nNumOfRotatedResult+=x1-x2+1;
	}
	//下四分之一圆
	//225--315范围内
	if(startangle<=45+270&&endangle>=45+180)
	{
		//max(45+180,startangle);
		//min(45+270,endangle);
		x2=r*cos(max(45+180,startangle)*PI_180);
		x1=r*cos(min(45+270,endangle)*PI_180);
		for(x=x2;x<=x1;x++)
		{
			*(p++)=x+Ox;
			itemp=abs(x);
			*(p++)=itemp=ftemp=Oy+coordinate[itemp];
			*(p++)=color;
			*(p++)=256-(itemp=(ftemp-itemp)*256);
			*(p++)=0;
			*(p++)=itemp;
			*(p++)=0;
		}
		g_nNumOfRotatedResult+=x1-x2+1;
	}
	//585--675范围内
	if(endangle>=45+180+360)
	{
		//45+180+360;
		//min(45+270+360,endangle);
		x2=r*cos((45+180+360)*PI_180);
		x1=r*cos(min(45+270+360,endangle)*PI_180);
		for(x=x2;x<=x1;x++)
		{
			*(p++)=x+Ox;
			itemp=abs(x);
			*(p++)=itemp=ftemp=Oy+coordinate[itemp];
			*(p++)=color;
			*(p++)=256-(itemp=(ftemp-itemp)*256);
			*(p++)=0;
			*(p++)=itemp;
			*(p++)=0;
		}
		g_nNumOfRotatedResult+=x1-x2+1;
	}
	//左四分之一圆
	//135--215范围内
	if(startangle<=45+180&&endangle>=45+90)
	{
		//max(45+90,startangle);
		//min(45+180,endangle);
		x2=r*sin(max(45+90,startangle)*PI_180);
		x1=r*sin(min(45+180,endangle)*PI_180);
		for(x=x1;x<=x2;x++)
		{
			itemp=abs(x);
			*(p++)=itemp=ftemp=Ox-coordinate[itemp];
			*(p++)=Oy-x;
			*(p++)=color;
			*(p++)=256-(itemp=(ftemp-itemp)*256);
			*(p++)=itemp;
			*(p++)=0;
			*(p++)=0;
		}
		g_nNumOfRotatedResult+=x2-x1+1;	
	}
	//495-585范围内
	if(endangle>=45+90+360)
	{
		//45+90+360;
		//min(45+180+360,endangle);
		x2=r*sin((45+90+360)*PI_180);
		x1=r*sin(min(45+180+360,endangle)*PI_180);
		for(x=x1;x<=x2;x++)
		{
			itemp=abs(x);
			*(p++)=itemp=ftemp=Ox-coordinate[itemp];
			*(p++)=Oy-x;
			*(p++)=color;
			*(p++)=256-(itemp=(ftemp-itemp)*256);
			*(p++)=itemp;
			*(p++)=0;
			*(p++)=0;
		}
		g_nNumOfRotatedResult+=x2-x1+1;	
	}
	//右四分之一圆
	//315--405范围内
	if(endangle>=45+270)
	{
		//max(45+270,startangle);
		//min(45+360,endangle);
		x1=r*sin(max(45+270,startangle)*PI_180);
		x2=r*sin(min(45+360,endangle)*PI_180);
		for(x=x1;x<=x2;x++)
		{
			itemp=abs(x);
			*(p++)=itemp=ftemp=Ox+coordinate[itemp];
			*(p++)=Oy-x;
			*(p++)=color;
			*(p++)=256-(itemp=(ftemp-itemp)*256);
			*(p++)=itemp;
			*(p++)=0;
			*(p++)=0;
		}
		g_nNumOfRotatedResult+=x2-x1+1;
	}
	//765--675范围内
	if(endangle>=675)
	{
		//45+270+360;
		//endangle;肯定小于675
		x1=r*sin((45+270+360)*PI_180);
		x2=r*sin(endangle*PI_180);
		for(x=x1;x<=x2;x++)
		{
			itemp=abs(x);
			*(p++)=itemp=ftemp=Ox+coordinate[itemp];
			*(p++)=Oy-x;
			*(p++)=color;
			*(p++)=256-(itemp=(ftemp-itemp)*256);
			*(p++)=itemp;
			*(p++)=0;
			*(p++)=0;
		}
		g_nNumOfRotatedResult+=x2-x1+1;	
	}
}
/*****************************************************************

** 函数名:Ellipse

** 输 入: int Ox,int Oy,int r,int color,int nFlags

** Ox---圆心横坐标

** Oy---圆心纵坐标

** r---半径

** color---圆弧的颜色

** nFlags---属性标志,在此有用的只有BLINKING位,指明圆弧是否闪烁

** 输 出: 无

** 功能描述:在屏幕上输出一圆

** 调用模块:无

** 全局变量:g_nNumOfRotatedResult

** 作 者:

** 日 期:2003.01.29

** 修改人:

** 日 期:2003.08.10

** 版 本:

****************************************************************/

void Ellipse(int Ox,int Oy,int r,int color,int nFlags)
{
	int *p=g_nRotatedResult+g_nNumOfRotatedResult*7;
	float ftemp,coordinate;int itemp,fix1,fix2;
	int x,y,rcos45,squareofr;
	//如果圆需要闪烁并正处于闪烁的消失阶段,则直接返回
	if((nFlags&BLINKING)&&g_nBlinkCounter<0) return;
	rcos45=r*0.70710678;squareofr=r*r;
	for(x=0;x<=rcos45;x++)
	{
		coordinate=sqrt(squareofr-x*x);
		//45----90
		*(p++)=Ox+x;
		*(p++)=itemp=ftemp=Oy-coordinate;
		*(p++)=color;
		*(p++)=fix1=256-(fix2=(ftemp-itemp)*256);
		*(p++)=0;
		*(p++)=fix2;
		*(p++)=0;
		//90----135
		*(p++)=Ox-x;
		*(p++)=itemp;
		*(p++)=color;
		*(p++)=fix1;
		*(p++)=0;
		*(p++)=fix2;
		*(p++)=0;
		
		//270----315
		*(p++)=Ox+x;
		*(p++)=itemp=ftemp=Oy+coordinate;
		*(p++)=color;
		*(p++)=fix1=256-(fix2=(ftemp-itemp)*256);
		*(p++)=0;
		*(p++)=fix2;
		*(p++)=0;
		//225----270
		*(p++)=Ox-x;
		*(p++)=itemp=ftemp=Oy+coordinate;
		*(p++)=color;
		*(p++)=fix1;
		*(p++)=0;
		*(p++)=fix2;
		*(p++)=0;
		
		//-45----0
		*(p++)=itemp=ftemp=Ox+coordinate;
		*(p++)=Oy+x;
		*(p++)=color;
		*(p++)=fix1=256-(fix2=(ftemp-itemp)*256);
		*(p++)=fix2;
		*(p++)=*(p++)=0;
		//0----45
		*(p++)=itemp=ftemp=Ox+coordinate;
		*(p++)=Oy-x;
		*(p++)=color;
		*(p++)=fix1;
		*(p++)=fix2;
		*(p++)=*(p++)=0;
		
		//135----180
		*(p++)=itemp=ftemp=Ox-coordinate;
		*(p++)=Oy-x;
		*(p++)=color;
		*(p++)=fix1=256-(fix2=(ftemp-itemp)*256);
		*(p++)=fix2;
		*(p++)=*(p++)=0;
		//180----225
		*(p++)=itemp=ftemp=Ox-coordinate;
		*(p++)=Oy+x;
		*(p++)=color;
		*(p++)=fix1;
		*(p++)=fix2;
		*(p++)=*(p++)=0;
	}
	g_nNumOfRotatedResult+=x*8;
}


/*****************************************************************

** 函数名:Line1

** 输 入: int x1,int y1,int x2,int y2,int color,int nFlags

** x1---直线一端的横坐标

** y1---直线一端的纵坐标

** x2---直线另一端的横坐标

** y2---直线另一端的纵坐标

** color---直线的颜色

** nFlags---属性标志,在此有用的有BLINKING位,指明直线是否闪烁
								BFINALRESULT,指明直线是否最终结果,如否,产生中间结果后用Rotate函数旋转
								NEEDMODIFY,指明直线需否插值修正,需修正的话,BFINALRESULT位必须同时有效

** 输 出: 无

⌨️ 快捷键说明

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