本文目录一览:
1、利用编码的方法进行二维裁剪时有哪些判断规则
2、求一个多边形的裁剪算法
3、学好计算机图形学需要学习那些相关的知识?
4、如果要用Liang-Barskey算法实现裁剪,如何修改程序?
5、裁剪算法
利用编码的方法进行二维裁剪时有哪些判断规则
要利用编码制作和裁剪出不规则的图形,具体步骤如下:
第一、启动ps软件,进入ps的界面后,将特定的图片拖进去;
第二。打开图片之后,双击该背景图层右边的锁头图标,在“新建图层”窗口上点击“确定”;
第三、图片解锁之后,使用钢笔工具在图片上方画出一个不规则的图形;
第四、接着在左侧工具栏里点击使用“路径选择工具”;
第五、接着,在图片上右击鼠标,选择“创建矢量蒙版”;
第六然后就可以看到该图片被裁剪成不规则的图形了。
求一个多边形的裁剪算法
#include graphics.h
#include dos.h
union REGS i,o;
int xl=100,xr=540,yb=400,yt=200; /*方框边界*/
void init()
{
int driver=DETECT,gm;
initgraph(driver,gm,"");
printf("Instruction:\n");
printf("1.Press left mouse button to set the vertex;\n");
printf("2.Press right button to end drawing;\n");
/*printf("3.Press both button to clip.");*/
outtextxy(450, 440, "Edit by lcfhy!");
setwritemode(2);
line(0,70,639,70);
setcolor(YELLOW);
rectangle(xl,yt,xr,yb);
i.x.ax=0;
int86(0x33,i,o);
if(o.x.ax==0)
{
printf("Mouse is not available...");
getch();
exit();
}
i.x.ax=1;
int86(0x33,i,o);
/*设置光标可用范围(Y方向)*/
i.x.ax=8;
i.x.cx=71;
i.x.dx=479;
int86(0x33,i,o);
}
int mousestatus(int *x,int *y)
{
i.x.ax=3; /*查询鼠标状态功能号为03H*/
int86(0x33,i,o);
*x=o.x.cx; /*鼠标横坐标 */
*y=o.x.dx; /*鼠标纵坐标 */
return o.x.bx; /*返回按键情况:0-NONE,1-LEFT,2-RIGHT,3-BOTH; */
}
void endpro() /*结束裁剪*/
{
char s[50]="Press any key to exit...";
setcolor(WHITE);
outtextxy(200,120,s); /*此处有可能出现乱码,正常现象,出现概率随机*/
getch();
closegraph();
exit();
}
void code(int x,int y,int *c )
{/*c为5元数组*/
int i;
for(i=1;i=4;i++) c[i]=0;
if(xxl) c[4]=1;
if(xxr) c[3]=1;
if(yyt) c[1]=1;
if(yyb) c[2]=1;
}
void cut(int x1,int y1,int x2,int y2)/*把不需要的线置为黑色,不可见*/
{
setcolor(BLACK);
setlinestyle(0, 0, 3); /*设置三点宽实线*/
line(x1,y1,x2,y2);
}
int logic_ride(int *c1,int *c2)/*判断逻辑乘是否为0,是则返回0,否则返回1*/
{
int i;
for(i=1;i=4;i++)
{
if(c1[i]*c2[i]==1) return 1;
}
return 0;
}
int logic2_ride(int *c)/*在内部则返回1,否则返回0*/
{
int m;
for(m=0;m=4;m++)
if(c[m]==1) return 0;
return 1;
}
void clip(int *x,int *y,int k)
/*裁剪函数,如果某个线段不在可视区,我们将其颜色置为黑色,否则不作颜色改变*/
{
/*int i;
for(i=1;i=k;i++)
printf("%d,%d\n",x[i],y[i]);*/ /*此段代码检测模板存入的数据没错*/
int c1[5],c2[5],c[5],p,x0,y0,ultra_x,ultra_y,t;/*x0,y0储存临时交点*/
x[k+1]=x[1];y[k+1]=y[1];
for(p=1;p=k;p++)
{
code(x[p],y[p],c1);
code(x[p+1],y[p+1],c2);
if(logic_ride(c1,c2)) cut(x[p],y[p],x[p+1],y[p+1]);/*完全不可见,则完全剪除*/
else if(logic2_ride(c1)==1logic2_ride(c2)==1) ;/*排除一种情况*/
else /*不完全在里面,也不完全在外面*/
{
if(logic2_ride(c1)!=1)/*起点在外面*/
{
t=1;
while(t)
{
if(logic_ride(c,c2)) {cut(x[p],y[p],x[p+1],y[p+1]);break;}/*完全不可见,则完全剪除*/
else
{
if(c1[4]==1)/*判断四边的情况*/
{
x0=xl;
y0=y[p]+(y[p+1]-y[p])*(xl-x[p])/(x[p+1]-x[p]);
}
else if(c1[3]==1)
{
x0=xr;
y0=y[p]+(y[p+1]-y[p])*(xr-x[p])/(x[p+1]-x[p]);
}
else if(c1[1]==1)
{
y0=yt;
x0=x[p]+(x[p+1]-x[p])*(yt-y[p])/(y[p+1]-y[p]);
}
else if(c1[2]==1)
{
y0=yb;
x0=x[p]+(x[p+1]-x[p])*(yb-y[p])/(y[p+1]-y[p]);
}
cut(x[p],y[p],x0,y0);
x[p]=x0;y[p]=y0; code(x0,y0,c);
if(logic2_ride(c)==1) t=0;
}
}
}
if(logic2_ride(c2)!=1)/*终点在外面*/
{
t=1;
if(c2[4]==1)/*判断四边的情况*/
{
x0=xl;
y0=y[p]+(y[p+1]-y[p])*(xl-x[p])/(x[p+1]-x[p]);
}
else if(c2[3]==1)
{
x0=xr;
y0=y[p]+(y[p+1]-y[p])*(xr-x[p])/(x[p+1]-x[p]);
}
else if(c2[1]==1)
{
y0=yt; x0=x[p]+(x[p+1]-x[p])*(yt-y[p])/(y[p+1]-y[p]);
}
else if(c2[2]==1)
{
y0=yb; x0=x[p]+(x[p+1]-x[p])*(yb-y[p])/(y[p+1]-y[p]);
}
cut(x0,y0,x[p+1],y[p+1]);
code(x0,y0,c);
if(logic2_ride(c)==0)
{
if(c[4]==1)/*判断四边的情况*/
{
ultra_x=xl;
ultra_y=y0+(y[p+1]-y0)*(xl-x0)/(x[p+1]-x0);
}
else if(c[3]==1)
{
ultra_x=xr;
ultra_y=y0+(y[p+1]-0)*(xr-0)/(x[p+1]-x0);
}
else if(c[1]==1)
{
ultra_y=yt;
ultra_x=x0+(x[p+1]-x0)*(yt-y0)/(y[p+1]-y0);
}
else if(c[2]==1)
{
ultra_y=yb;
ultra_x=x0+(x[p+1]-x0)*(yb-y0)/(y[p+1]-y0);
}
cut(x0,y0,ultra_x,ultra_y);
}
}
}
}
endpro();
}
void draw(int *x,int *y)
{
int k=0,lx,ly,color,i;
int tempx,tempy;
while(1){
/*描点并存储顶点*/
if(mousestatus(tempx,tempy)==1)
{
if(x[k]!=tempx||y[k]!=tempy) k++; /*这一步有关键,想想看为什么?*/
x[k]=tempx;
y[k]=tempy;
setcolor(WHITE);
circle(tempx,tempy,1);
if (k!=1)
{
setcolor(WHITE);
line(x[k-1],y[k-1],x[k],y[k]);
}
}
lx=tempx,ly=tempy;
if(mousestatus(tempx,tempy)==2) /*如果按下右键*/
{
line(x[1],y[1],x[k],y[k]);
clip(x,y,k);
}
putpixel(tempx,tempy,WHITE);/* trace the mouse,*/
putpixel(lx,ly,BLACK);
}
}
void main()
{
int x[100],y[100];
init();
draw(x,y);
}
来源:
学好计算机图形学需要学习那些相关的知识?
学好计算机图形学主要学好线形代数和高等数学这二门课。
主要的还是一些图形学的算法研究,当然c语言也是必不可少的。
计算机图形学介绍了很多基础算法,这些算法虽然很基础,但是很经典,关键是学到一种思考问题的方式。
如果要用Liang-Barskey算法实现裁剪,如何修改程序?
给你一个完整的Liang-Barskey直线段裁剪算法的C语言程序
#include "graphics.h"
#include "stdio.h"
#define LINE_COLOR 10
#define WINDOW_COLOR 4
int ClipT(float p,float q,float *u1,float *u2)
{
int flag=1;
float r;
if(p0.0)
{
r=q/p;
if(r*u2) flag=0;
else if(r*u1)
*u1=r;
}
else if(p0.0)
{
r=q/p;
if(r*u1) flag=0;
else if(r*u2)
*u2=r;
}
else if(q0.0) flag=0;
return flag;
}
void Liang_Barsky(int xL,int yT,int xR,int yB,int x1,int y1,int x2,int y2)
{
float dx,dy,u1,u2;
u1=0.0;u2=1.0;
dx=x2-x1;
if(ClipT(-dx,x1-xL,u1,u2))
if(ClipT(dx,xR-x1,u1,u2))
{
dy=y2-y1;
if(ClipT(-dy,y1-yT,u1,u2))
if(ClipT(dy,yB-y1,u1,u2))
{
if(u21.0)
{
x2=x1+u2*dx;
y2=y1+u2*dy;
}
if(u10.0)
{
x1=x1+u1*dx;
y1=y1+u1*dy;
}
line(x1,y1,x2,y2);
}
}
}
void main(void)
{
int gdriver=DETECT,gmode;
int XL,XR,YB,YT;
int x0,y0,x1,y1;
do
{
registerbgidriver(EGAVGA_driver);
initgraph(gdriver,gmode,"");
cleardevice();
printf("\nLiang_Barsky\n");
printf("\n");
printf("Please input the line node(x0,y0,x1,y1):\n");
scanf("%d,%d,%d,%d",x0,y0,x1,y1);
printf("\n");
cleardevice();
setcolor(LINE_COLOR);
line(x0,y0,x1,y1);
getch();
printf("\nLiang_Barsky\n");
printf("\n");
printf("Please input the rectangle point(XL,YT,XR,YB):\n");
scanf("%d,%d,%d,%d",XL,YT,XR,YB);
printf("\n");
cleardevice();
line(x0,y0,x1,y1);
setcolor(WINDOW_COLOR);
rectangle(XL,YT,XR,YB);
getch();
cleardevice();
rectangle(XL,YT,XR,YB);
setcolor(LINE_COLOR);
Liang_Barsky(XL,YT,XR,YB,x0,y0,x1,y1);
getch();
printf("\n\n Continue?(y|n?)");
getchar();
}while(getchar()=='y'||getchar()=='Y');
printf("\n");
printf("press any key to end!");
getch();
closegraph();
}
裁剪算法
OpenGL中经常用到裁剪,这里记录下裁剪的一些基本算法和概念。
裁剪就是去掉窗口外不可见的部分,保留在窗口中的内同。是OpenGL的管线中必不可少的一步,裁剪算法的执行效率会直接影响整个程序的效率。
裁剪可以按照线或面进行,一般使用规则裁剪框进行裁剪,也有用不规则图形进行裁剪,常见的是使用矩形框进行裁剪。
裁剪过程的难度随裁剪区域的复杂度和被裁剪物体的形状复杂程度增加。
这里用矩形裁剪框解释常用的裁剪算法。
点的裁剪相对简单,已知矩形裁剪框的两个对角线顶点坐标A(x1,y1)、B(x2,y2),判断点P(x,y)是不是在A、B坐标范围内即可。
若:
min(x1,x2) = x = max(x1,x2);
min(y1,y2) = y = max(y1,y2);
则P点在裁剪框中,否则在裁剪框外。
这里说的直线,都是线段。线的裁剪算法有很多,常见的有:cohen-sutherland算法,中点分割裁剪算法,Liang-Barsky算法,beck算法等。
这个算法的主要思想是,用四位掩码做运算判断线是否在裁剪框内,如果在或全部在裁剪框外,结束。如果部分在窗口中,用线和裁剪框的交点对线段进行分割,然后分割后的继续重复判断。步骤如下:
设要裁剪的线段是P0P1。从P0端点出发,找出离P0点最近的可见点。从P1端点出发,找出离P1点最近的可见点。这两个可见点的连线就是裁剪框中的要保留的部分。
找可见点的方法用二分法,先取线段的中点M点,判断P1M是否可见,如果不能定为不可见,用P1M线段再2分,重复判断。