[图形学] 习题8.6 线段旋转后使用Cohen-Sutherland算法裁剪
习题8.6 生成一条比观察窗口对角线还长的线段动画,线段重点位于观察窗口中心,每一帧的线段在上一帧基础上顺时针旋转一点,旋转后用Cohen-Sutherland线段裁剪算法进行裁剪。
步骤:
- 1 视口范围:(-100, -100)到(100, 100);
- 2 裁剪窗口区域:winMin(-50, -50) 到 winMax(50, 50),原始端点:p0(-100, 0)到 p1(100, 0)
- 3 使用Bresenham算法画原始线段,使用Cohen-Sutherland算法画裁剪线段;
- 4 theta += delta,其中 theta为累计旋转角度,delta为每次变化的角度;
- 5 计算旋转后的新的原始线段端点:p0'和p1'。x' = x * cos(theta) - y * sin(theta), y' = x * sin(theta) +y * cos(theta);
- 6 每帧重复步骤3-5.
#include <GLUT/GLUT.h>
#include <math.h>
#include <iostream>
#include "linebres.h"
#include "linecohsuth.h" const GLdouble PI = 3.1416;
GLdouble theta = 0.0;
const GLdouble delta = - PI / ; void init (void)
{
glClearColor(0.0, 0.0, 0.0, 1.0); glMatrixMode(GL_PROJECTION);
gluOrtho2D(-, , -, ); glMatrixMode(GL_MODELVIEW);
} void clippingWindow (void)
{
glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINE_LOOP);
glVertex2i(-, -);
glVertex2i(-, );
glVertex2i(, );
glVertex2i(, -);
glEnd();
} void displayFcn (void)
{
glClear(GL_COLOR_BUFFER_BIT); clippingWindow(); glColor3f(1.0, 1.0, 1.0); wcPt2D winMin, winMax;
winMin.setCoords(-, -);
winMax.setCoords(, ); wcPt2D p0, p1;
p0.setCoords(-, );
p1.setCoords(, ); wcPt2D p00, p01;
p00.setCoords(p0.getx() * cos(theta) - p0.gety() * sin(theta), p0.getx() * sin(theta) + p0.gety() * cos(theta));
p01.setCoords(p1.getx() * cos(theta) - p1.gety() * sin(theta), p1.getx() * sin(theta) + p1.gety() * cos(theta)); // std::cout << "p00 : " << p00.getx() << "," << p00.gety() << std::endl;
// std::cout << "p01 : " << p01.getx() << "," << p01.gety() << std::endl; glColor3f(1.0, 1.0, 0.0);
lineBres(round(p00.getx()), round(p00.gety()), round(p01.getx()), round(p01.gety()));
glColor3f(0.0, 1.0, 1.0);
lineClipCohSuth(winMin, winMax, p00, p01); glutSwapBuffers();
} void idleFcn (void)
{
theta += delta;
displayFcn();
} int main(int argc, char * argv[]) { glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(-, );
glutInitWindowSize(, );
glutCreateWindow("Exercise 8.6"); init();
glutDisplayFunc(displayFcn);
glutIdleFunc(idleFcn); glutMainLoop(); return ;
}
因为theta一直在变化,每次重新计算cos(theta)和sin(theta)会影响效率,因此p0和p1每次更新为旋转后的坐标,修改代码如下:
#include <GLUT/GLUT.h>
#include <math.h>
#include <iostream>
#include "linebres.h"
#include "linecohsuth.h" const GLdouble PI = 3.1416;
const GLdouble delta = - PI / ;
GLint initialized = ;
GLdouble cosDelta, sinDelta;
wcPt2D p0, p1, winMin, winMax; void init (void)
{
glClearColor(0.0, 0.0, 0.0, 1.0); glMatrixMode(GL_PROJECTION);
gluOrtho2D(-, , -, ); glMatrixMode(GL_MODELVIEW);
} void clippingWindow (void)
{
glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINE_LOOP);
glVertex2i(-, -);
glVertex2i(-, );
glVertex2i(, );
glVertex2i(, -);
glEnd();
} void displayFcn (void)
{
glClear(GL_COLOR_BUFFER_BIT); clippingWindow(); glColor3f(1.0, 1.0, 1.0); if(!initialized)
{
initialized = ;
cosDelta = cos(delta);
sinDelta = sin(delta);
winMin.setCoords(-, -);
winMax.setCoords(, );
p0.setCoords(-, );
p1.setCoords(, );
} p0.setCoords(p0.getx() * cosDelta - p0.gety() * sinDelta, p0.getx() * sinDelta + p0.gety() * cosDelta);
p1.setCoords(p1.getx() * cosDelta - p1.gety() * sinDelta, p1.getx() * sinDelta + p1.gety() * cosDelta); glColor3f(1.0, 1.0, 0.0);
lineBres(round(p0.getx()), round(p0.gety()), round(p1.getx()), round(p1.gety()));
glColor3f(0.0, 1.0, 1.0);
lineClipCohSuth(winMin, winMax, p0, p1); glutSwapBuffers();
} int main(int argc, char * argv[]) { glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(-, );
glutInitWindowSize(, );
glutCreateWindow("Exercise 8.6"); init();
glutDisplayFunc(displayFcn);
glutIdleFunc(displayFcn); glutMainLoop(); return ;
}
本来想使用glRotatef(delta, 0.0, 0.0, 1.0)这个转换矩阵进行旋转,但使用C-S裁剪算法时传入的端点坐标依然不是旋转后的,先裁剪后旋转导致裁剪区域不对。不知道是否可以用glRotatef来解答这道题目。

[图形学] 习题8.6 线段旋转后使用Cohen-Sutherland算法裁剪的更多相关文章
- [图形学] 习题8.12 NLN二维线段裁剪算法实现
Nicholl-Lee-Nicholl二维线段裁剪算法相对于Cohen-Sutherland和Liang-Barsky算法来说,在求交点之前进行了线段端点相对于几个区域的判断,可以确切的知道要求交点的 ...
- 【LeetCode】Find Minimum in Rotated Sorted Array 找到旋转后有序数组中的最小值
本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4032570.html 原题: Suppose a sorted array is ...
- Launcher3自定义壁纸旋转后拉伸无法恢复
MTK8382/8121平台. 描述:将自定义图片设置成壁纸后,横屏显示时,旋转为竖屏,图片由于分辨率过小,会拉伸:再旋转为横屏,拉伸不恢复. 这两天正在解这个问题,研究了很久,走了不少弯路,最后发现 ...
- [golang]图片按中心旋转后,新图的左顶点位置的偏移量
1 前言 图片按中心旋转后,新图的左顶点位置的偏移量 2 代码 func OffsetXYAfterRotationCore(W, H, L, T, Angle float64) (x, y floa ...
- iOS开发 CGAffineTransform 让图片旋转, 旋转后获得图片旋转的角度
1.让图片旋转 UIImageView *imageView = [[UIImageView alloc]init]; imageView.frame = CGRectMake(50, 50, 200 ...
- Android设置屏幕旋转后保存数据
1.onCreate()方法中最后判断需要保存的状态值 if(savedInstanceState != null){ mCurrentIndex = savedInstanceState.getIn ...
- [PHP] 算法-有序数组旋转后寻找最小值的PHP实现
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组 ...
- CSU 1453: 平衡序列 学会线段树后必做
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1453. 题目:给定一个大小为100000的数组,里面的数字最大也是100000.现在叫你求出一段子 ...
- scramble-string——两个字符串经过树化并旋转后是否一致、递归、动态规划
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...
随机推荐
- JS代码整洁随笔
// 之前都是这么写:使用undefined和null来检测一个属性是否存在 if (obj['name'] !== undefined) { console.log('name属性存在'); // ...
- java web 数据库开发1
一个完整的数据库部署架构通常由客户端和服务器端两部分组成.客户端封装数据库请求将其发送给服务器端,服务器端执行完毕将其及结果返回给服务器端. 以mysql为例 介绍java应用程序对数据库的访问 JD ...
- Struts2入门(一)
今天学习Struts2首先struts是一个成熟的框架.Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Cont ...
- centos6.5 ssh免密码登陆
ssh-keygen -t rsa ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop1
- 获取openId | 小程序
最近项目中需要使用微信授权,继上一篇<关于微信小程序拒绝授权后,重新授权并获取用户信息>之后,需要获取用户的openId,开发测试时,发现无论如何都获取不到: 官方文档如下: 相信很多同学 ...
- javaSE_06Java中的数组(array)-提高练习
1.求1!+2!+3!+···+30!的和,定义一个方法 public class Test1{ public static void main(String[] args){ //1.求1!+2!+ ...
- Delphi使用Zint生成QR二维条码(zint.dll)
Delphi使用Zint生成QRCODE 本文使用的Zint Barcode Library(zint.dll)版本为2.6.0,和之前使用的2.4.3版本在zint_symbol这个结构体上会有差异 ...
- std::forward_list
forward_list相比list来说空间利用率更好,与list一样不支持随机访问,若要访问除头尾节点的其他节点则时间复杂度为线性. 在forward_list成员函数里只能访问头节点以及向头节点插 ...
- 基于java.util.logging实现轻量级日志记录库(增加根据当前类class初始化,修复线程池模型(javaEE)下的堆栈轨迹顺序与当前调用方法不一致问题)
前言: 本章介绍自己写的基于java.util.logging的轻量级日志记录库(baseLog). 该版本的日志记录库犹如其名,baseLog,是个实现日志记录基本功能的小库,适合小型项目使用,方便 ...
- Unslider Web前端框架之图片轮播
前端框架,前端组件,前端库,都是一个意思,能看源码. 最近做H5小游戏,用到了图片轮播的组件,而且要求支持移动端触屏滑动.一开始用的是nivo slider,但是对大小不一样的图不支持box 的参数设 ...