计算机科学系实验报告
课程名称计算机图形学班级
实验名称TC绘制基本图形教导教师
姓名学号日期
一、实验目的
1.掌握直线DDA算法,直线Bresenham算法,圆Bresenham算法;
2.掌握种子填充算法,汉字显示算法。
二、实验设备与环境
TC2.0,Windows XP
三、实验内容、程序清单及运行结果
实验步骤:
#include <stdlib.h>
#include "stdafx.h"
#include "graphics.h"
#include <conio.h>
#include "windows.h"
#include <math.h>
#define ROW 1 /*纵坐标放大倍数*/
#define COL 1 /*横坐标放大倍数*/
//DDA直线
void dda_line(int xa,int ya,int xb,int yb,int c)
{
float delta_x,delta_y,x,y;
int dx,dy,steps,k;
dx=xb-xa;
dy=yb-ya;
if(abs(dx)>abs(dy))
steps=abs(dx);
else steps=abs(dy);
delta_x=(float)dx/(float)steps;
delta_y=(float)dy/(float)steps;
x=xa;
y=ya;
putpixel(x,y,c);
for(k=1;k<=steps;k++)
{x+=delta_x;
y+=delta_y;
putpixel(x,y,c);
}
}
//Bresenham直线
void lineBres(int x0, int y0, int xEnd, int yEnd,int c)
{
int dx = fabs (xEnd -x0), dy = fabs (yEnd-y0);
int p =2* dy-dx;
int twoDy = 2*dy, twoDyMinusDx = 2* (dy - dx);
int x,y;
if (x0>xEnd)
{
x=xEnd;
y=yEnd;
xEnd=x0;
}
else{
x=x0;
y=y0;
}
putpixel (x,y,c);
while (x<xEnd)
{
x++;
if(p<0)
p+=twoDy;
else{
y++;
p+=twoDyMinusDx;
}
putpixel (x,y,c);
}
}
//Bresenham圆
plot_circle_points(int xc,int yc,int x,int y,int c) {
putpixel(xc+x,yc+y,c);
putpixel(xc-x,yc+y,c);
putpixel(xc+x,yc-y,c);
putpixel(xc-x,yc-y,c);
putpixel(xc+y,yc+x,c);
putpixel(xc-y,yc+x,c);
putpixel(xc+y,yc-x,c);
putpixel(xc-y,yc-x,c);
}
circle(int xc,int yc,int radius,int c)
{
int x,y,p;
x=0;
y=radius;
p=3-2*radius;
while(x<y){
plot_circle_points(xc,yc,x,y,c);
if(p<0) p=p+4*x+6;
else{
p=p+4*(x-y)+10;
y-=1;
}
x+=1;
}
if (x==y)
plot_circle_points(xc,yc,x,y,c);
}
//种子填充
void seed_filling(int x,int y,int fill_color,int boundary_color) {
int c;
c=getpixel(x,y);
if((c!=boundary_color)&&(c!=fill_color))
{putpixel(x,y,fill_color);
seed_filling(x+1,y,fill_color,boundary_color);
seed_filling(x-1,y,fill_color,boundary_color);
seed_filling(x,y+1,fill_color,boundary_color);
seed_filling(x,y-1,fill_color,boundary_color);
}
}
//汉字
void hanzi(char *s)
{
int x,y;
FILE *fp;
char buffer[32]; /*buffer用来存储一个汉字*/
register m,n,i,j,k;
unsigned char qh,wh;
unsigned long offset;
if ((fp=fopen("hzk16","rb"))==NULL)
/*打开汉字库,该字库可以在ucdos中找到*/
{printf("Can't open haz16,Please add it");
getch();
exit(0);
}
x=150; y=250; /*显示位置设置*/
while(*s)
{
qh=*(s)-0xa0; /*汉字区位码*/
wh=*(s+1)-0xa0;
offset=(94*(qh-1)+(wh-1))*32L; /*计算该汉字在字库中偏移量*/
fseek(fp,offset,SEEK_SET);
fread(buffer,32,1,fp); /*取出汉字32字节的点阵字模存入buffer中(一个汉字)*/
for (i=0;i<16;i++) /*将32位字节的点阵按位在屏幕上打印出来(1:打印,0:不打印),显示汉字*/
for(n=0;n<ROW;n++)
for(j=0;j<2;j++)
for(k=0;k<8;k++)
for(m=0;m<COL;m++)
if (((buffer[i*2+j]>>(7-k))&0x1)!=NULL)
putpixel(x+8*j*COL+k*COL+m,y+i*ROW+n,GREEN);
s+=2; /*因为一个汉字内码占用两个字节,所以s必须加2*/
x+=16;
}
fclose(fp);
}
void main()
{
int gd=DETECT,gm; /*图形屏幕初始化*/
//char *s="惠州学院计算机科学系汉字显示程序ABCD123";
initgraph(&gd,&gm,"");
//hanzi(100);
//DDA直线
dda_line(150,200,550,200,RED);
//Bresenham直线
lineBres(150,300,550,300,YELLOW);
//Bresenham圆
circle(350,120,70,YELLOW);
//种子填充
seed_filling(350,120,YELLOW,RED);
//汉字
char *s="班级:网络2班李文森1214080613213"; hanzi(s);
//Bresenham圆
circle(350,380,70,GREEN);
//种子填充
seed_filling(350,380,GREEN,RED);
getch();
closegraph();
}
四、实验结论、实验体会
今天的实验是完成一个简单的直线、图形和汉字的组合输出。
这个实验看起来不难,但是也有一些需要一些注意的东西,如汉字输入时需要注意全角字符的转换,一些函数的调用时,需要注意先声明再调用。
通过本次实验,不仅加深了对C语言基础知识的了解,同时更好的复习了图形学里面的重点知识及其实现原理,还明白基础知识的重要性。
因为拥有良好的基础,很容易就能发现错在哪里,知道哪里缺少什么,然后进行正确修改。
总之,其中让我明白了多实践,基础知识不可少。