|
|
计算机图形学上机作业:
1. 输入三角形的三个顶点坐标,在屏幕上画出三角形。 画线子程序可以采用中点画线或Bresenham画线算法。
2. 输入圆心、半径 ,在屏幕上利用Bresenham画园算法画出该园。
注:输入可以在屏幕上直接确定 点,或用键盘输入坐标值。画线和画园的过程要加延时,以便观察是在画点。
3 . 对屏幕上所画图形进行拾取。可以用鼠标或键盘控制拾取。
4. 对拾取的图形进行比例、平移和旋转变换。比例系数可以由键盘输入,平移可以 由键盘或鼠标控制。旋转角度可以由键盘输入或鼠标控制。
5. 对比例 、平移和旋转后的图形用任意非边界色进行填充。
我刚刚做完了前两个,可是有些问题,初学xlib,好多地方还不了解只是照猫画虎。我把第2个Bresenham画园算法代码贴到下边:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
#define DUMP_ERR printf
static void draw(Display *display,Window win,GC gc,int width,int height,int x0,int y0,double r);
int main()
{
Display *display;
int screennum;
int width;
int height;
Atom protocols;
Window win;
GC gc;
display = XOpenDisplay(NULL);
if( !display )
{
DUMP_ERR("call XOpenDisplay(%s) fail\n",XDisplayName(NULL));
return 1;
}
// get default screen
screennum = DefaultScreen(display);
width = DisplayWidth(display,screennum)/2;
height = DisplayHeight(display,screennum)/2;
// create window
win = XCreateSimpleWindow(display,RootWindow(display,screennum),0,0,width,height,3,BlackPixel(display,screennum),WhitePixel(display,screennum));
//增加这个代码是捕获程序退出事件
protocols = XInternAtom(display, "WM_DELETE_WINDOW", True);
XSetWMProtocols(display, win, &protocols, 1);
// select event
XSelectInput(display,win,ExposureMask|ButtonPressMask|ButtonReleaseMask|StructureNotifyMask);
// create gc
{
unsigned long valuemask = 0;
XGCValues values;
gc = XCreateGC(display,win,valuemask,&values);
}
// show window
XMapWindow(display,win);
int x0,y0;
double r;
/*** //注意这里的注释^_^
printf("\nthe center of the circle(x,y):");
scanf("%d%d",&x0,&y0);
printf("\nthe radius of the circle(r):");
scanf("%f",&r);
***/
// event loop
while(1)
{
XEvent event;
XNextEvent(display,&event);
switch(event.type)
{
case Expose: // expose window
if( event.xexpose.count != 0) break;
/* //再注意这里的注释^_^
printf("\nthe center of the circle(x,y):");
scanf("%d%d",&x0,&y0);
printf("\nthe radius of the circle(r):");
scanf("%f",&r);
*/
draw(display,win,gc,width,height,200,200,100);
break;
case ConfigureNotify: // when the window’s size change
width = event.xconfigure.width;
height = event.xconfigure.height;
draw(display,win,gc,width,height,200,200,100);
break;
case ClientMessage :
if(event.xclient.data.l[0] == protocols)
{
DUMP_ERR("recv destroy notify\n");
XFreeGC(display,gc);
XDestroyWindow(display, win);
XCloseDisplay(display);
return 0;
}
default: break;
}//switch
}//while
return 0;
}//main
// 使用changeGC修改属性的代码 只有valuemask被设置的属性才会根据XCGValues里面的值进行修改
static void set_gc_values(Display *display,GC gc)
{
XGCValues values;
values.line_width = 2;
values.line_style = LineSolid;
values.cap_style = CapRound;
values.join_style = JoinRound;
XChangeGC(display,gc,GCLineWidth|GCLineStyle,//|GCCapStyle|GCFillStyle,
&values);
}
int Bres_Circle(Display *display,Window win,GC gc,int width,int height,int x0,int y0,double r);
// 画画的代码
static void draw(Display *display,Window win,GC gc,int width,int height,int x0,int y0,double r)
{
Bres_Circle(display,win,gc,width,height,x0,y0,r);
set_gc_values(display,gc);
}
void iSwap (int *a, int *b)
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
int CirPot(Display *display,Window win,GC gc,int width,int height,int x0,int y0,int x,int y);
int Bres_Circle(Display *display,Window win,GC gc,int width,int height,int x0,int y0,double r)
{
int x,y,d;
x=0;
y=(int)r;
d=(int)(3-2*r);
while(x<y)
{
CirPot(display,win,gc,width,height,x0,y0,x,y);
if(d<0)
d+=4*x+6;
else
{
d+=4*(x-y)+10;
y--;
}
x++;
}
if(x==y)
CirPot(display,win,gc,width,height,x0,y0,x,y);
return 0;
}
int CirPot(Display *display,Window win,GC gc,int width,int height,int x0,int y0,int x,int y)
{
// oldcolor=setcolor(color);
XDrawPoint(display,win,gc,(x0+x),(y0+y));
XDrawPoint(display,win,gc,(x0+y),(y0+x));
XDrawPoint(display,win,gc,(x0+y),(y0-x));
XDrawPoint(display,win,gc,(x0+x),(y0-y));
XDrawPoint(display,win,gc,(x0-x),(y0-y));
XDrawPoint(display,win,gc,(x0-y),(y0-x));
XDrawPoint(display,win,gc,(x0-y),(y0+x));
XDrawPoint(display,win,gc,(x0-x),(y0+y));
//tcolor(oldcolor);
return 0;
}
[adamzyg@adamzyg 图形]$ gcc -L/usr/X11R6/lib -lX11 hello.c -o hello -Wall
[adamzyg@adamzyg 图形]$ gcc -L/usr/X11R6/lib -lX11 hello.c -o hello -Wall
hello.c: 在函数 ‘main’ 中:
hello.c:55: 警告:未使用的变量 ‘r’
hello.c:54: 警告:未使用的变量 ‘y0’
hello.c:54: 警告:未使用的变量 ‘x0’
[adamzyg@adamzyg 图形]$ ls
Bres_Line.c hello hello1.c hello.c test test.c wxwindows.cpp
[adamzyg@adamzyg 图形]$./hello
如上的代码,我画圆的数据(圆心,半径)是通过常数传递的,如:
draw(display,win,gc,width,height,200,200,100);
本来应该从终端传入,可是就像我注释的部分一样在两个地方输入数据都会导致产生的窗口就是不画图,只有重复的输入数据。不知道怎么办才好。希望各位GGJJ们帮帮我,真的太笨了。^_^
上传的“画圆.tar.gz”里包括“hello.c”(源代码)和“hello”(可执行)两个文件。
[adamzyg@adamzyg 图形]$ gcc --version
gcc (GCC) 4.1.0 20060304 (Red Hat 4.1.0-3)
Copyright (C) 2006 Free Software Foundation, Inc. |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|