def load_line(): a = BasicEntity.BasicEntity() a.link_list = [[0, 1], [0, 2]] a.point_list = [ Space.Point(100, 0, 0), Space.Point(-100, -100, 200), Space.Point(-100, -100, 100) ] return [a]
def canvas_plane(self): player = self.world.player d = -(player.face_to.x * player.location.x + player.face_to.y * player.location.y + player.face_to.z * player.location.y + math.sqrt(player.face_to.modulo_fang())) return Space.Plane(player.face_to.x, player.face_to.y, player.face_to.z, d)
def get_new_xy_vector(self): player = self.world.player canvas_zero = player.location + player.face_to x_vector = Space.Vector(player.face_to.y, -player.face_to.x, 0).to_modulo_one() y_vector = Space.Vector(-player.face_to.z * player.face_to.x, -player.face_to.z * player.face_to.y, player.face_to.y**2 + player.face_to.x**2).to_modulo_one() # y > 0 时 x 轴正方向为 x 增大方向 # if ((math.cos(player.face_to.angle_x) > 0 and x_vector.x < 0) # or (math.cos(player.face_to.angle_x) < 0 and x_vector.x > 0)): # x_vector.reverse() # if y_vector.z < 0: # y_vector.reverse() return x_vector, y_vector, canvas_zero
def plane_cross_line(plane_point, plane_vector, point_a, point_b): mol = (plane_point.x - point_b.x) * plane_vector.x + \ (plane_point.y - point_b.y) * plane_vector.y + \ (plane_point.z - point_b.z) * plane_vector.z de = plane_vector.x * (point_a.x - point_b.x) + \ plane_vector.y * (point_a.y - point_b.y) + \ plane_vector.z * (point_a.z - point_b.z) k = mol / de if de != 0 else 0 # k = k if k > 0 else -k # print("k", k, "x", point_a.x - point_b.x, "y", point_a.y - point_b.y, "z", point_a.z - point_b.z) cross_point_x = k * (point_a.x - point_b.x) + point_b.x cross_point_y = k * (point_a.y - point_b.y) + point_b.y cross_point_z = k * (point_a.z - point_b.z) + point_b.z return Space.Point(cross_point_x, cross_point_y, cross_point_z)
def get_final_cross_point(self, point_start, point_cross, is_not_among_point): # print("point_start", point_start, "point_cross", point_cross) # if (point_cross.x > Set.screen_width or point_cross.x < 0) and \ # (point_cross.y > Set.screen_height or point_cross.y < 0): # return point_cross k = self.get_line_k(point_cross, point_start) k1 = self.get_line_k( Space.CanvasPoint(Set.screen_width, Set.screen_height), point_start) k2 = self.get_line_k(Space.CanvasPoint(0, Set.screen_height), point_start) k3 = self.get_line_k(Space.CanvasPoint(0, 0), point_start) k4 = self.get_line_k(Space.CanvasPoint(Set.screen_width, 0), point_start) if k == 0: k = 0.001 # 与画布平面上四条边的四个交点 point1 = Space.CanvasPoint( (Set.screen_height - point_start.y) / k + point_start.x, Set.screen_height) point2 = Space.CanvasPoint(0, -point_start.x * k + point_start.y) point3 = Space.CanvasPoint(-point_start.y / k + point_start.x, 0) point4 = Space.CanvasPoint(Set.screen_width, (Set.screen_width - point_start.x) * k + point_start.y) # print("point1", point1, k1) # print("point2", point2, k2) # print("point3", point3, k3) # print("point4", point4, k4) # print("k", k) point = None if point_cross.x >= point_start.x and point_cross.y >= point_start.y: if k >= k1: point = point1 else: point = point4 elif point_cross.x < point_start.x and point_cross.y >= point_start.y: if k >= k2: point = point2 else: point = point1 elif point_cross.x < point_start.x and point_cross.y < point_start.y: if k >= k3: point = point3 else: point = point2 elif point_cross.x >= point_start.x and point_cross.y < point_start.y: if k >= k4: point = point4 else: point = point3 if is_not_among_point: if point == point1: return point3 if point == point2: return point4 if point == point3: return point1 if point == point4: return point2 return point
def tick_draw(self, dt): # 移动人物 InputControl.player_move(dt) # 移动实体 self.world.update(dt) self.plane = self.canvas_plane() x_vector, y_vector, canvas_zero = self.get_new_xy_vector() # 存储线及点是否可见 canvas_point_list = [] canvas_point_visible = [] point_list = [] # 屏幕中点 screen_reset = Space.CanvasPoint(Set.screen_width / 2, Set.screen_height / 2) # 取出当前世界中的点进行计算,转换到画布坐标系上 for point in self.world.point_list: # 简化空间点 space_point = self.canvas_plane_cross_point(point) # 获取画布点(以原点为中心) canvas_point = self.space_to_canvas(space_point, x_vector, y_vector, canvas_zero) # print("point", point, "space_point", space_point, "canvas_point", canvas_point) point_list.append(point) # 获取画布点移至视平面中心,并存储至列表中 canvas_point_list.append(canvas_point + screen_reset) # 判断点是否存在于 canvas_point_visible.append(self.is_visible(point)) # print("pointlist", point_list) # print("canvas_point_list", canvas_point_list) # print("canvas_point_visible", canvas_point_visible) # 清除画布 self.window.clear() # 重新绘制画布,将点的连线应用至点上 for line in self.world.line_list: # 遍历连线 # 如果连线的两端都不可见则直接跳过 is_visible = True if not canvas_point_visible[line[0]] and not canvas_point_visible[ line[1]]: continue player = self.world.player point_a = canvas_point_list[line[0]] point_b = canvas_point_list[line[1]] # print("point_origin_a", point_a, "point_origin_b", point_b) # 判断是否应该隐藏,如果一个点在视野外,一个点在后脑勺就隐藏 # TODO 判断标准应比这更复杂 # if point_a.is_out_screen() and not canvas_point_visible[line[1]]: # continue # elif point_b.is_out_screen() and not canvas_point_visible[line[0]]: # continue # 单侧不可见的情况下,将其中转换为投影 if not canvas_point_visible[line[0]]: is_visible = False cross_point = self.plane_cross_line( player.location + player.face_to, player.face_to, point_list[line[0]], point_list[line[1]]) is_not_among_point = self.is_not_among_point( point_list[line[0]], point_list[line[1]], cross_point) canvas_cross_point = self.space_to_canvas( cross_point, x_vector, y_vector, canvas_zero) point_a = self.get_final_cross_point( point_b, canvas_cross_point + screen_reset, is_not_among_point) # print("cross_point", cross_point, "canvas_cross_point", canvas_cross_point, "point_a", point_a) elif not canvas_point_visible[line[1]]: is_visible = False cross_point = self.plane_cross_line( player.location + player.face_to, player.face_to, point_list[line[0]], point_list[line[1]]) is_not_among_point = self.is_not_among_point( point_list[line[0]], point_list[line[1]], cross_point) canvas_cross_point = self.space_to_canvas( cross_point, x_vector, y_vector, canvas_zero) point_b = self.get_final_cross_point( point_a, canvas_cross_point + screen_reset, is_not_among_point) # print("cross_point", cross_point, "canvas_cross_point", canvas_cross_point, "\npoint_b", point_b) # print("point_a", point_a, "point_b", point_b) # 绘制连线 Canvas.draw_line(point_a.x, point_a.y, point_b.x, point_b.y, is_visible) Canvas.time += 1 pyglet.text.Label('FPS:%d' % Canvas.fps, font_name='Times New Roman', font_size=15, x=30, y=Set.screen_height - 10, anchor_x='center', anchor_y='center').draw()
def space_to_canvas(space_point, x_vector, y_vector, canvas_zero): vector = space_point - canvas_zero x = vector * x_vector y = vector * y_vector return Space.CanvasPoint(x * 250 / Set.screen_range, y * 250 / Set.screen_range)
def load_cube_3x4(): # 设置场景方块 cube_list = [ StaticEntity.Cube(Space.Point(0, 200, 200), 200), StaticEntity.Cube(Space.Point(0, 200, 400), 200), StaticEntity.Cube(Space.Point(0, 200, 600), 200), StaticEntity.Cube(Space.Point(0, 200, 800), 200), StaticEntity.Cube(Space.Point(0, 400, 200), 200), StaticEntity.Cube(Space.Point(0, 400, 400), 200), StaticEntity.Cube(Space.Point(0, 400, 600), 200), StaticEntity.Cube(Space.Point(0, 400, 800), 200), StaticEntity.Cube(Space.Point(0, 600, 200), 200), StaticEntity.Cube(Space.Point(0, 600, 400), 200), StaticEntity.Cube(Space.Point(0, 600, 600), 200), StaticEntity.Cube(Space.Point(0, 600, 800), 200), ] return cube_list
def load_square(): return [StaticEntity.Square(Space.Point(0, 0, 0), 200)]