Advertisement
anik11556

graphicsLab

Apr 28th, 2024
693
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.48 KB | None | 0 0
  1. import glfw
  2. from OpenGL.GL import *
  3. import math
  4.  
  5. W, H = 800, 800
  6.  
  7. colors= [[255,255,255],
  8. [255,0,0],
  9. [0,255,0],
  10. [0,0,255],
  11. [255,255,0],
  12. [0,255,255],
  13. [255,0,255],
  14. [127,127,127]]
  15.  
  16. def get_zone(x0, y0, x1, y1):
  17.     dx= x1-x0
  18.     dy= y1-y0
  19.  
  20.     if dx>=0 and dy>=0:
  21.         if dx > dy:
  22.             return 0
  23.         return 1
  24.  
  25.     elif dx>=0 and dy<0:
  26.         if dx > abs(dy):
  27.             return 7
  28.         return 6
  29.  
  30.     elif dx<0 and dy>=0:
  31.         if abs(dx) > dy :
  32.             return 3
  33.         return 2
  34.  
  35.     else:
  36.         if abs(dx)>abs(dy):
  37.             return 4
  38.         return 5
  39.  
  40. def return_back(zone, x, y): # zone3 to all zones
  41.     if zone == 0:
  42.         return -x, y
  43.     elif zone == 1:
  44.         return y, -x
  45.     elif zone == 2:
  46.         return -y, -x
  47.     elif zone == 3:
  48.         return x, y
  49.     elif zone == 4:
  50.         return x, -y
  51.     elif zone == 5:
  52.         return -y, x
  53.     elif zone == 6:
  54.         return y, x
  55.     else:
  56.         return -x, -y
  57.    
  58. def allZone_to_3(zone, x, y): #all zone to zone3
  59.     if zone == 0:
  60.         return -x, y
  61.     elif zone == 1:
  62.         return -y, x
  63.     elif zone == 2:
  64.         return -y, -x
  65.     elif zone == 3:
  66.         return x, y
  67.     elif zone == 4:
  68.         return x, -y
  69.     elif zone == 5:
  70.         return y, -x
  71.     elif zone == 6:
  72.         return y, x
  73.     else:
  74.         return -x, -y
  75.  
  76. def draw_axes():
  77.     glColor3ub(127, 127, 127)
  78.     glBegin(GL_LINES)
  79.     glVertex2f(-W/2, 0)
  80.     glVertex2f(W/2-1, 0)
  81.     glVertex2f(0, -H/2)
  82.     glVertex2f(0, H/2-1)
  83.     glEnd()
  84.  
  85. def draw_pixel(x, y, zone):
  86.     x, y = return_back(zone, x, y)
  87.     glVertex2f(x, y)
  88.  
  89. def draw_pixel_2(x,y):
  90.     glVertex2f(x, y)
  91.  
  92. def draw_line_3(x0, y0, x1, y1, zone):
  93.     dx = x1 - x0
  94.     dy = y1 - y0
  95.     x = x0
  96.     y = y0
  97.     d = -2 * dx + dy
  98.     del_w = -2 * dy
  99.     del_nw = -2 * (dx + dy)
  100.     draw_pixel(x, y, zone)
  101.     while (x > x1):
  102.         if (d < 0):
  103.             d += del_nw
  104.             x -= 1
  105.             y += 1
  106.         else:
  107.             d += del_w
  108.             x -= 1
  109.         draw_pixel(x, y, zone)
  110.        
  111.        
  112. def read_polygon_file(filename):
  113.     points = []
  114.     with open(filename, 'r') as file:
  115.         num_vertices = int(file.readline().strip())
  116.         for _ in range(num_vertices):
  117.             x, y = map(int, file.readline().strip().split(','))
  118.             points.append((x, y))
  119.     return points
  120.  
  121.  
  122. def construct_edge_table(points):
  123.     edges = {}
  124.    
  125.     for i in range(1,len(points)):
  126.         edges[i-1] = [points[i],points[i-1]]
  127.         edges[i-1] = sorted(edges[i-1],key=lambda x: (x[1],x[0]))
  128.        
  129.         if i==len(points)-1:
  130.             edges[i] = [points[i],points[0]]
  131.             edges[i] = sorted(edges[i],key=lambda x: (x[1],x[0]))
  132.  
  133.  
  134.  
  135.     _,y_min = min(points,key=lambda x : (x[1],x[0]))
  136.     x_of_y_max,y_max = max(points,key=lambda x : (x[1],x[0]))
  137.  
  138.  
  139.     def slope(x0,y0,x1,y1):
  140.         if (x1-x0)==0:
  141.             return 0
  142.         return (y1-y0)/(x1-x0)
  143.  
  144.     edge_table = {}
  145.     for i in range(y_min,y_max):
  146.         edge_vertexs = []
  147.         for key,edge in edges.items():
  148.            
  149.             first_vertex,second_vertex = edge[0],edge[1]
  150.             x0,y0 = first_vertex
  151.             x1,y1 = second_vertex
  152.             if y0==i and y0!=y1:
  153.                 m = slope(x0,y0,x1,y1)
  154.                 if m==0:
  155.                     edge_vertexs.append((y1,x0,0))
  156.                 else:
  157.                     edge_vertexs.append((y1,x0,1/m))
  158.                    
  159.        
  160.         if i!=y_min:
  161.             previous_edge_vertexs = edge_table[i-1]
  162.             for triplet in previous_edge_vertexs:
  163.                 prev_y_max, prev_x_of_y_min, prev_slope = triplet
  164.                 if prev_y_max!=i:
  165.                     prev_x_of_y_min+=prev_slope
  166.                     edge_vertexs.append((prev_y_max,prev_x_of_y_min,prev_slope))
  167.        
  168.        
  169.         edge_vertexs = sorted(edge_vertexs,key = lambda x : (x[1],x[0]))
  170.        
  171.         edge_table[i] = edge_vertexs
  172.  
  173.     return y_min,y_max,edge_table,points,edges
  174.  
  175.  
  176. def draw_polygon_vertex(points):
  177.     glPointSize(6)
  178.     glBegin(GL_POINTS)
  179.     for point in points:
  180.         glColor3ub(0,255,0)
  181.         draw_pixel_2(point[0],point[1])
  182.     glEnd()
  183.     glPointSize(1)
  184.    
  185. def draw_edges(edges):
  186.     glPointSize(3)
  187.     glBegin(GL_POINTS)
  188.     for key,edge in edges.items():
  189.         x0,y0 = edge[0]
  190.         x1,y1 = edge[1]
  191.         zone= get_zone(x0, y0, x1, y1)
  192.         x0, y0 = allZone_to_3(zone, x0, y0)      
  193.         x1, y1 = allZone_to_3(zone, x1, y1)      
  194.  
  195.         glColor3ub(255,255,0)
  196.         draw_line_3(x0, y0, x1, y1, zone)
  197.     glEnd()
  198.     glPointSize(1)
  199.    
  200.  
  201. def draw_boundary_pixels(edges):
  202.     glPointSize(6)
  203.     glBegin(GL_POINTS)
  204.     for key, edge in edges.items():
  205.         first_vertex, second_vertex = edge[0], edge[1]
  206.         x0, y0 = first_vertex
  207.         x1, y1 = second_vertex
  208.        
  209.         # Calculate the number of pixels needed to traverse the edge
  210.         num_pixels = max(abs(x1 - x0), abs(y1 - y0)) + 1
  211.        
  212.         # Calculate the step size for x and y to move between pixels
  213.         dx = (x1 - x0) / num_pixels
  214.         dy = (y1 - y0) / num_pixels
  215.        
  216.         # Draw all the pixels along the edge
  217.         for i in range(num_pixels):
  218.             pixel_x = round(x0 + i * dx)
  219.             pixel_y = round(y0 + i * dy)
  220.             glColor3ub(0, 0, 255)  # Set color for the boundary pixels
  221.             draw_pixel_2(pixel_x, pixel_y)  # Draw the boundary pixel
  222.  
  223.     glEnd()
  224.     glPointSize(1)
  225.  
  226.  
  227. def draw_polygon_fill(y_min,y_max,edge_table):
  228.     glBegin(GL_POINTS)
  229.     for y in range(y_min,y_max):
  230.         i = 0
  231.         while i<len(edge_table[y]):
  232.             first_triplet = edge_table[y][i]
  233.             second_triplet = edge_table[y][i+1]
  234.            
  235.             x0,y0 = first_triplet[1],y
  236.             x1,y1 = second_triplet[1],y
  237.                  
  238.             zone= get_zone(x0, y0, x1, y1)
  239.             x0, y0 = allZone_to_3(zone, x0, y0)      
  240.             x1, y1 = allZone_to_3(zone, x1, y1)      
  241.  
  242.             glColor3ub(255,255,0)
  243.  
  244.             draw_line_3(x0, y, x1, y, zone)
  245.                
  246.             i+=2
  247.    
  248.     glEnd()
  249.  
  250.  
  251. draw_vertex_flag = True
  252. draw_boundary_pixel_flag = False
  253. draw_polygon_fill_flag = False
  254. y_min,y_max,edge_table,points,edges = 0,0,{},[],{}
  255.  
  256.  
  257.  
  258. def rotate_point(point, angle):
  259.     x, y = point
  260.     angle_rad = math.radians(angle)
  261.     new_x = x * math.cos(angle_rad) - y * math.sin(angle_rad)
  262.     new_y = x * math.sin(angle_rad) + y * math.cos(angle_rad)
  263.     return (new_x, new_y)
  264.  
  265. def rotate_polygon(points, angle):
  266.     cx = sum(x for x, _ in points) / len(points)
  267.     cy = sum(y for _, y in points) / len(points)
  268.    
  269.     translated_points = [(x - cx, y - cy) for x, y in points]
  270.    
  271.     rotated_points = [rotate_point(point, angle) for point in translated_points]
  272.    
  273.     new_points = [(round(x + cx), round(y + cy)) for x, y in rotated_points]
  274.    
  275.     return new_points
  276.  
  277. def key_callback(window, key, scancode, action, mods):
  278.     global draw_vertex_flag, draw_boundary_pixel_flag, draw_polygon_fill_flag
  279.     global y_min, y_max, edge_table, points, edges
  280.    
  281.     mouse_x, mouse_y = glfw.get_cursor_pos(window)
  282.     window_width, window_height = glfw.get_window_size(window)
  283.     if mouse_x >= 0 and mouse_x < window_width and mouse_y >= 0 and mouse_y < window_height:
  284.         if action == glfw.PRESS:
  285.             if key == glfw.KEY_KP_0:
  286.                 draw_vertex_flag = True
  287.                 draw_boundary_pixel_flag = False
  288.                 draw_polygon_fill_flag = False
  289.             elif key == glfw.KEY_KP_1:
  290.                 draw_vertex_flag = False
  291.                 draw_boundary_pixel_flag = True
  292.                 draw_polygon_fill_flag = False
  293.             elif key == glfw.KEY_KP_2:
  294.                 draw_vertex_flag = False
  295.                 draw_boundary_pixel_flag = False
  296.                 draw_polygon_fill_flag = True
  297.             elif key == glfw.KEY_LEFT:
  298.                 points = rotate_polygon(points, 5)
  299.                 y_min, y_max, edge_table, points, edges = construct_edge_table(points)
  300.             elif key == glfw.KEY_RIGHT:
  301.                 points = rotate_polygon(points, -5)
  302.                 y_min, y_max, edge_table, points, edges = construct_edge_table(points)
  303.  
  304.  
  305. def main():
  306.     global draw_vertex_flag,draw_boundary_pixel_flag,draw_polygon_fill_flag
  307.     global y_min,y_max,edge_table,points,edges
  308.    
  309.     if not glfw.init():
  310.         return
  311.  
  312.     Window = glfw.create_window(W, H, "Lab 3", None, None)
  313.     if not Window:
  314.         glfw.terminate()
  315.         return
  316.  
  317.     glfw.make_context_current(Window)
  318.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  319.    
  320.     glMatrixMode(GL_PROJECTION)
  321.     glLoadIdentity()
  322.     glOrtho(-W/2, W/2-1, -H/2, H/2-1, -1,1)
  323.    
  324.     glMatrixMode(GL_MODELVIEW)
  325.     glLoadIdentity()
  326.  
  327.     points = read_polygon_file("vertex.txt")
  328.     y_min, y_max, edge_table,points,edges = construct_edge_table(points)
  329.    
  330.  
  331.     glfw.set_key_callback(Window,key_callback)
  332.  
  333.     while not glfw.window_should_close(Window):
  334.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  335.         glfw.poll_events()
  336.        
  337.         draw_axes()
  338.        
  339.        
  340.         if draw_vertex_flag:
  341.             draw_polygon_vertex(points)
  342.         elif draw_boundary_pixel_flag:
  343.             draw_boundary_pixels(edges)
  344.         elif draw_polygon_fill_flag:
  345.             draw_polygon_fill(y_min, y_max, edge_table)
  346.        
  347.        
  348.         glfw.swap_buffers(Window)
  349.  
  350.     glfw.terminate()
  351.  
  352. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement