计算机图形学-实验五 直线和多边形的裁剪
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
大学实验报告
学院:计算机科学与信息学院专业:软件工程班级:102班
学号实验组实验时间指导教师成绩实验项目名称实验五直线和多边形的裁剪
实
验
目
的
掌握直线段的裁剪算法以及多边形的裁剪算法
实
验要求熟练掌握直线段的裁剪算法以及多边形的裁剪算法的基本原理,并编写测试代码进行实验。
实验原理
Cohen-Sutherland直线剪裁算法
以区域编码为基础,将窗口及其周围的,8个方向以4 bit的二进制数进行编码。
右图所示的编码方法将窗口及其邻域
分为5个区域:
⑴域:区域(0000)。
⑵上域:区域(1001, 1000, 1010)。
⑶下域:区域(0101, 0100, 0110)。
⑷左域:区域(1001, 0001, 0101)。
⑸右域:区域(1010, 0010, 0110)。
当线段的两个端点的编码的逻辑“与”非零时,线段为显然不可见的,对某线段的两个端点的区号进行位与运算,可知这两个端点是否同在视区的上、下、左、右;
Cohen-Sutherland直线剪裁算法的算法思想是:
对于每条线段P1P2分为三种情况处理。(1)若P1P2完全在窗口,则显示该线段P1P2简称“取”之。(2)若P1P2明显在窗口外,则丢弃该线段,简称“弃”之。(3)若线段既不满足“取”的条件,也不满足“弃”的条件,则在交点处把线段分为两段。其中
while (code1 != 0 || code2 != 0) {
if ((code1 & code2) != 0) {// 两端点的编码相与不为0,表示直线在窗口外
return;
}
if (code1 != 0) {
code = code1;
} else {
code = code2;
}
if ((LEFT & code) != 0) {// 直线的端点与矩形窗口的左边编码相与!=0 x = XL;
y = y1 + (y2 - y1) * (XL - x1) / (x2 - x1);// 求直线与矩形窗口的左边界的交点
} else if ((RIGHT & code) != 0) {// 直线的端点与矩形窗口的右边编码相与!=0
x = XR;
y = y1 + (y2 - y1) * (XR - x1) / (x2 - x1);// 求直线与矩形窗口的右边界的交点
} else if ((BOTTOM & code) != 0) {// 直线的端点与矩形窗口的下边编码相与!=0
y = YB;
x = x1 + (x2 - x1) * (YB - y1) / (y2 - y1);// 求直线与矩形窗口的下边界的交点
} else if ((TOP & code) != 0) {// 直线的端点与矩形窗口的上边编码相与!=0
y = YT;
x = x1 + (x2 - x1) * (YT - y1) / (y2 - y1);// 直线的端点与矩形窗口的
上
// 边编码相与!=0
}
if (code == code1) {
x1 = x;
y1 = y;
code1 = encode(x, y);
} else {
x2 = x;
y2 = y;
code2 = encode(x, y);
}
}
g.drawLine((int) (x1 + 0.5), (int) (y1 + 0.5), (int) (x2 + 0.5),(int) (y2 + 0.5));
}
二、多边形裁剪的核心代码为:
通过点集画直线或者多边形:
private void draw() {//通过点集画直线或者多边形
for (int i = 1; i < points.size(); i++) {
Point p1 = new Point();
p1 = points.get(i);
int x1 = (int) p1.getX();
int y1 = (int) p1.getY();
Point p2 = new Point();
p2 = points.get(i - 1);
int x2 = (int) p2.getX();
int y2 = (int) p2.getY();
g.drawLine(x1, y1, x2, y2);
}
}
多边形的裁剪函数:
private Point[] cutPicture(Point[] point, Point[] edge) {// 剪裁函数,参数为(点集,边)Point[] intersectPoint = new Point[20];//存放交点的集合
for (int j = 0; j < 20; j++) {
intersectPoint[j] = new Point();
}
Point s = new Point();
Point p = new Point();
Point t = new Point();
int i = 0;
int length = point.length;
s = point[length - 1];
for (int j = 0; j < length; j++) {
p = point[j];
if (inside(p, edge)) {// sp在窗口,情况1
if (inside(s, edge)) {
intersectPoint[i] = p;
i += 1;
} else {// s在窗口外,情况4
t = intersect(s, p, edge);
intersectPoint[i] = t;
i += 1;
intersectPoint[i] = p;
i += 1;
}