http://www.cnblogs.com/baichenjia/p/3694727.html

一、Cohen-Sutherland剪裁算法

1.基本思想

对于每条线段P1P2分为三种情况处理:

(1)若P1P2完全在窗口内,则显示该线段P1P2。

(2)若P1P2明显在窗口外,则丢弃该线段。

(3)若线段不满足(1)或(2)的条件,则在交点处把线段分为两段。其中一段完全在窗口外,可弃之。然后对另一段重复上述处理。

为快速判断,采用如下编码方法:

将窗口边线两边沿长,得到九个区域,每一个区域都用一个四位二进制数标识,直线的端点都按其所处区域赋予相应的区域码,用来标识出端点相对于裁剪矩形边界的位置

  • 任何位赋值为1,代表端点落在相应的位置上,否则该位为0。
  • 若端点在剪取矩形内,区域码为0000。

2.算法流程

  • 若P1P2完全在窗口内code1=0,且code2=0,则“取”
  • 若P1P2明显在窗口外code1&code2≠0,则“弃”
  • 在交点处把线段分为两段。其中一段完全在窗口外,可弃之。然后对另一段重复上述处理。

3.交点求取

计算线段P1(x1,y1)--P2(x2,y2)与窗口边界的交点

if ( LEFT &code !=0 )

{ x=XL; y=y1+(y2-y1)*(XL-x1)/(x2-x1);}

else if ( RIGHT & code !=0 )

{ x=XR; y=y1+(y2-y1)*(XR-x1)/(x2-x1);}

else if ( BOTTOM & code !=0 )

{ y=YB; x=x1+(x2-x1)*(YB-y1)/(y2-y1);}

else if ( TOP & code !=0 )

{ y=YT; x=x1+(x2-x1)*(YT-y1)/(y2-y1);}

二、Sutherland-Hodgman剪裁算法

1.基本思想

分割处理策略:将多边形关于矩形窗口的裁剪分解为多边形关于窗口四边所在直线的裁剪。

流水线过程(左上右下):前边的结果是后边的输入。

  • 一次用窗口的一条边裁剪多边形。
  • 考虑窗口的一条边以及延长线构成的裁剪线,把平面分成两个部分:可见一侧;不可见一侧
  • 多边形的各条边的两端点S、P。它们与裁剪线的位置关系只有四种
  • 情况(1)仅输出顶点P;
  • 情况(2)输出0个顶点;
  • 情况(3)输出线段SP与裁剪线的交点I;
  • 情况(4)输出线段SP与裁剪线的交点I和终点P

三、 程序流程图

一、Cohen-Sutherland算法

二、Sutherland-Hodgman算法

四、源程序

一、Cohen-Sutherland

  1 #include "easyx.h"
  2 #include "math.h"
  3 #include "windows.h"
  4 #include "stdio.h"
  5 #include "stdlib.h"
  6 #include "conio.h"
  7 #include "graphics.h"
  8
  9 #define left 1
 10 #define right 2
 11 #define bottom 8
 12 #define top 4
 13
 14 int edge_x1,edge_x2,edge_y1,edge_y2;  //全局变量,代表剪裁的边界
 15
 16 //画线算法
 17 void dda(int x1,int y1,int x2,int y2,int color)
 18 {
 19     int steps;
 20     double xin,yin,dx,dy,x,y;
 21     dx = x2 - x1;
 22     dy = y2 - y1;
 23     if(fabs(dx) > fabs(dy))
 24         steps = fabs(dx);
 25     else
 26         steps = fabs(dy);
 27     xin = (double)(dx/steps);
 28     yin = (double)(dy/steps);  //possible loss of data
 29     x = x1;
 30     y = y1;
 31     putpixel(x,y,color);
 32     for(int i = 0;i <= steps;i ++)
 33     {
 34         x = x + xin;
 35         y = y + yin;
 36         putpixel(x,y,color);
 37     }
 38 }
 39
 40
 41 //对输入的点进行编码
 42 int coding(int x,int y)
 43 {
 44     int code;
 45     if(y <= edge_y2 && y >= edge_y1)
 46     {
 47         if(x > edge_x2)
 48             code = 2;              //中右方
 49         else if(x < edge_x1)
 50             code = 1;              //中左方
 51         else
 52             code = 0;              //中心
 53     }
 54
 55     else if(y > edge_y2)
 56     {
 57         if(x > edge_x2)
 58             code = 6;            //右下方
 59         else if(x < edge_x1)
 60             code = 5;              //左下方
 61         else
 62             code = 4;           //中下方
 63     }
 64     else
 65     {
 66         if(x > edge_x2)
 67             code = 10;            //右上方
 68         else if(x < edge_x1)
 69             code = 9;           //左上方
 70         else
 71             code = 8;          //中上方
 72     }
 73
 74     return code;
 75 }
 76
 77
 78
 79
 80 //剪裁算法
 81 int cutline(int x1,int y1,int x2,int y2)
 82 {
 83     int visible = 0,done = 1;
 84     int c;
 85     int c1,c2;
 86     int x,y;  //表示交点
 87     c1 = coding(x1,y1);
 88     c2 = coding(x2,y2);   //将顶点进行编码
 89     do
 90     {
 91         if(c1 == 0 && c2 == 0)  //完全可见
 92         {
 93             visible = 1;
 94             done = 0;
 95         }
 96         else if((c1 & c2) != 0)   //完全不可见
 97         {
 98             done = 0;
 99         }
100         else
101         {
102             ////
103             if(c1 != 0)
104                 c = c1;
105             else
106                 c = c2;
107             ////
108             if((left & c) != 0)
109             {
110                 x = edge_x1;
111                 y = y1 + (y2 - y1)*(edge_x1 - x1)/(x2-x1);
112             }
113             else if((right & c) != 0)
114             {
115                 x = edge_x2;
116                 y = y1 + (y2 - y1)*(edge_x2 - x1)/(x2-x1);
117             }
118             else if((bottom &c )!= 0)
119             {
120                 y = edge_y1;
121                 x = x1 + (x2 - x1)*(edge_y1 - y1)/(y2-y1);
122             }
123             else if((top & c )!= 0)
124             {
125                 y = edge_y2;
126                 x = x1 + (x2 - x1)*(edge_y2 - y1)/(y2-y1);
127             }
128             else
129             {}
130             //
131             if(c = c1)
132             {
133                 x1 = x;
134                 y1 = y;
135                 c1 = coding(x1,y1);
136             }
137             else
138             {
139                 x2 = x;
140                 y2 = y;
141                 c2 = coding(x2,y2);
142             }
143             ///
144         }//else
145
146     }while(done);  //while
147
148     dda(x1,y1,x2,y2,RGB(0,0,255));         //画线
149
150     return 0;
151 }
152
153
154 int main()
155 {
156     //硬件测试,将gd装入图形驱动器,gm置入最大图形模式。
157     int gd=DETECT,gm;
158     int x1,y1,x2,y2;
159     //输入X的边界
160     printf("请输入剪裁区域的横坐标边界\n");
161     printf("X1 = ");
162     scanf("%d",&edge_x1);
163     printf("\n");
164     printf("X2 = ");
165     scanf("%d",&edge_x2);
166     printf("\n\n");
167
168     //输入Y的边界
169     printf("请输入剪裁区域的纵坐标边界\n");
170     printf("Y1 = ");
171     scanf("%d",&edge_y1);
172     printf("\n");
173     printf("Y2 = ");
174     scanf("%d",&edge_y2);
175     printf("\n\n");
176
177     //输入直线端点
178     printf("请输入直线两个顶点的坐标");
179     scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
180
181     //图形初始化
182     initgraph(&gd,&gm,"c:\\tc");
183     //设置兰背景。
184     setbkcolor(WHITE);
185     cleardevice();
186
187     cutline(x1,y1,x2,y2);  //进行剪裁
188
189     getch();
190     closegraph();
191     return 0;
192 }

二.Sutherland-Hodgman

  1 #include "easyx.h"
  2 #include "math.h"
  3 #include "windows.h"
  4 #include "stdio.h"
  5 #include "stdlib.h"
  6 #include "conio.h"
  7 #include "graphics.h"
  8
  9 int edge_x1,edge_x2,edge_y1,edge_y2;  //全局变量,代表剪裁的边界
 10
 11 //画线算法
 12 void dda(int x1,int y1,int x2,int y2,int color)
 13 {
 14     int steps;
 15     double xin,yin,dx,dy,x,y;
 16     dx = x2 - x1;
 17     dy = y2 - y1;
 18     if(fabs(dx) > fabs(dy))
 19         steps = fabs(dx);
 20     else
 21         steps = fabs(dy);
 22     xin = (double)(dx/steps);
 23     yin = (double)(dy/steps);  //possible loss of data
 24     x = x1;
 25     y = y1;
 26     putpixel(int(x),int(y),color);
 27     for(int i = 0;i <= steps;i ++)
 28     {
 29         x = x + xin;
 30         y = y + yin;
 31         putpixel(int(x),int(y),color);
 32     }
 33 }
 34
 35 //剪裁算法
 36 int Surtherland_Hondgman(double p[][2],int n,int bound)
 37 {
 38     int sumpoint = 0;   //新的顶点个数
 39     double new_p[100][2];    //存放新的顶点序列
 40     double sx = p[n-1][0],sy = p[n-1][1];   //将定点序列的最后一个顶点赋值给s
 41     int flag;
 42     if(sx > bound)   //在内侧
 43         flag = 0;
 44     else
 45         flag = 1;
 46
 47     for(int i = 0;i < n;i++)
 48     {
 49         if(p[i][0] > bound)  //在内侧
 50         {
 51             if(flag != 0)
 52             {
 53                 flag = 0;
 54                 //求交点并放入新的多边形顶点序列中;
 55                 new_p[sumpoint][0] = bound;   //横坐标
 56                 new_p[sumpoint][1] = sy + (((p[i][1] - sy)/(p[i][0] - sx)) * (bound - sx));  //纵坐标
 57                 sumpoint++;
 58             }
 59             new_p[sumpoint][0] = p[i][0];
 60             new_p[sumpoint][1] = p[i][1];   //将当前顶点放入新的多边形顶点序列new_p中
 61             sumpoint++;
 62         }
 63         else
 64         {
 65             if(flag == 0)
 66             {
 67                 flag = 1;
 68                 new_p[sumpoint][0] = bound;   //横坐标
 69                 new_p[sumpoint][1] = sy + (((p[i][1] - sy)/(p[i][0] - sx)) * (bound - sx));  //纵坐标
 70                 sumpoint++;
 71             }
 72         }
 73         sx = p[i][0];
 74         sy = p[i][1];
 75     }
 76     for(int i = 0;i < sumpoint-1;i++)
 77         dda(new_p[i][0],new_p[i][1],new_p[i+1][0],new_p[i+1][1],RGB(255,0,0));
 78     dda(new_p[0][0],new_p[0][1],new_p[sumpoint-1][0],new_p[sumpoint-1][1],RGB(255,0,0));
 79
 80     return 0;
 81 }
 82
 83
 84 int main()
 85 {
 86     //硬件测试,将gd装入图形驱动器,gm置入最大图形模式。
 87     int gd=DETECT,gm;
 88     int n;
 89     double p[10][2];
 90     //输入X的边界
 91     printf("请输入剪裁区域的左侧边界的横坐标\n");
 92     printf("X1 = ");
 93         scanf("%d",&edge_x1);
 94
 95     //dda(edge_x1,1,edge_x1,500,BLUE);
 96
 97     //输入直线端点
 98     printf("请输入待剪裁多边形的边数:");
 99     scanf("%d",&n);
100     printf("请输入待剪裁多边形的顶点序列:\n");
101     for(int i = 0;i < n;i ++)
102         scanf("%lf%lf",&p[i][0],&p[i][1]);
103
104
105     //图形初始化
106     initgraph(&gd,&gm,"c:\\tc");
107     //设置兰背景。
108     setbkcolor(WHITE);
109     cleardevice();
110
111     Surtherland_Hondgman(p,n,edge_x1);  //先对左边界进行裁剪
112
113     getch();
114     closegraph();
115     return 0;
116 }

二维图形的剪裁_Sutherland-Hodgeman_Cohen—Sutherland相关推荐

  1. 图形学_二维图形的剪裁_Sutherland-Hodgeman_Cohen—Sutherland

    一.Cohen-Sutherland剪裁算法 1.基本思想 对于每条线段P1P2分为三种情况处理: (1)若P1P2完全在窗口内,则显示该线段P1P2. (2)若P1P2明显在窗口外,则丢弃该线段. ...

  2. 计算机图形学 学习笔记(七):二维图形变换:平移,比例,旋转,坐标变换等

    接上文 计算机图形学 学习笔记(六):消隐算法:Z-buffer,区间扫描线,Warnock,光栅图形学小结 在图形学中,有两大基本工具:向量分析,图形变换.本文将重点讲解向量和二维图形的变换. 5. ...

  3. autocad2007二维图画法_cad怎样绘制简单的二维图形

    CAD绘制二维图形非常的简单,大家经常用它来画图,下面是学习啦小编带来关于cad怎样绘制简单的二维图形的内容,希望可以让大家有所收获! cad绘制简单二维图形的方法 1.绘图菜单绘图菜单是绘制图形最基 ...

  4. 通过Matrix进行二维图形仿射变换

    Affine Transformation是一种二维坐标到二维坐标之间的线性变换,保持二维图形的"平直性"和"平行性".仿射变换可以通过一系列的原子变换的复合来 ...

  5. 如何使用MATLAB绘制不同类型的二维图形

    如何使用MATLAB绘制不同类型的二维图形 听语音 | 浏览:360 | 更新:2014-11-30 18:10 | 标签:matlab 1 2 3 4 5 分步阅读 如何用MATLAB绘制各种二维图 ...

  6. 二维绕任意点旋转_二维图形复合线性变换程序设计:三角形绕任意点旋转2wfhbh...

    第七讲:二维图形复合线性变换程序设计: 例题:三角形绕任意点旋转. 组合变换为: ( 1 )平移变换 ( 2 )旋转变换 ( 3 )平移变换 #include #include #define PAI ...

  7. matlab 如何画二维图形,Matlab 学习 画图篇 一 二维图形

    matlab给绘制二维图形提供了很多的函数,把一些绘制二维图形的基本函数做成一张表,如下图所示: 我就按照表的顺序一一记录一些个函数的简略用法. 首先是 1.plot函数 plot函数有很多重载方法, ...

  8. matlab画二维颜色深浅,matlab中如何为二维图形填充渐进的颜色

    t1=(0:11)/11*pi; t2=(0:400)/400*pi; t3=(0:50)/50*pi; y1=sin(t1).*sin(9*t1); y2=sin(t2).*sin(9*t2); y ...

  9. 计算机图形学二维图形基本变换实验原理,计算机图形学实验:二维图形变换.docx...

    计算机图形学实验:二维图形变换.docx (9页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 实验三 二维图形变换一.实验任务1. 通 ...

最新文章

  1. 全虚拟化与半虚拟化的实现方式
  2. web cache缓存设备的需求与讨论 ( Http://CACHE.MARASYSTEMS.ASIA )
  3. SQL Lite on NHibernate
  4. 【数据库】navicat运行sql文件报错
  5. linux 内核/proc
  6. 【线程安全】—— 单例类双重检查加锁(double-checked locking)
  7. 阿里云 Link ID² 标准项目获浙江省标准创新重大贡献奖
  8. 如何寻找、下载期刊投稿的LaTeX模板
  9. R语言大作业(三):新乡市、郑州市不同学历毕业生信息统计
  10. 造成笔记本电池损耗的主要原因
  11. 解决undefined reference to `WinMain'
  12. 亚太融媒+ | APEC数据+:“鲸确数集”环保熊猫“小保保”2022拜年 | APEC产业+
  13. html的table 菜鸟,HTML table 标签 | 菜鸟教程
  14. IDC数据:中国VR市场2017预计增幅将达441.2%
  15. 【超实用】python批量ppt转图片,pdf转图片,word转图片脚本,直接拿去用
  16. 从三网融合看音视频即时通讯的市场与挑战
  17. 将ShellCode注入进程内存
  18. freemarker生成word不显示图片
  19. GB9706.1-2007名词解释:电气间隙、爬电距离,绝缘、接地等
  20. Python自动化:提取扫描件中的文字

热门文章

  1. cad自动运行dvb lisp_AutoCAD自动加载程序方法 - CAD自学网
  2. android NFC读写卡教程
  3. 【考研复试】西电833/834计网笔记
  4. 如何使用Authorware给原始视频添加字幕
  5. 小学生通用计算机在线使用,小学生信息学练习计算机基础.doc
  6. Cinema 4D自学笔记记录
  7. HTML 压缩库 HtmlCompressor
  8. Linux命令行操作Vmware虚拟机
  9. c语言全国贫困信息管理系统,全国扶贫开发信息系统业务管理子系统
  10. 前端开发程序员的年薪到底有多高?