<legend id='LSVle'><style id='LSVle'><dir id='LSVle'><q id='LSVle'></q></dir></style></legend>

    <tfoot id='LSVle'></tfoot>
  • <small id='LSVle'></small><noframes id='LSVle'>

      • <bdo id='LSVle'></bdo><ul id='LSVle'></ul>

        <i id='LSVle'><tr id='LSVle'><dt id='LSVle'><q id='LSVle'><span id='LSVle'><b id='LSVle'><form id='LSVle'><ins id='LSVle'></ins><ul id='LSVle'></ul><sub id='LSVle'></sub></form><legend id='LSVle'></legend><bdo id='LSVle'><pre id='LSVle'><center id='LSVle'></center></pre></bdo></b><th id='LSVle'></th></span></q></dt></tr></i><div id='LSVle'><tfoot id='LSVle'></tfoot><dl id='LSVle'><fieldset id='LSVle'></fieldset></dl></div>
      1. Pygame 围绕轴旋转立方体

        时间:2023-09-11

            <bdo id='HKEr7'></bdo><ul id='HKEr7'></ul>
            <i id='HKEr7'><tr id='HKEr7'><dt id='HKEr7'><q id='HKEr7'><span id='HKEr7'><b id='HKEr7'><form id='HKEr7'><ins id='HKEr7'></ins><ul id='HKEr7'></ul><sub id='HKEr7'></sub></form><legend id='HKEr7'></legend><bdo id='HKEr7'><pre id='HKEr7'><center id='HKEr7'></center></pre></bdo></b><th id='HKEr7'></th></span></q></dt></tr></i><div id='HKEr7'><tfoot id='HKEr7'></tfoot><dl id='HKEr7'><fieldset id='HKEr7'></fieldset></dl></div>
            <tfoot id='HKEr7'></tfoot>

            <legend id='HKEr7'><style id='HKEr7'><dir id='HKEr7'><q id='HKEr7'></q></dir></style></legend>
              <tbody id='HKEr7'></tbody>
              1. <small id='HKEr7'></small><noframes id='HKEr7'>

                  本文介绍了Pygame 围绕轴旋转立方体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  我一直在玩旋转立方体的例子


                  最小示例:

                  导入数学导入pygamedef 项目(向量,w,h,fov,距离):因子 = math.atan(fov/2 * math.pi/180)/(距离 + vector.z)x = 矢量.x * 因子 * w + w/2y = -vector.y * 因子 * w + h/2返回 pygame.math.Vector3(x, y, vector.z)def rotate_vertices(顶点,角度,轴):return [v.rotate(angle, axis) for v in vertices]def scale_vertices(顶点,s):返回 [pygame.math.Vector3(v[0]*s[0], v[1]*s[1], v[2]*s[2]) for v in vertices]def translate_vertices(顶点,t):return [v + pygame.math.Vector3(t) for v in vertices]def project_vertices(顶点,w,h,fov,距离):return [project(v, w, h, fov, distance) for v in vertices]类网格():def __init__(自我,顶点,面):self.__vertices = [pygame.math.Vector3(v) for v in vertices]self.__faces = 面孔def旋转(自我,角度,轴):self.__vertices = rotate_vertices(self.__vertices, 角度, 轴)def 比例(自我,s):self.__vertices = scale_vertices(self.__vertices, s)定义翻译(自我,t):self.__vertices = translate_vertices(self.__vertices, t)def calculate_average_z(自我,顶点):return [(i, sum([vertices[j].z for j in f])/len(f)) for i, f in enumerate(self.__faces)]def get_face(自我,索引):返回 self.__faces[index]def get_vertices(self):返回自我.__顶点def create_polygon(self, face, vertices):返回 [(vertices[i].x, vertices[i].y) for i in [*face, face[0]]]课堂场景:def __init__(self, mehses, fov, distance):self.meshes = mehsesself.fov = fovself.distance = 距离self.euler_angles = [0, 0, 0]def transform_vertices(自我,顶点,宽度,高度):转换的_vertices = 顶点axis_list = [(1, 0, 0), (0, 1, 0), (0, 0, 1)]对于角度,轴反转(list(zip(list(self.euler_angles),axis_list))):变换顶点 = 旋转顶点(变换顶点,角度,轴)转换顶点 = 项目顶点(转换顶点,宽度,高度,self.fov,self.distance)返回transformed_verticesdef 绘制(自我,表面):多边形 = []对于 self.meshes 中的网格:transform_vertices = self.transform_vertices(mesh.get_vertices(), *surface.get_size())avg_z = mesh.calculate_average_z(transformed_vertices)对于 avg_z 中的 z:#for z in sorted(avg_z, key=lambda x: x[1], reverse=True):点列表 = mesh.create_polygon(mesh.get_face(z[0]),transformed_vertices)多边形.附加((点列表,z [1]))#pygame.draw.polygon(surface, (128, 128, 192), pointlist)#pygame.draw.polygon(surface, (0, 0, 0), pointlist, 3)对于排序中的多边形(多边形,键= lambda x:x [1],反向=真):pygame.draw.polygon(表面, (128, 128, 192), poly[0])pygame.draw.polygon(surface, (0, 0, 0), poly[0], 3)顶点 = [(-1,-1,1), (1,-1,1), (1,1,1), (-1,1,1), (-1,-1,-1),(1,-1,-1), (1,1,-1), (-1,1,-1)]面 = [(0,1,2,3), (1,5,6,2), (5,4,7,6), (4,0,3,7), (3,2,6,7), (1,0,4,5)]cube_origins = [(-1, -1, 0), (0, -1, 0), (1, -1, 0), (1, 0, 0), (1, 1, 0), (0,1, 0), (-1, 1, 0), (-1, 0, 0)]网格 = []对于 cube_origins 中的原点:立方体=网格(顶点,面)立方体.scale((0.5, 0.5, 0.5))cube.translate(原点)网格.附加(立方体)场景 = 场景(网格,90, 5)pygame.init()窗口 = pygame.display.set_mode((400, 300))时钟 = pygame.time.Clock()运行=真运行时:时钟.tick(60)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 假window.fill((255, 255, 255))场景.draw(窗口)场景.euler_angles[1] += 1pygame.display.flip()pygame.quit()

                  I have been playing around with the example of a rotating cube here. I have generated 2 cubes that should rotate around the Y-axis. However, it doesn't seem to work as expected and I can't figure out what the problem of it is.

                  Here is a working code example:

                  import sys
                  import math
                  import pygame
                  
                  from pygame.math import Vector3
                  from enum import Enum
                  
                  
                  class Color(Enum):
                      BLACK = (0, 0, 0)
                      SILVER = (192,192,192)
                  
                  
                  class Cube():
                  
                      def __init__(self, vectors, screen_width, screen_height, initial_angle=25):
                          self._vectors = vectors
                          self._angle = initial_angle
                          self._screen_width = screen_width
                          self._screen_height = screen_height
                  
                          # Define the vectors that compose each of the 6 faces
                          self._faces  = [(0,1,2,3),
                                         (1,5,6,2),
                                         (5,4,7,6),
                                         (4,0,3,7),
                                         (0,4,5,1),
                                         (3,2,6,7)]
                  
                          self._setup_initial_positions(initial_angle)
                  
                      def _setup_initial_positions(self, angle):
                          tmp = []
                          for vector in self._vectors:
                              rotated_vector = vector.rotate_x(angle).rotate_y(angle)#.rotateZ(self.angle)
                              tmp.append(rotated_vector)
                  
                          self._vectors = tmp
                  
                      def transform_vectors(self, new_angle):
                          # It will hold transformed vectors.
                          transformed_vectors = []
                  
                          for vector in self._vectors:
                              # Rotate the point around X axis, then around Y axis, and finally around Z axis.
                              mod_vector = vector.rotate_y(new_angle)
                              # Transform the point from 3D to 2D
                              mod_vector = self._project(mod_vector, self._screen_width, self._screen_height, 256, 4)
                              # Put the point in the list of transformed vectors
                              transformed_vectors.append(mod_vector)
                  
                          return transformed_vectors
                  
                      def _project(self, vector, win_width, win_height, fov, viewer_distance):
                          factor = fov / (viewer_distance + vector.z)
                          x = vector.x * factor + win_width / 2
                          y = -vector.y * factor + win_height / 2
                          return Vector3(x, y, vector.z)
                  
                      def calculate_average_z(self, vectors):
                          avg_z = []
                          for i, face in enumerate(self._faces):
                              # for each point of a face calculate the average z value
                              z = (vectors[face[0]].z + 
                                   vectors[face[1]].z + 
                                   vectors[face[2]].z + 
                                   vectors[face[3]].z) / 4.0
                              avg_z.append([i, z])
                  
                          return avg_z
                  
                      def get_face(self, index):
                          return self._faces[index]
                  
                      def create_polygon(self, face, transformed_vectors):
                          return [(transformed_vectors[face[0]].x, transformed_vectors[face[0]].y), 
                                  (transformed_vectors[face[1]].x, transformed_vectors[face[1]].y),
                                  (transformed_vectors[face[2]].x, transformed_vectors[face[2]].y),
                                  (transformed_vectors[face[3]].x, transformed_vectors[face[3]].y),
                                  (transformed_vectors[face[0]].x, transformed_vectors[face[0]].y)]
                  
                  
                  class Simulation:
                      def __init__(self, win_width=640, win_height=480):
                          pygame.init()
                  
                          self.screen = pygame.display.set_mode((win_width, win_height))
                  
                          self.clock = pygame.time.Clock()
                  
                          cube = Cube([
                              Vector3(0, 0.5, -0.5),
                              Vector3(0.5, 0.5, -0.5),
                              Vector3(0.5, 0, -0.5),
                              Vector3(0, 0, -0.5),
                              Vector3(0, 0.5, 0),
                              Vector3(0.5, 0.5, 0),
                              Vector3(0.5, 0, 0),
                              Vector3(0, 0, 0)
                          ], win_width, win_height)
                  
                          cube2 = Cube([
                              Vector3(0.5, 0.5, -0.5),
                              Vector3(1, 0.5, -0.5),
                              Vector3(1, 0, -0.5),
                              Vector3(0.5, 0, -0.5),
                              Vector3(0.5, 0.5, 0),
                              Vector3(1, 0.5, 0),
                              Vector3(1, 0, 0),
                              Vector3(0.5, 0, 0)
                          ], win_width, win_height)
                  
                          self._angle = 30
                  
                          self._cubes = [cube, cube2]
                  
                      def run(self):
                          while True:
                              for event in pygame.event.get():
                                  if event.type == pygame.QUIT:
                                      pygame.quit()
                                      sys.exit()
                  
                              self.clock.tick(50)
                              self.screen.fill(Color.BLACK.value)
                  
                              for cube in self._cubes:
                                  transformed_vectors = cube.transform_vectors(self._angle)
                                  avg_z = cube.calculate_average_z(transformed_vectors)
                  
                                  # Draw the faces using the Painter's algorithm:
                                  # Distant faces are drawn before the closer ones.
                                  for avg_z in sorted(avg_z, key=lambda x: x[1], reverse=True):
                                      face_index = avg_z[0]
                                      face = cube._faces[face_index]
                                      pointlist = cube.create_polygon(face, transformed_vectors)
                  
                                      pygame.draw.polygon(self.screen, Color.SILVER.value,pointlist)
                                      pygame.draw.polygon(self.screen, Color.BLACK.value, pointlist, 3)
                                      # break 
                  
                              self._angle += 1
                  
                              pygame.display.flip()
                  
                  if __name__ == "__main__":
                      Simulation().run()
                  

                  Both cubes should rotate around the Y-axis in this example. For the future I'd like to have a solution so they can rotate around any axis.

                  解决方案

                  It is not sufficient to sort the faces of each cube separately by its depth. You've to sort the faces of all objects of the entire scene by its depth.

                  Create a list of tuples, which consists of the projected (transformed) points ofa face and the average depth (z value):

                  polygons = []
                  for cube in self._cubes:
                      transformed_vectors = cube.transform_vectors(self._angle)
                      avg_z = cube.calculate_average_z(transformed_vectors)
                      for z in avg_z:
                          face_index = z[0]
                          face = cube._faces[face_index]
                          pointlist = cube.create_polygon(face, transformed_vectors)
                          polygons.append((pointlist, z[1]))
                  

                  Draw the faces of all objects in (reverse) sorted order:

                  for poly in sorted(polygons, key=lambda x: x[1], reverse=True):
                      pygame.draw.polygon(self.screen, Color.SILVER.value,poly[0])
                      pygame.draw.polygon(self.screen, Color.BLACK.value, poly[0], 3)
                  


                  Minimal example:

                  import math
                  import pygame
                  
                  def project(vector, w, h, fov, distance):
                      factor = math.atan(fov / 2 * math.pi / 180) / (distance + vector.z)
                      x = vector.x * factor * w + w / 2
                      y = -vector.y * factor * w + h / 2
                      return pygame.math.Vector3(x, y, vector.z)
                  
                  def rotate_vertices(vertices, angle, axis):
                      return [v.rotate(angle, axis) for v in vertices]
                  def scale_vertices(vertices, s):
                      return [pygame.math.Vector3(v[0]*s[0], v[1]*s[1], v[2]*s[2]) for v in vertices]
                  def translate_vertices(vertices, t):
                      return [v + pygame.math.Vector3(t) for v in vertices]
                  def project_vertices(vertices, w, h, fov, distance):
                      return [project(v, w, h, fov, distance) for v in vertices]
                  
                  class Mesh():
                  
                      def __init__(self, vertices, faces):
                          self.__vertices = [pygame.math.Vector3(v) for v in vertices]
                          self.__faces = faces
                  
                      def rotate(self, angle, axis):
                          self.__vertices = rotate_vertices(self.__vertices, angle, axis)
                      def scale(self, s):
                          self.__vertices = scale_vertices(self.__vertices, s)
                      def translate(self, t):
                          self.__vertices = translate_vertices(self.__vertices, t)
                  
                      def calculate_average_z(self, vertices):
                          return [(i, sum([vertices[j].z for j in f]) / len(f)) for i, f in enumerate(self.__faces)]
                  
                      def get_face(self, index):
                          return self.__faces[index]
                      def get_vertices(self):
                          return self.__vertices
                  
                      def create_polygon(self, face, vertices):
                          return [(vertices[i].x, vertices[i].y) for i in [*face, face[0]]]
                         
                  class Scene:
                      def __init__(self, mehses, fov, distance):
                          self.meshes = mehses
                          self.fov = fov
                          self.distance = distance 
                          self.euler_angles = [0, 0, 0]
                  
                      def transform_vertices(self, vertices, width, height):
                          transformed_vertices = vertices
                          axis_list = [(1, 0, 0), (0, 1, 0), (0, 0, 1)]
                          for angle, axis in reversed(list(zip(list(self.euler_angles), axis_list))):
                              transformed_vertices = rotate_vertices(transformed_vertices, angle, axis)
                          transformed_vertices = project_vertices(transformed_vertices, width, height, self.fov, self.distance)
                          return transformed_vertices
                  
                      def draw(self, surface):
                          
                          polygons = []
                          for mesh in self.meshes:
                              transformed_vertices = self.transform_vertices(mesh.get_vertices(), *surface.get_size())
                              avg_z = mesh.calculate_average_z(transformed_vertices)
                              for z in avg_z:
                              #for z in sorted(avg_z, key=lambda x: x[1], reverse=True):
                                  pointlist = mesh.create_polygon(mesh.get_face(z[0]), transformed_vertices)
                                  polygons.append((pointlist, z[1]))
                                  #pygame.draw.polygon(surface, (128, 128, 192), pointlist)
                                  #pygame.draw.polygon(surface, (0, 0, 0), pointlist, 3)
                  
                          for poly in sorted(polygons, key=lambda x: x[1], reverse=True):
                              pygame.draw.polygon(surface, (128, 128, 192), poly[0])
                              pygame.draw.polygon(surface, (0, 0, 0), poly[0], 3)
                          
                  
                  vertices = [(-1,-1,1), (1,-1,1), (1,1,1), (-1,1,1), (-1,-1,-1), (1,-1,-1), (1,1,-1), (-1,1,-1)]
                  faces = [(0,1,2,3), (1,5,6,2), (5,4,7,6), (4,0,3,7), (3,2,6,7), (1,0,4,5)]
                  
                  cube_origins = [(-1, -1, 0), (0, -1, 0), (1, -1, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0), (-1, 1, 0), (-1, 0, 0)]
                  meshes = []
                  for origin in cube_origins:
                      cube = Mesh(vertices, faces)
                      cube.scale((0.5, 0.5, 0.5))
                      cube.translate(origin)
                      meshes.append(cube)
                  
                  scene = Scene(meshes, 90, 5)
                  
                  pygame.init()
                  window = pygame.display.set_mode((400, 300))
                  clock = pygame.time.Clock()
                  
                  run = True
                  while run:
                      clock.tick(60)
                      for event in pygame.event.get():
                          if event.type == pygame.QUIT:
                              run = False
                  
                      window.fill((255, 255, 255))
                      scene.draw(window)
                      scene.euler_angles[1] += 1
                      pygame.display.flip()
                  
                  pygame.quit()
                  

                  这篇关于Pygame 围绕轴旋转立方体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:如何使用 PIL 生成圆形缩略图? 下一篇:python中好的几何库?

                  相关文章

                  最新文章

                  <legend id='a0alX'><style id='a0alX'><dir id='a0alX'><q id='a0alX'></q></dir></style></legend>

                  1. <tfoot id='a0alX'></tfoot>
                      <bdo id='a0alX'></bdo><ul id='a0alX'></ul>

                    <small id='a0alX'></small><noframes id='a0alX'>

                  2. <i id='a0alX'><tr id='a0alX'><dt id='a0alX'><q id='a0alX'><span id='a0alX'><b id='a0alX'><form id='a0alX'><ins id='a0alX'></ins><ul id='a0alX'></ul><sub id='a0alX'></sub></form><legend id='a0alX'></legend><bdo id='a0alX'><pre id='a0alX'><center id='a0alX'></center></pre></bdo></b><th id='a0alX'></th></span></q></dt></tr></i><div id='a0alX'><tfoot id='a0alX'></tfoot><dl id='a0alX'><fieldset id='a0alX'></fieldset></dl></div>