📄 drawgraph.c
字号:
/******************************************************************
** 文件名: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 + -