习题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来解答这道题目。

commit: 6ee4159541b305fadd2bf88b1dbd950558e12e8e 

[图形学] 习题8.6 线段旋转后使用Cohen-Sutherland算法裁剪的更多相关文章

  1. [图形学] 习题8.12 NLN二维线段裁剪算法实现

    Nicholl-Lee-Nicholl二维线段裁剪算法相对于Cohen-Sutherland和Liang-Barsky算法来说,在求交点之前进行了线段端点相对于几个区域的判断,可以确切的知道要求交点的 ...

  2. 【LeetCode】Find Minimum in Rotated Sorted Array 找到旋转后有序数组中的最小值

     本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4032570.html 原题: Suppose a sorted array is ...

  3. Launcher3自定义壁纸旋转后拉伸无法恢复

    MTK8382/8121平台. 描述:将自定义图片设置成壁纸后,横屏显示时,旋转为竖屏,图片由于分辨率过小,会拉伸:再旋转为横屏,拉伸不恢复. 这两天正在解这个问题,研究了很久,走了不少弯路,最后发现 ...

  4. [golang]图片按中心旋转后,新图的左顶点位置的偏移量

    1 前言 图片按中心旋转后,新图的左顶点位置的偏移量 2 代码 func OffsetXYAfterRotationCore(W, H, L, T, Angle float64) (x, y floa ...

  5. iOS开发 CGAffineTransform 让图片旋转, 旋转后获得图片旋转的角度

    1.让图片旋转 UIImageView *imageView = [[UIImageView alloc]init]; imageView.frame = CGRectMake(50, 50, 200 ...

  6. Android设置屏幕旋转后保存数据

    1.onCreate()方法中最后判断需要保存的状态值 if(savedInstanceState != null){ mCurrentIndex = savedInstanceState.getIn ...

  7. [PHP] 算法-有序数组旋转后寻找最小值的PHP实现

    把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组 ...

  8. CSU 1453: 平衡序列 学会线段树后必做

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1453. 题目:给定一个大小为100000的数组,里面的数字最大也是100000.现在叫你求出一段子 ...

  9. scramble-string——两个字符串经过树化并旋转后是否一致、递归、动态规划

    Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...

随机推荐

  1. 【Netty】Netty之ByteBuf

    一.前言 前面已经学习了Netty中传输部分,现在接着学习Netty中的ByteBuf. 二.ByteBuf 2.1 ByteBuf API 在网络上传输的数据形式为Byte,Java NIO提供了B ...

  2. opencv基础到进阶(2)

    本文为系列文章的第2篇,主要讲解对图像的像素的操作方法. 2.1存取像素值 为了存取矩阵元素,需要指定元素所在的行和列,程序会返回相应的元素.单通道图像返回单个数值,多通道图像,返回的则是一组向量(V ...

  3. 地理位置 API

    js获取地理位置的接口navigator.geolocation geolocation对象有三个方法 1.getCurrentPosition 2.watchPosition 3.clearWatc ...

  4. 使用VideoView开发视频总结

    一.VideoView及其相关组件总结 在Android中,播放视频有2种方式,第一种方式是使用MediaPlayer结合SurfaceView来播放,通过MediaPlayer来控制视频的播放.暂停 ...

  5. be 动词

    be 动词:表达人或事物的状态,即身份.性质.特征状态等 be动词 在翻译里面我们称之为缺项词,在我们的文化中很难找到一个具体的词汇与之像应对,我们只能用一个句子去解释它. be动词主要是用来表达人或 ...

  6. OOP中this指向详解

    谁调用了函数,this就指向谁 >>> this指向的永远只可能是对象!!! >>> this指向谁,永远不取决于this写在哪,而是取决于函数在哪调用!!! &g ...

  7. python学习-面向对象

    面向对象 编程方式的区别 过程式编程 函数式编程 面向对象式编程 面向对象编程 对象是类的一个实例 创建 class foo(): def __init__(self): #类的构造方法 pass d ...

  8. ecshop支付方式含线下自提

    用户展示页面模板所在:如ecshop/theme/default/flow.dwt 后台管理展示页面模板所在:如admin/templates/payment_list.htm ecshop 支付接口 ...

  9. [1] MVC & MVP &MVVM

    开发架构之MVC & MVP & MVVM  

  10. Go - method

    hello, 大家好,由于之前工作上面的事情较多,所以关于go语言的学习就暂时“搁浅了”...不过从今天开始,我们又将回到了go语言的学习过程之中. 当然,我们学习go的"初心"是 ...