Advertisement
Ladies_Man

#CG LAB5 (clipping) COMPLETE

May 6th, 2015
308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.47 KB | None | 0 0
  1. //отсечение средней точкой
  2. //управление: задать 2 точки -> d -> рисовать отрезки
  3.  
  4. // glfw_30.cpp : Defines the entry point for the console application.
  5.  
  6. #include "stdafx.h"
  7. #include <time.h>
  8. #define _USE_MATH_DEFINES
  9. #include <cmath>
  10. #include <GL/glew.h>
  11. #include <GL\glut.h>
  12. #include <GLFW/glfw3.h>
  13. #include <vector>
  14. #include <cstdlib>
  15.  
  16. #define SCREEN_WIDTH        600
  17. #define SCREEN_HEIGHT       400
  18. #define SCREEN_POS_X        100
  19. #define SCREEN_POS_Y        100
  20.  
  21. typedef struct point
  22. {
  23.     int x, y;
  24.     bool p_visibility;
  25.  
  26.     //original idea by Ivan.M
  27.     union {
  28.         struct {
  29.             char _0bit : 1;     //standalone bit
  30.             char _1bit : 1;
  31.             char _2bit : 1;
  32.             char _3bit : 1;
  33.             char _rest : 4;     //standalone 4bits
  34.         };
  35.         char half : 4;      //first half of char (first 4bits) above presented as number
  36.     };
  37. }point;
  38.  
  39. typedef struct line
  40. {
  41.     point a, b;
  42.     int len;
  43.     bool l_visibility;
  44. }line;
  45.  
  46. typedef struct clipper
  47. {
  48.     point a, b, c, d;
  49.     int x_min, x_max;
  50.     int y_min, y_max;
  51. }clipper;
  52.  
  53. bool draw_flag;
  54.  
  55. std::vector<point> temp_vect;
  56.  
  57. clipper my_clipper;
  58.  
  59. std::vector<line> lines;
  60. std::vector<line> pre_visible;
  61.  
  62. std::vector<line> final_lines;
  63.  
  64. int line_len(point a, point b)
  65. {
  66.     int dx = abs(a.x - b.x);
  67.     int dy = abs(a.y - b.y);
  68.  
  69.     return (int)sqrt(dx * dx + dy*dy);
  70. }
  71.  
  72. int get_code(point a)
  73. {
  74.     int code = 0;
  75.  
  76.     a._0bit = 0;
  77.     a._1bit = 0;
  78.     a._2bit = 0;
  79.     a._3bit = 0;
  80.     a._rest = 0;
  81.  
  82.     if (a.x < my_clipper.x_min) {
  83.         code += 1;
  84.         a._0bit = 1;
  85.     }
  86.     if (a.y > my_clipper.y_max) {
  87.         code += 10;
  88.         a._1bit = 1;
  89.     }
  90.     if (a.x > my_clipper.x_max) {
  91.         code += 100;
  92.         a._2bit = 1;
  93.     }
  94.     if (a.y < my_clipper.y_min) {
  95.         code += 1000;
  96.         a._3bit = 1;
  97.     }
  98.  
  99.     return code;
  100. }
  101.  
  102. bool point_visibility(point a)
  103. {
  104.     bool inner_x = false, inner_y = false;
  105.  
  106.     if (my_clipper.x_max > a.x && my_clipper.x_min < a.x) inner_x = true;
  107.     if (my_clipper.y_max > a.y && my_clipper.y_min < a.y) inner_y = true;
  108.  
  109.     if (inner_x && inner_y) return true;
  110.  
  111.     return false;
  112. }
  113.  
  114. int line_visibility(point a, point b)
  115. {
  116.     int code_a = get_code(a);
  117.     int code_b = get_code(b);
  118.  
  119.     if (a.half & b.half != 0) return -1;    //triv_invisibility
  120.  
  121.     if (a.half == 0 && b.half == 0) return 1;   //visibility
  122.  
  123.     return 0;
  124. }
  125.  
  126. point mid_point(point a, point b)
  127. {
  128.     point middle;
  129.  
  130.     middle.x = (a.x + b.x) / 2;
  131.     middle.y = (a.y + b.y) / 2;
  132.     int code = get_code(middle);
  133.  
  134.     return middle;
  135. }
  136.  
  137. void clip(line AB)
  138. {
  139.     int code_a = get_code(AB.a);
  140.     int code_b = get_code(AB.b);
  141.     int l_v = line_visibility(AB.a, AB.b);
  142.     int len = line_len(AB.a, AB.b);
  143.  
  144.     line half_1, half_2;
  145.  
  146.     if (l_v == -1)
  147.         return;
  148.  
  149.     if (l_v == 1) {
  150.         pre_visible.push_back(AB);
  151.         return;
  152.     }
  153.  
  154.     if (len == 1) {
  155.         if (point_visibility(AB.a))
  156.             pre_visible.push_back(AB);
  157.         return;
  158.     }
  159.  
  160.     if (l_v == 0) {
  161.         half_1.a = AB.a;
  162.         half_1.b = mid_point(AB.a, AB.b);
  163.         clip(half_1);
  164.  
  165.         half_2.a = mid_point(AB.a, AB.b);
  166.         half_2.b = AB.b;
  167.         clip(half_2);
  168.     }
  169. }
  170.  
  171. void changeSize(int w, int h)
  172. {
  173.     if (0 == h) h = 1;
  174.  
  175.     float ratio = w * 1.0 / h;
  176.  
  177.     // Use the Projection Matrix
  178.     glMatrixMode(GL_PROJECTION);
  179.  
  180.     // Reset Matrix
  181.     glLoadIdentity();
  182.  
  183.     // Set the viewport to be the entire window
  184.     glViewport(0, 0, w, h);
  185.  
  186.     // Set the correct perspective.
  187.     gluOrtho2D(0, (GLdouble)w, 0, (GLdouble)h);
  188.  
  189.     // Get Back to the Modelview
  190.     glMatrixMode(GL_MODELVIEW);
  191. }
  192.  
  193.  
  194. //==================INPUT===================
  195. void set_clipper()
  196. {
  197.     int x_max, x_min, y_max, y_min;
  198.     point tmp1 = temp_vect[0], tmp2 = temp_vect[1];
  199.  
  200.     if (tmp1.x > tmp2.x) {
  201.         x_max = tmp1.x;
  202.         x_min = tmp2.x;
  203.     }
  204.     else {
  205.         x_max = tmp2.x;
  206.         x_min = tmp1.x;
  207.     }
  208.  
  209.     if (tmp1.y > tmp2.y) {
  210.         y_max = tmp1.y;
  211.         y_min = tmp2.y;
  212.     }
  213.     else {
  214.         y_max = tmp2.y;
  215.         y_min = tmp1.y;
  216.     }
  217.  
  218.     my_clipper.x_max = x_max;
  219.     my_clipper.x_min = x_min;
  220.     my_clipper.y_max = y_max;
  221.     my_clipper.y_min = y_min;
  222.  
  223.     my_clipper.a.x = x_min;
  224.     my_clipper.a.y = y_max;
  225.  
  226.     my_clipper.b.x = x_max;
  227.     my_clipper.b.y = y_max;
  228.  
  229.     my_clipper.c.x = x_max;
  230.     my_clipper.c.y = y_min;
  231.  
  232.     my_clipper.d.x = x_min;
  233.     my_clipper.d.y = y_min;
  234. }
  235.  
  236. void draw_clipper()
  237. {
  238.     glBegin(GL_LINE_LOOP);
  239.         glColor3f(1, 0, 0);
  240.         glVertex2f(my_clipper.a.x, my_clipper.a.y);
  241.         glVertex2f(my_clipper.b.x, my_clipper.b.y);
  242.         glVertex2f(my_clipper.c.x, my_clipper.c.y);
  243.         glVertex2f(my_clipper.d.x, my_clipper.d.y);
  244.     glEnd();
  245. }
  246.  
  247. void draw_original_lines()
  248. {
  249.     for (int i = 0; i < lines.size(); i++) {
  250.         glColor3f(0, 0, 1);
  251.         glBegin(GL_LINES);
  252.             glVertex2f(lines[i].a.x, lines[i].a.y);
  253.             glVertex2f(lines[i].b.x, lines[i].b.y);
  254.         glEnd();
  255.     }
  256. }
  257.  
  258.  
  259. //=================OUTPUT===================
  260. void draw_visible_lines()
  261. {
  262.     glLineWidth(1.0);
  263.     for (int i = 0; i < final_lines.size(); i++) {
  264.         glBegin(GL_LINES);
  265.             glColor3f(1, 0, 0);
  266.             glVertex2f(final_lines[i].a.x, final_lines[i].a.y);
  267.             glVertex2f(final_lines[i].b.x, final_lines[i].b.y);
  268.         glEnd();
  269.     }
  270. }
  271.  
  272.  
  273. //===================MAIN====================
  274. void renderScene(void)
  275. {
  276.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  277.  
  278.     if (draw_flag && temp_vect.size() > 1) {
  279.         draw_clipper();
  280.         draw_original_lines();
  281.         draw_visible_lines();
  282.     }
  283.  
  284.     glutSwapBuffers();
  285. }
  286.  
  287. int m = 0;
  288.  
  289. void mouseButton(int button, int state, int x, int y)
  290. {
  291.     if (GLUT_LEFT_BUTTON == button) {
  292.         int k, p;
  293.         point a;
  294.         line AB, tmp;
  295.         if (GLUT_DOWN == state) {
  296.             a.x = x;
  297.             a.y = SCREEN_HEIGHT - y;
  298.  
  299.             temp_vect.push_back(a);
  300.             if (m > 1 && m % 2 != 0) {
  301.                 AB.a = temp_vect[m - 1];
  302.                 AB.b = temp_vect[m];
  303.  
  304.                 lines.push_back(AB);
  305.  
  306.                 clip(AB);   //main process - mid point segmentation clipping
  307.  
  308.                 if (pre_visible.size() == 0) {
  309.                     goto fuck;
  310.                 } else {
  311.                     p = 0;
  312.                     k = pre_visible.size() - 1;
  313.                 }
  314.  
  315.                 tmp.a = pre_visible[p].a;
  316.                 tmp.b = pre_visible[k].b;
  317.  
  318.                 final_lines.push_back(tmp);
  319.  
  320.                 pre_visible.clear();
  321.                 pre_visible.shrink_to_fit();
  322.             }
  323.            
  324.         fuck:
  325.             m++;
  326.             glutPostRedisplay();
  327.         }
  328.         if (GLUT_UP == state) {
  329.             glutPostRedisplay();
  330.         }
  331.     }
  332. }
  333.  
  334. void keyboardButton(unsigned char key, int x, int y)
  335. {
  336.     if ('d' == key || 'D' == key) {
  337.         draw_flag = true;
  338.         set_clipper();
  339.  
  340.         printf("clipper\n");
  341.  
  342.         glutPostRedisplay();
  343.     }
  344.     if ('t' == key || 'T' == key) {
  345.         printf("temp_vect.size=%d vertices\n", temp_vect.size());
  346.         printf("lines.size=%d lines\n", lines.size());
  347.         for (int i = 0; i < lines.size(); i++) {
  348.             printf(" %dx%d -> ", lines[i].a.x, lines[i].a.y);
  349.             printf("%dx%d\n", lines[i].b.x, lines[i].b.y);
  350.         }
  351.         printf("vis_lines.size=%d lines\n", pre_visible.size());
  352.         for (int i = 0; i < pre_visible.size(); i++) {
  353.             printf(" %dx%d -> ", pre_visible[i].a.x, pre_visible[i].a.y);
  354.             printf("%dx%d\n", pre_visible[i].b.x, pre_visible[i].b.y);
  355.         }
  356.         printf("temp_vect: p_X x p_Y (code)\n");
  357.         for (int i = 2; i < temp_vect.size(); i++) {
  358.             printf("%dx%d (%d)\n", temp_vect[i].x, temp_vect[i].y, get_code(temp_vect[i]));
  359.         }
  360.         glutPostRedisplay();
  361.     }
  362. }
  363.  
  364. void initial_state()
  365. {
  366.     glClearColor(0.9, 0.9, 0.9, 1);
  367.  
  368.     draw_flag = false;
  369. }
  370.  
  371. int main(int argc, char **argv)
  372. {
  373.     glutInit(&argc, argv);
  374.     glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
  375.     glutInitWindowPosition(SCREEN_POS_X, SCREEN_POS_Y);
  376.     glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
  377.     glutCreateWindow("Anthony's Project: Lab 5(clipping)");
  378.  
  379.     glutDisplayFunc(renderScene);
  380.     glutReshapeFunc(changeSize);
  381.     glutIdleFunc(renderScene);
  382.  
  383.     glutMouseFunc(mouseButton);
  384.     glutKeyboardFunc(keyboardButton);
  385.  
  386.     initial_state();
  387.  
  388.     glutMainLoop();
  389.  
  390.     return 0;
  391. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement