- 苏萦
-
有关图形窗口和图形屏幕操作函数
一、图形窗口操作
象文本方式下可以设定屏幕窗口一样,图形方式下也可以在屏幕上某一区域设定窗口,只是设定的为图形窗口而已,其后的有关图形操作都将以这个窗口的左上角 (0, 0)作为坐标原点,而且可为通过设置使窗口之外的区域为不可接触。这样,所有的图形操作就被限定在窗口内进行。 void far setviewport(int xl,int yl,int x2, int y2,int clipflag); 设定一个以(xl,yl)象元点为左上角,(x2,y2)象元为右下角的图
形窗口,其中x1,y1,x2,y2是相对于整个屏幕的坐标。若 clipflag为非0,则设定的图形以外部分不可接触,若clipflag为0,则图形窗口
以外可以接触。
void far clearviewport(void); 清除现行图形窗口的内容。
void far getviewsettings(struct viewporttypefar * viewport); 获得关于现行窗口的信息,并将其存于viewporttype定义的结构
变量viewport中,其中viewporttype的结构说明如下:
struct viewporttype
{
int left, top, right, bottom;
int cliplag;
};
注明:
1. 窗口颜色的设置与前面讲过的屏幕颜色设置相同,但屏幕背景色和窗口背景色只能是一种颜色,如果窗口背景色改变,整个屏幕的背景色也将改变这与文本窗口不同。
2. 可以在同一个屏幕上设置多个窗口,但只能有一个现行窗口工作,要对其它窗口操作,通过将定义那个窗口的setviewport()函数再用一次即可。
3. 前面讲过图形屏幕操作的函数均适合于对窗口的操作。
二、屏幕操作
除了清屏函数以外,关于屏幕操作还有以下函数:
void far setactivepage(int pagenum); void far setvisualpage(int pagenum);这两个函数只用于EGA,VGA 以及HERCULES图形适配器。 setctivepage()函数是为图形输出选择激活页。所谓激活页是指后续图形的输出被写到函数选定的 pagenum页面,该页面并不一定可见。
setvisualpage()函数才使pagenum所指定的页面变成可见页。页面从0开始(Turbo C默认页)。如果先用setactivepage() 函数在不同页面
上画出一幅幅图像,再用setvisualpage() 函数交替显示,就可以实现一些动画的效果。
void far getimage(int xl,int yl, int x2,int y2,void far *mapbuf); void far putimge(int x,int,y,void * mapbuf, int op); unsined far imagesize(int xl,int yl,int x2,int y2);
这三个函数用于将屏幕上的图像复制到内存,然后再将内存中的图像送回到屏幕上。首先通过函数imagesize() 测试要保存左上角为
(xl,yl),右上角为(x2,y2)的图形屏幕区域内的全部内容需多少个字节,然后再给mapbuf分配一个所测数字节内存空间的指针。通过调用
getimage()函数就可将该区域内的图像保存在内存中,需要时可用putimage()函数将该图像输出到左上角为点(x, y)的位置上,其中
getimage()函数中的参数op规定如何释放内存中图像。 关于这个参数的定义参见下表:
putimage()函数中的op值
━━━━━━━━━━━━━━━━━━━━━━━━━━
符号常数 数值 含 义
——————————————————————————
COPY_PUT 0 复制
XOR_PUT 1 与屏幕图像异或的复制
OR_PUT 2 与屏幕图像或后复制
AND_PUT 3 与屏幕图像与后复制
NOT_PUT 4 复制反像的图形
━━━━━━━━━━━━━━━━━━━━━━━━━━
对于imagesize()函数,只能返回字节数小于64K字节的图像区域,否则将会出错,出错时返回-1。
本节介绍的函数在图像动画处理、菜单设计技巧中非常有用。
下面程序模拟两个小球动态碰撞过程。#include
#include
#include
int main()
{
int i, gdriver, gmode, size;
void *buf;
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\caic\bgi");
setbkcolor(BLUE);
cleardevice();
setcolor(LIGHTRED);
setlinestyle(0,0,1);
setfillstyle(1, 10);
circle(100, 200, 30);
floodfill(100, 200, 12);
size=imagesize(69, 169, 131, 231);
buf=malloc(size);
if(!buf) return -1;
getimage(69, 169, 131, 231,buf);
putimage(500, 269, buf, COPY_PUT);
for(i=0; i<185; i++){
putimage(70+i, 170, buf, COPY_PUT);
putimage(500-i, 170, buf, COPY_PUT);
}
for(i=0;i<185; i++){
putimage(255-i, 170, buf, COPY_PUT);
putimage(315+i, 170, buf, COPY_PUT);
}
getch();
closegraph();
}
图形模式下的文本输出
在图形模式下,只能用标准输出函数,如printf(),puts(),putchar()函数输出文本到屏幕。除此之外,其它输出函数(如窗口输出函数)不能使用,即是可以输出的标准函数,也只以前景色为白色,按80列,25行的文本方式输出。
Turbo C2.0也提供了一些专门用于在图形显示模式下的文本输出函数。下面将分别进行介绍。
一、文本输出函数 void far outtext(char far *textstring); 该函数输出字符串指针textstring所指的文本在现行位置。
void far outtextxy(int x, int y, char far *textstring);该函数输出字符串指针textstring所指的文本在规定的(x, y)位置。其中x和y为象元坐标。
说明:
这两个函数都是输出字符串,但经常会遇到输出数值或其它类型的数据,此时就必须使用格式化输出函数sprintf()。sprintf()函数的调用格式为: int sprintf(char *str, char *format, variable-list); 它与printf()函数不同之处是将按格式化规定的内容写入str 指向的字符串中,返回值等于写入的字符个数。
例如:
"C110F1sprintf(s, "your TOEFL score is %d", mark);这里s应是字符串指针或数组,mark为整型变量。
二、有关文本字体、字型和输出方式的设置
有关图形方式下的文本输出函数,可以通过setcolor()函数设置输出文本的颜色。另外,也可以改变文本字体大小以及选择是水平方向输出还是垂直方向输出。
void far settexjustify(int horiz, int vert); 该函数用于定位输出字符串。
对使用outtextxy(int x, int y, char far *str textstring)函数所输出的字符串,其中哪个点对应于定位坐标(x,y)在TurboC2.0中是有规定的。如果把一个字符串看成一个长方形的图形,在水平方向显示时,字符串长方形按垂直方向可分为顶部,中部和底部三个位置,水平方向可分为左,中,右三个位置,两者结合就有9个位置。
settextjustify()函数的第一个参数horiz 指出水平方向三个位置中的一个,第二个参数vert指出垂直方向三个位置中的一个,二者就确定了其中一个位置。当规定了这个位置后,用outtextxy () 函数输出字符串时,字符串长方形的这个规定位置就对准函数中的(x,y)位置。而对用outtext()函数输出字符串时,这个规定的位置就位于现行游标的位置。有关参数 horiz和vert的取值参见下表:
参数horiz和vert的取值
━━━━━━━━━━━━━━━━━━━━━━━━
符号常数 数值 用于
————————————————————————
LEFT_TEXT 0 水平
RIGHT_TEXT 2 水平
BOTTOM_TEXT 0 垂直
TOP_TEXT 2 垂直
CENTER_TEXT 1 水平或垂直
━━━━━━━━━━━━━━━━━━━━━━━━
void far settextstyle(int font, int direction,int charsize);
该函数用来设置输出字符的字形(由font确定)、输出方向(由direction确定)和字符大小(由charsize确定)等特性。
Turbo C2.0对函数中各个参数的规定见下列各表所示:
font的取值
━━━━━━━━━━━━━━━━━━━━━━━━
符号常数 数值 含义
————————————————————————
DEFAULT_FONT 0 8*8点阵字(缺省值)
TRIPLEX_FONT 1 三倍笔划字体
SMALL_FONT 2 小号笔划字体
SANSSERIF_FONT 3 无衬线笔划字体
GOTHIC_FONT 4 黑体笔划字
━━━━━━━━━━━━━━━━━━━━━━━━
direction的取值
━━━━━━━━━━━━━━━━━━━━━━━━
符号常数 数值 含义
————————————————————————
HORIZ_DIR 0 从左到右
VERT_DIR 1 从底到顶
━━━━━━━━━━━━━━━━━━━━━━━━
charsize的取值
━━━━━━━━━━━━━━━━━━━━━━━━
符号常数或数值 含义
————————————————————————
1 8*8点阵
2 16*16点阵
3 24*24点阵
4 32*32点阵
5 40*40点阵
6 48*48点阵
7 56*56点阵
8 64*64点阵
9 72*72点阵
10 80*80点阵
USER_CHAR_SIZE=0 用户定义的字符大小
━━━━━━━━━━━━━━━━━━━━━━━━
有关图形屏幕下文本输出和字体字型设置函数的用法请看下例:#include
#include
int main()
{
int i, gdriver, gmode;
char s[30];
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\caic\bgi");
setbkcolor(BLUE);
cleardevice();
setviewport(100, 100, 540, 380, 1);
/*定义一个图形窗口*/
setfillstyle(1, 2); /*绿色以实填充*/
setcolor(YELLOW);
rectangle(0, 0, 439, 279);
floodfill(50, 50, 14);
setcolor(12);
settextstyle(1, 0, 8);
/*三重笔划字体, 水平放大8倍*/
outtextxy(20, 20, "Good Better");
setcolor(15);
settextstyle(3, 0, 5);
/*无衬笔划字体, 水平放大5倍*/
outtextxy(120, 120, "Good Better");
setcolor(14);
settextstyle(2, 0, 8);
i=620;
sprintf(s, "Your score is %d", i);
/*将数字转化为字符串*/
outtextxy(30, 200, s);
/*指定位置输出字符串*/
setcolor(1);
settextstyle(4, 0, 3);
outtextxy(70, 240, s);
getch();
closegraph();
return 0;
}
三、用户对文本字符大小的设置
前面介绍的settextstyle()函数,可以设定图形方式下输出文本字符这字体和大小但对于笔划型字体(除8*8点阵字以个的字体),只能在水平和垂直方向以相同的放大倍数放大。为此Turbo C2.0又提供了另外一个setusercharsize() 函数,对笔划字体可以分别设置水平和垂直方向的放大倍数。该函数的调用格式为:
void far setusercharsize(int mulx, int divx,int muly, int divy); 该函数用来设置笔划型字和放大系数,它只有在settextstyle()
函数中的charsize为0(或USER_CHAR_SIZE)时才起作用,并且字体为函数settextstyle()规定的字体。调用函数 setusercharsize()后,每个显示在屏幕上的字符都以其缺省大小乘以mulx/divx为输出字符宽,乘以muly/divy为输出字符高。该函数的用法见下例:
#include
#include
int main()
{
int gdriver, gmode;
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\caic\bgi");
setbkcolor(BLUE);
cleardevice();
setfillstyle(1, 2); /*设置填充方式*/
setcolor(WHITE); /*设置白色作图*/
rectangle(100, 100, 330, 380);
floodfill(50, 50, 14); /*填充方框以外的区域*/
setcolor(12); /*作图色为淡红*/
settextstyle(1, 0, 8); /*三重笔划字体,放大8倍*/
outtextxy(120, 120, "Very Good");
setusercharsize(2, 1, 4, 1);
/*水平放大2倍,垂直放大4倍*/
setcolor(15);
settextstyle(3, 0, 5);
/*无衬字笔划,放大5倍*/
outtextxy(220, 220, "Very Good");
setusercharsize(4, 1, 1, 1);
settextstyle(3, 0, 0);
outtextxy(180, 320, "Good");
getch();
closegraph();
return 0;
}
- 不白九百
-
楼主您好,你这个分值已经吸引了我
在下不才,也是自己写过一些c语言画图模式下的程序。所以我认为我在这一方面具有一定的权威.
(文本模式下)
我对于您的问题理解的不是很透彻,但是看字面意思来说,您是想当前坐标赋值给变量,我假设变量为(x、y)分别为x轴、y轴坐标变量。则将坐标赋值,为x=getx();y=gety();
(画图模式下)
在这里,我一般是直接对寄存器进行中断取得 鼠标 的值。在对他进行操作。
c语言只有以上2种模式,通过你的提问,我觉得你问的是文本模式下的。如果你觉得我回答不够详细,可以直接加QQ:942690451 询问。
- 左迁
-
一、 算法设计及流程
1. 点
不管什么样的图形归根结底到屏幕,都是由一些颜色不一的象素点组成,为提高图形的显示效率,没有用到系统的画点函数,而采用了640*480*16模式下的直接写屏技术画点,该模式下的直接写屏比320*200*256的直接写屏要复杂的多,后者的视频缓冲区是线性编址的,一个字节对应屏幕上一点的颜色,而前者的视频缓冲区被分成四个位面,屏幕上一点的颜色由每个位面上的一位组成的四位二进制数决定,由于四位二进制数的最大表示范围是16,所以在这种模式下最多可同时显示16种颜色。
在对视频缓冲区的读写时,是一个字节一个字节写的,只需要其中某一位时,就要用到位掩码屏蔽掉其他的位,位掩码就在图形控制寄存器的位屏蔽寄存器里设置。先通过向端口号为0x3ce的索引寄存器写入位屏蔽寄存器的索引号8,然后向端口号为0x3cf的寄存器写入位掩码值。设置好位掩码后,直接向视频缓冲区相应位置写入颜色即为画点函数。
取屏幕上一点颜色其实也就是画点的反操作,画点是将一个四位的二进制颜色值分配到四个位面,而取一点的颜色是将四个位面的颜色组合成一个四位二进制数。
2. 线
线其实就是由点组成的,通过连续的改变点的坐标,也就可以得到一条线。所以画线的函数归根结底也就是如何改变画点的坐标。
画线通常有DDA算法,BRESENHAM算法,这里采用的是BRESENHAM算法。这种算法从根本上讲,是通过横线与竖线的倍数关系来实现的。每次循环画点后x、y中位移大的坐标变化一个单位,而当循环次数是两者倍数关系时,x、y中位移小的坐标变化一个单位。为了使画线函数能在八个方向都能画,将增量为负的都转化正的增量。
画图程序经常要用到moveto、lineto等函数,用于把点移动到某点或从当前点画线到某点,为了模拟这些函数,设置了SX,SY两个全局变量用来作为Moveto()的目的地和Drawlineto()的起始坐标。
3. 矩形及填充矩形
矩形是通过两点确定的对角线来画的,直接连上各点的坐标就可以了。填充矩形是通过一条线一条线画的。这种算法速度比较慢,较好的方法是用Fillscreen()里面用到的方法,那是一个字节一个字节处理的。就因为画矩形并不一定是整字节开始整字节结束的,开始处和结尾处就有了问题。我也把它们单独拿出来处理,但还是没做好,等有时间了再改吧。
4. 圆及弧
画圆采用的是参数方程的方法。为了提高速度,角度的sin、cos值建立了一个表,要用时直接查表。这是因为在用BRESENHAM算法画椭圆时,效果不是很好,画的椭圆不但厚薄不一,而且不闭合。估计是程序哪里出问题了,干脆都用参数方程的方法,又简单,又省事。我这人通常是比较懒的。
弧主要是用来画圆角矩形的,且只能画圆弧。这也是用参数方程来画的,跟画圆不同的只是有了角度的限制。
5. 贝塞尔曲线
贝塞尔曲线其实主要也就是一个公式,跟参数方程画圆是一回事,只是要传入的参数要多一些。在用鼠标控制时,因为有四个点,而用鼠标对多点的采集有点不好做,于是先就初始化了一个四点的数组,用不按键、按左键、按右键分别控制三个点,左右键同时按时,确定下一条曲线。
其实用鼠标画贝塞尔曲线因该把一次、二次、三次的处理函数都写出来,在按下左键时,标记下这点,再一次按下左键时,用画一次贝塞尔曲线的函数画,按下第三次时,用画二次曲线的函数画,按下第四次时才用画三次曲线的函数画。这样就不用为每个点分配一个鼠标按键了。
6. 填充
填充也是采用的种子填充法,不过不是直接从种子开始填色,而是先从种子出发,找到种子沿x最小的边界,然后填上一点,判断这一点的上边一点和下边一点,如果不为边界并且未被填色,则压入栈中,然后x增1后判断是否到达这一行x的最大值(既边界),如不是,则循环处理这一行,直到到达边界,再弹出一个点继续循环处理。由于是一个点一个点处理,所以速度比较慢。
为了对一个图形的不同颜色边界也能填充,填色时没有传入图形的边界颜色,而是采用先取出种子的颜色,在填充下一个点时,把下一点的颜色和种子颜色比较,如果相同则填色,不同则作为边界。
7. 汉字及字符
图形模式下显示汉字其实是一件比较麻烦的事,一般要用到汉字字库,生成的可执行文件也得在有字库的环境下运行。我这里采用了汉字无字库技术,生成的文件不依赖任何其他文件。
无字库技术是通过从字库文件提取需要的中文点阵字模建立一个类似字库的字库数组。它可以大大提高汉字的显示速度。在建立字库数组时,将字模数组进行了排序,所以在显示汉字时
文章来自: 好喜爱学习网() 网址:
- 安徽路人假
-
根据getx和gety函数的定义
int getx(void)
int gety(void)
函数没有参数,直接调用后返回一个int型数据表示坐标的像素值
windef.h有下列结构定义x,y为坐标的点:
typedef struct tagPOINT {
LONG x;
LONG y;
} POINT;
所以,可以这样得到点a的坐标
POINT a;
a.x=getx();
a.y=gety();
个人观点,参考一下.
- ardim
-
getx(),gety()的返回值是int型,直接用int型变量接值就可以的。
例如:
if(getx()==500){
moveto(120,gety());
moverel(20,0);
white();
}
希望能帮上你。。
- 阳光下的日耳曼尼亚
-
如何用c语言进行画图呢?
首先,我们要做的就是初始化图形模式驱动程序。
例如用如下程序画一个饼分图:
#include<stdio.h>
#include<graphics.h>
main()
{ int gdriver,gmode;
gdriver=DETECT;
initgraph(&gdriver,&gmode,"");
setcolor(BLUE);
setfillstyle(1,RED);
pieslice(250,250,0,45,200);
setfillstyle(1,GREEN);
pieslice(250,250,45,90,200);
setfillstyle(1,BLUE);
pieslice(250,250,90,135,200);
setfillstyle(1,CYAN);
pieslice(250,250,135,180,200);
setfillstyle(1,BROWN);
pieslice(250,250,180,225,200);
setfillstyle(1,LIGHTGRAY);
pieslice(250,250,225,270,200);
setfillstyle(1,YELLOW);
pieslice(250,250,270,315,200);
setfillstyle(1,MAGENTA);
pieslice(250,250,315,360,200);
getch();
closegraph();
}
这三行代码部分就是初始化图形模式,加载图形模式驱动程序。
int gdriver,gmode;
gdriver=DETECT;
initgraph(&gdriver,&gmode,"");