• [图形学] 习题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.
     1 #include <GLUT/GLUT.h>
     2 #include <math.h>
     3 #include <iostream>
     4 #include "linebres.h"
     5 #include "linecohsuth.h"
     6 
     7 const GLdouble PI = 3.1416;
     8 GLdouble theta = 0.0;
     9 const GLdouble delta = - PI / 100;
    10 
    11 void init (void)
    12 {
    13     glClearColor(0.0, 0.0, 0.0, 1.0);
    14     
    15     glMatrixMode(GL_PROJECTION);
    16     gluOrtho2D(-100, 100, -100, 100);
    17     
    18     glMatrixMode(GL_MODELVIEW);
    19 }
    20 
    21 void clippingWindow (void)
    22 {
    23     glColor3f(1.0, 1.0, 1.0);
    24     
    25     glBegin(GL_LINE_LOOP);
    26     glVertex2i(-50, -50);
    27     glVertex2i(-50, 50);
    28     glVertex2i(50, 50);
    29     glVertex2i(50, -50);
    30     glEnd();
    31 }
    32 
    33 void displayFcn (void)
    34 {
    35     glClear(GL_COLOR_BUFFER_BIT);
    36     
    37     clippingWindow();
    38     
    39     glColor3f(1.0, 1.0, 1.0);
    40     
    41     wcPt2D winMin, winMax;
    42     winMin.setCoords(-50, -50);
    43     winMax.setCoords(50, 50);
    44     
    45     wcPt2D p0, p1;
    46     p0.setCoords(-100, 0);
    47     p1.setCoords(100, 0);
    48     
    49     wcPt2D p00, p01;
    50     p00.setCoords(p0.getx() * cos(theta) - p0.gety() * sin(theta), p0.getx() * sin(theta) + p0.gety() * cos(theta));
    51     p01.setCoords(p1.getx() * cos(theta) - p1.gety() * sin(theta), p1.getx() * sin(theta) + p1.gety() * cos(theta));
    52     
    53 //    std::cout << "p00 : " << p00.getx() << "," << p00.gety() << std::endl;
    54 //    std::cout << "p01 : " << p01.getx() << "," << p01.gety() << std::endl;
    55     
    56     glColor3f(1.0, 1.0, 0.0);
    57     lineBres(round(p00.getx()), round(p00.gety()), round(p01.getx()), round(p01.gety()));
    58     glColor3f(0.0, 1.0, 1.0);
    59     lineClipCohSuth(winMin, winMax, p00, p01);
    60     
    61     glutSwapBuffers();
    62 }
    63 
    64 void idleFcn (void)
    65 {
    66     theta += delta;
    67     displayFcn();
    68 }
    69 
    70 int main(int argc, char * argv[]) {
    71 
    72     glutInit(&argc, argv);
    73     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    74     glutInitWindowPosition(-50, 50);
    75     glutInitWindowSize(600, 600);
    76     glutCreateWindow("Exercise 8.6");
    77     
    78     init();
    79     glutDisplayFunc(displayFcn);
    80     glutIdleFunc(idleFcn);
    81     
    82     glutMainLoop();
    83     
    84     return 0;
    85 }
    View Code

      因为theta一直在变化,每次重新计算cos(theta)和sin(theta)会影响效率,因此p0和p1每次更新为旋转后的坐标,修改代码如下:

     1 #include <GLUT/GLUT.h>
     2 #include <math.h>
     3 #include <iostream>
     4 #include "linebres.h"
     5 #include "linecohsuth.h"
     6 
     7 const GLdouble PI = 3.1416;
     8 const GLdouble delta = - PI / 100;
     9 GLint initialized = 0;
    10 GLdouble cosDelta, sinDelta;
    11 wcPt2D p0, p1, winMin, winMax;
    12 
    13 void init (void)
    14 {
    15     glClearColor(0.0, 0.0, 0.0, 1.0);
    16     
    17     glMatrixMode(GL_PROJECTION);
    18     gluOrtho2D(-100, 100, -100, 100);
    19     
    20     glMatrixMode(GL_MODELVIEW);
    21 }
    22 
    23 void clippingWindow (void)
    24 {
    25     glColor3f(1.0, 1.0, 1.0);
    26     
    27     glBegin(GL_LINE_LOOP);
    28     glVertex2i(-50, -50);
    29     glVertex2i(-50, 50);
    30     glVertex2i(50, 50);
    31     glVertex2i(50, -50);
    32     glEnd();
    33 }
    34 
    35 void displayFcn (void)
    36 {
    37     glClear(GL_COLOR_BUFFER_BIT);
    38     
    39     clippingWindow();
    40     
    41     glColor3f(1.0, 1.0, 1.0);
    42     
    43     if(!initialized)
    44     {
    45         initialized = 1;
    46         cosDelta = cos(delta);
    47         sinDelta = sin(delta);
    48         winMin.setCoords(-50, -50);
    49         winMax.setCoords(50, 50);
    50         p0.setCoords(-100, 0);
    51         p1.setCoords(100, 0);
    52     }
    53     
    54     p0.setCoords(p0.getx() * cosDelta - p0.gety() * sinDelta, p0.getx() * sinDelta + p0.gety() * cosDelta);
    55     p1.setCoords(p1.getx() * cosDelta - p1.gety() * sinDelta, p1.getx() * sinDelta + p1.gety() * cosDelta);
    56     
    57     glColor3f(1.0, 1.0, 0.0);
    58     lineBres(round(p0.getx()), round(p0.gety()), round(p1.getx()), round(p1.gety()));
    59     glColor3f(0.0, 1.0, 1.0);
    60     lineClipCohSuth(winMin, winMax, p0, p1);
    61     
    62     glutSwapBuffers();
    63 }
    64 
    65 int main(int argc, char * argv[]) {
    66 
    67     glutInit(&argc, argv);
    68     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    69     glutInitWindowPosition(-50, 50);
    70     glutInitWindowSize(600, 600);
    71     glutCreateWindow("Exercise 8.6");
    72     
    73     init();
    74     glutDisplayFunc(displayFcn);
    75     glutIdleFunc(displayFcn);
    76     
    77     glutMainLoop();
    78     
    79     return 0;
    80 }
    View Code

      本来想使用glRotatef(delta, 0.0, 0.0, 1.0)这个转换矩阵进行旋转,但使用C-S裁剪算法时传入的端点坐标依然不是旋转后的,先裁剪后旋转导致裁剪区域不对。不知道是否可以用glRotatef来解答这道题目。

    commit: 6ee4159541b305fadd2bf88b1dbd950558e12e8e 

  • 相关阅读:
    Linux下g++编译与使用静态库和动态库(仅命令)
    Shell算数运算
    (转载)解决/usr/bin/ld: cannot find -lxxx 问题
    (转)C语言中的EOF和feof()
    204 Count Primes
    228 Summary Range
    235 Lowest Common Ancestor of a Binary Search Tree
    242 Valid Anagram
    简易计算器实现优化
    原生JS操作cookie
  • 原文地址:https://www.cnblogs.com/p0e0o0p0l0e0/p/6925092.html
Copyright © 2020-2023  润新知