# Untitled

Jun 14th, 2021
677
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. #define GL_SILENCE_DEPRECATION //Убираем предупреждения
2. #define _USE_MATH_DEFINES
3. //#include "GL/glew.h"
4. #include "GLFW/glfw3.h"
5. #include <stdlib.h>
6. #include <math.h>
7. #include <iostream>
8. #include <cstring>
9. #include <vector>
10. #include <ctime>
11. #include <sstream>
12. #include <fstream>
13. #include <time.h>
14.
15. #define SQUARE(a) a * a
16. #define MODULE_FRICTION_FORCE 10.f
17. #define MODULE_PULLING_FORCE 10.5f
18. #define WALL_POS_1 15.f
19. #define WALL_POS_2 -10.f
20. GLint w, h;
21.
22. class Point
23. {
24.
25. public:
26.
27.     long double x;
28.     long double y;
29.     long double z;
30.
31.     Point( long double pX , long double pY, long double pZ ){
32.         x = pX;
33.         y = pY;
34.         z = pZ;
35.     }
36.     friend bool operator == (const Point & c1,
37.                              const Point & c2) {
38.         return c1.x == c2.x && c1.y == c2.y && c1.z == c2.z;
39.     }
40. };
41.
42. class vertex {
43. public:
44.     Point coord = Point(0,0,0);
45.     Point norm_vector = Point(0,0,0);
46. };
47.
48. double sqr(double x) {return x * x; }
49.
50. class Poly
51. {
52. public:
53.     std::vector <vertex> points;
54.     Point poly_normal = Point(0,0,0);
55.
56.     Poly(Point p1 , Point p2, Point p3){
57.         vertex x, y, z;
58.         x.coord = p1;
59.         y.coord = p2;
60.         z.coord = p3;
61.         points.push_back(x); points.push_back(y); points.push_back(z);
62.     }
63.
64.     void CalcNormals()
65.     {
66.         Point a = points[0].coord;
67.         Point b = points[1].coord;
68.         Point c = points[2].coord;
69.
70.         long double wrki;
71.         Point v1 = Point(a.x - b.x, a.y - b.y, a.z - b.z);
72.         Point v2 = Point(b.x - c.x, b.y - c.y, b.z - c.z);
73.
74.         wrki = sqrt(sqr(v1.y*v2.z - v1.z * v2.y) + sqr(v1.z * v2.x - v1.x * v2.z) + sqr(v1.x * v2.y - v1.y * v2.x));
75.
76.         poly_normal = Point((v1.y * v2.z - v1.z * v2.y) / wrki, (v1.z * v2.x - v1.x * v2.z) / wrki, (v1.x * v2.y - v1.y * v2.x) / wrki);
77.     }
78.
79.     bool has_vertex(vertex p){
80.         for (int i = 0; i < points.size(); i++){
81.             if (points[i].coord == p.coord){
82.                 return true;
83.             }
84.         }
85.         return false;
86.     }
87. };
88.
89. using namespace std;
90. enum asics{X, Y, Z};
91. bool light_on = false;
92. bool normal_flag = false;
93. bool animation = false;
94. float move_X = 0.0f;
95. float move_Y = 0.0f;
96. float move_Z = 0.0f;
97. float rot_X = 0.0f;
98. float rot_Y = 0.0f;
99. float rot_Z = 0.0f;
100.
101.
102. GLuint  box;
103. GLuint  fig;
104. GLuint  norm;
105.
106. int current_asic = X;
107. int change_height = 100;
108. int num_poly = 6;
109. float mode = GL_LINE_LOOP;
110. vector < vector <Point> > figure;
111. vector < Poly > poly_fig;
112.
113.
114. void resize_callback(GLFWwindow *window, int new_w, int new_h) {
115.     w = new_w, h = new_h;
116. }
117.
118. void drawcube(){
120.     glColor3f(0.0,1.0,0.0);
121.     glVertex3f( 1.0, 1.0,-1.0);
122.     glVertex3f(-1.0, 1.0,-1.0);
123.     glVertex3f(-1.0, 1.0, 1.0);
124.     glVertex3f( 1.0, 1.0, 1.0);
125.     glEnd();
127.     glColor3f(1.0,0.5,0.0);
128.     glVertex3f( 1.0,-1.0, 1.0);
129.     glVertex3f(-1.0,-1.0, 1.0);
130.     glVertex3f(-1.0,-1.0,-1.0);
131.     glVertex3f( 1.0,-1.0,-1.0);
132.     glEnd();
134.     glColor3f(1.0,0.0,0.0);
135.     glVertex3f( 1.0, 1.0, 1.0);
136.     glVertex3f(-1.0, 1.0, 1.0);
137.     glVertex3f(-1.0,-1.0, 1.0);
138.     glVertex3f( 1.0,-1.0, 1.0);
139.     glEnd();
141.     glColor3f(1.0,1.0,0.0);
142.     glVertex3f( 1.0,-1.0,-1.0);
143.     glVertex3f(-1.0,-1.0,-1.0);
144.     glVertex3f(-1.0, 1.0,-1.0);
145.     glVertex3f( 1.0, 1.0,-1.0);
146.     glEnd();
148.     glColor3f(0.0,0.0,1.0);
149.     glVertex3f(-1.0, 1.0, 1.0);
150.     glVertex3f(-1.0, 1.0,-1.0);
151.     glVertex3f(-1.0,-1.0,-1.0);
152.     glVertex3f(-1.0,-1.0, 1.0);
153.     glEnd();
155.     glColor3f(1.0,0.0,1.0);
156.     glVertex3f( 1.0, 1.0,-1.0);
157.     glVertex3f( 1.0, 1.0, 1.0);
158.     glVertex3f( 1.0,-1.0, 1.0);
159.     glVertex3f( 1.0,-1.0,-1.0);
160.     glEnd();
161.
162. }
163.
164. void create_list_box(){
165.     box = glGenLists(1);
166.     glNewList( box, GL_COMPILE );
167.     drawcube();
168.     glEndList();
169. }
170.
171. void connect_Poly(vector <Point> cir1, vector <Point> cir2){  //соединение окружностей с помощью треугольников
172.
173.     for (int j = 0; j < cir1.size(); j+=num_poly ){
174.         float near = j + num_poly;
175.         if (j + num_poly >= cir1.size()){ near = 0; }
176.
177.         Poly tr1 = Poly(cir1[j], cir2[j], cir2[near]);
178.         tr1.CalcNormals();
179.         if (!isnan(tr1.poly_normal.x)) poly_fig.push_back(tr1);
180.
181.
182.         Poly tr2 = Poly(cir1[near], cir1[j], cir2[near]);
183.         tr2.CalcNormals();
184.         if (!isnan(tr2.poly_normal.x)) poly_fig.push_back(tr2);
185.     }
186. }
187.
188. void draw_normals(){ //рисуются нормали
189.     for (int j = 0; j < poly_fig.size(); j++){
190.         Poly trinagle = poly_fig[j];
191.
192.         for (int i = 0; i < trinagle.points.size(); i++){
193.             vertex triangle_vert = trinagle.points[i];
194.             glColor3f(1,1,1);
195.             glBegin(GL_LINES);
196.             glVertex3f(triangle_vert.coord.x, triangle_vert.coord.y, triangle_vert.coord.z);
197.             glVertex3f(triangle_vert.coord.x + triangle_vert.norm_vector.x, triangle_vert.coord.y + triangle_vert.norm_vector.y, triangle_vert.coord.z + triangle_vert.norm_vector.z);
198.             glEnd();
199.         }
200.     }
201. }
202.
203. void draw_poly(){ //отрисовка фигуры
204.
205.     for (int j = 0; j < poly_fig.size(); j++){
206.         Poly triangle = poly_fig[j];
207.         glColor3f(0,1,0);
208.         glBegin(mode);
209.
210.         for (int v = 0; v < triangle.points.size(); v++){
211.             glNormal3f(triangle.points[v].norm_vector.x, triangle.points[v].norm_vector.y, triangle.points[v].norm_vector.z);
212.             glVertex3f(triangle.points[v].coord.x, triangle.points[v].coord.y, triangle.points[v].coord.z);
213.         }
214.
215.         glEnd();
216.     }
217. }
218.
219. void countNormal(vertex &x){ //просчёт координат нормали в вершине
220.
221.     vector < Poly > all_poly_with_cur_vert;
222.     long double x_normal = 0.f;
223.     long double y_normal = 0.f;
224.     long double z_normal = 0.f;
225.
226.     for (int i = 0; i < poly_fig.size(); i++){
227.         Poly triangle = poly_fig[i];
228.         if (triangle.has_vertex(x)){
229.             all_poly_with_cur_vert.push_back(triangle);
230.         }
231.     }
232.
233.     for (int i = 0; i < all_poly_with_cur_vert.size(); i++){
234.         Poly tmp = all_poly_with_cur_vert[i];
235.         x_normal += tmp.poly_normal.x;
236.         y_normal += tmp.poly_normal.y;
237.         z_normal += tmp.poly_normal.z;
238.     }
239.
240.     x_normal = x_normal / double(all_poly_with_cur_vert.size());
241.     y_normal = y_normal / double(all_poly_with_cur_vert.size());
242.     z_normal = z_normal / double(all_poly_with_cur_vert.size());
243.     x.norm_vector.x = x_normal;
244.     x.norm_vector.y = y_normal;
245.     x.norm_vector.z = z_normal;
246.
247. }
248.
249. void rebuild(){ //построение фигуры в зависимости от шага
250.     poly_fig.clear();
251.     int i = 0;
252.     for (; i < figure.size() - change_height; i+= change_height){
253.         connect_Poly(figure[i], figure[i+change_height]);
254.     }
255.     connect_Poly(figure[i], figure[figure.size() - 1]);
256.
257.     for (int i = 0; i < poly_fig.size(); i++){
258.         countNormal(poly_fig[i].points[0]);
259.         countNormal(poly_fig[i].points[1]);
260.         countNormal(poly_fig[i].points[2]);
261.     }
262. }
263.
264. void create_list_fig(){ //как дисплейный список для нашей фигуры 7 лаба
265.     glDeleteLists(fig, 1);
266.     fig = glGenLists(1);
267.     rebuild();
268.     glNewList( fig , GL_COMPILE );
269.     draw_poly();
270.     glEndList();
271.
272.     glDeleteLists(norm, 1);
273.     norm = glGenLists(1);
274.     glNewList( norm , GL_COMPILE );
275.     draw_normals();
276.     glEndList();
277. }
278.
279. void create_circles(float a, float b, float c, float height){ //создание круга
280.     vector <Point> circle;
281.     float level = 1 + ( SQUARE(height) / SQUARE(c) );
282.     for(float i = 0; i <= 2* M_PI; i+=0.1f ) {
283.         float high_part_drob = (a*a) * (b*b) * level;
284.         float low_part_drob = ((b*b) * (cosf(i) * cosf(i))) + ((a*a) * (sinf(i) * sinf(i))) ;
285.         float r = sqrtf( high_part_drob / low_part_drob );
286.         circle.push_back(Point(cosf( i ) * r, height, sinf( i ) * r));
287.     }
288.     figure.push_back(circle);
289. }
290.
291. void create_fig(float a, float b, float c, float height_low, float height_high){ //создание фигуры через круги
292.     float h = height_low;
293.     while (h <= height_high){
294.         create_circles(a, b, c, h);
295.         h+=0.008f;
296.     }
297.     create_circles(a, b, c, h);
298. }
299.
300. float begin_s = 0.0f; //анимация
301. bool pos = true;
302.
303. bool move_1(float result_force_module){
304.     if (begin_s <= WALL_POS_1){
305.         move_X -= result_force_module;
306.         begin_s += result_force_module;
307.         return true;
308.     }
309.     return false;
310. }
311.
312. bool move_2(float result_force_module){
313.     if (begin_s >= WALL_POS_2){
314.         move_X += result_force_module;
315.         begin_s -= result_force_module;
316.         return false;
317.     }
318.     return true;
319. }
320.
321. void move_fig_to_wall(){
322.     float result_force_module = MODULE_PULLING_FORCE - MODULE_FRICTION_FORCE;
323.     if (result_force_module <= 0){
324.         glCallList(fig);
325.     }
326.     else {
327.         if (pos) pos = move_1(result_force_module);
328.         else pos = move_2(result_force_module);
329.     }
330.     glCallList(fig);
331. }
332.
333. void renderScene(void) { //
334.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
335.
337.     glTranslated(-5.0f, 0.0f,-6.0f);
338.     glCallList(box);
339.
341.     glTranslated(0.0f, 0.0f, -2.0f);
342.     glTranslated(move_X, move_Y, move_Z);
343.     glRotatef(rot_Z, 0, 0, 1);
344.     glRotatef(rot_X, 1, 0, 0);
345.     glRotatef(rot_Y, 0, 1, 0);
346.     if (animation) move_fig_to_wall();
347.     if (!animation) glCallList(fig);
348.     if(normal_flag) glCallList(norm);
350. }
351.
352. void light_enable()
353. {
355.
356.     glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
357.
358.     GLfloat amb[] = {.8f, .8f, .8f, 1.f};
359.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
360.
361.     GLfloat lightPos[] = {0.f, 0, 0.f, -10.f};
362.     glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
363.
364.     GLfloat light_amb[] = {.75f, .75f, .75f, 1.f};
365.     glLightfv(GL_LIGHT0, GL_AMBIENT, light_amb);
366.
367.     GLfloat light_diff[] = {.75f, .75f, .75f, 1.f};
368.     glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diff);
369.
370.     GLfloat light_spec[] = {7.5f, 7.5f, 7.5f, 1.f};
371.     glLightfv(GL_LIGHT0, GL_SPECULAR, light_spec);
372.
373.     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.5f);
374.     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, .5f);
376. }
377.
378. void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
379.     if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
380.         glfwSetWindowShouldClose(window, GL_TRUE);
381.     }
382.
383.     else if (key == GLFW_KEY_A && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
384.         if (num_poly == 16) {}
385.         else{ num_poly++; create_list_fig(); }
386.     }
387.
388.     else if (key == GLFW_KEY_N && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
389.         if(normal_flag) { normal_flag = false; }
390.         else { normal_flag = true; };
391.     }
392.
393.     else if (key == GLFW_KEY_X && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
394.         current_asic = X;
395.     }
396.
397.     else if (key == GLFW_KEY_Y && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
398.         current_asic = Y;
399.     }
400.
401.     else if (key == GLFW_KEY_Z && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
402.         current_asic = Z;
403.     }
404.
405.     else if (key == GLFW_KEY_W && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
406.         if (change_height == 1) {}
407.         else { change_height = change_height - 1; create_list_fig();}
408.     }
409.
410.     else if (key == GLFW_KEY_S && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
411.         change_height = change_height + 1; create_list_fig();
412.     }
413.
414.     else if (key == GLFW_KEY_M && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
415.         if (mode == GL_TRIANGLES){ mode = GL_LINE_LOOP; create_list_fig();}
416.         else { mode = GL_TRIANGLES; create_list_fig();}
417.     }
418.
419.     else if (key == GLFW_KEY_L && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
420.         if (light_on){
421.             glDisable(GL_LIGHTING);
422.             glDisable(GL_LIGHT0);
423.             light_on = false;
424.         }
425.         else {
426.             glEnable(GL_LIGHTING);
427.             glEnable(GL_LIGHT0);
428.             light_enable();
429.             light_on = true;
430.         }
431.     }
432.
433.
434.     else if (key == GLFW_KEY_F && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
435.         if (animation) { animation = false; }
436.         else { animation = true; }
437.     }
438.
439.     else if (key == GLFW_KEY_D && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
440.         if (num_poly == 1) {}
441.         else {num_poly--; create_list_fig();}
442.     }
443.
444.     else if (key == GLFW_KEY_LEFT && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
445.         if (current_asic == Z) { move_Z-= 0.1f; }
446.         if (current_asic == X) { move_X-= 0.1f; }
447.         if (current_asic == Y) { move_Y-= 0.1f; }
448.     }
449.
450.     else if (key == GLFW_KEY_RIGHT && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
451.         if (current_asic == Z) { move_Z+= 0.1f; }
452.         if (current_asic == X) { move_X+= 0.1f; }
453.         if (current_asic == Y) { move_Y+= 0.1f; }
454.     }
455.
456.     else if (key == GLFW_KEY_UP && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
457.         if (current_asic == Z) { rot_Z+= 0.4f; }
458.         if (current_asic == X) { rot_X+= 0.4f; }
459.         if (current_asic == Y) { rot_Y+= 0.4f; }
460.     }
461.
462.     else if (key == GLFW_KEY_DOWN && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
463.         if (current_asic == Z) { rot_Z-= 0.4f; }
464.         if (current_asic == X) { rot_X-= 0.4f; }
465.         if (current_asic == Y) { rot_Y-= 0.4f; }
466.     }
467.
468.
469. }
470.
471. void projection(GLint width, GLint height) { //как я хочу видеть фигуру
472.
473.     GLfloat k = 0.07;
474.
475.     GLfloat project[] = {
476.             1.f, 0.f, 0.f, 0.0f,
477.             0.f, 1.f, 0.f, 0.f,
478.             0.f, 0.f, 1.f, 0.0f,
479.             0.f, 0.f, 0.f, 1.f};
480.
481.     glMatrixMode(GL_PROJECTION);
483.
484.     glMultMatrixf(project);
485.
486.     glOrtho(-w * k / 2, w * k / 2, -h * k / 2,
487.             h * k / 2, -(w * k + h * k) / 4, (w * k + h * k) / 4);
488.
489. }
490.
491. int main(int argc, char **argv) {
492.     float a = 3.0f;
493.     float b = 2.0f;
494.     float c = 0.1f;
495.     float z_low = -5.0f;
496.     float z_high = 5.0f;
497.
498.     if (!glfwInit()) {
499.         fprintf(stderr, "Failed to initialize GLFW\n");
500.         exit(EXIT_FAILURE);
501.     }
502.
503.     GLFWwindow
504.             *window = glfwCreateWindow(800, 800, "Lab6", nullptr, nullptr);
505.     if (!window) {
506.         fprintf(stderr, "Failed to open GLFW window.\n");
507.         glfwTerminate();
508.         exit(EXIT_FAILURE);
509.     }
510.
511.     glfwMakeContextCurrent(window);
512.     glfwSetKeyCallback(window, key_callback);
513.     glfwSetWindowSizeCallback(window, resize_callback);
514.
515.     glfwGetFramebufferSize(window, &w, &h);
516.
517.     create_fig(a, b, c, z_low, z_high);
518.     create_list_box();
519.     create_list_fig();
520.
521.     glEnable(GL_DEPTH_TEST);
522.     glDepthFunc(GL_LEQUAL);
523.     glEnable(GL_NORMALIZE);
524.
525.
526.     while (!glfwWindowShouldClose(window)) {
527.
528.         glClearColor(0, 0, 0, 0);
529.         glClear(GL_COLOR_BUFFER_BIT);
530.         glClear(GL_DEPTH_BUFFER_BIT);
531.
532.         glViewport(0, 0, w, h);
533.         projection(w, h);
534.         glMatrixMode(GL_MODELVIEW);
535.         renderScene();
536.
537.         glfwPollEvents();
538.         glfwSwapBuffers(window);
539.     }
540.     glfwDestroyWindow(window);
541.     glfwTerminate();
542. }
543.
RAW Paste Data