本文目錄一覽:
- 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分,重複判斷。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/151412.html