Вращение оси Y в PythonPython

Программы на Python
Ответить
Anonymous
 Вращение оси Y в Python

Сообщение Anonymous »

Итак, я пытался создать 3D-движок с нуля на Python, когда пытался повернуть плоскость. Все оси были в порядке как предопределенные повороты в трехмерном пространстве, но при обновлении вращения в коде работали только оси x и z. Но что касается оси Y, то при обновлении вращения она выглядела как восьмиугольный беспорядок оригами.
Изображение

Хотя он выглядит нормально, он продолжает трястись. Я не могу показать вам видео, но вы, скорее всего, поняли идею.
Вот весь код, который я написал на данный момент:

Код: Выделить всё

# imports
import pygame as pg
from vec import Vec3, Vec2
from math import sin, cos, tau

pg.init()

# screen
screen_dim: tuple[int, int] = (480, 360)
screen = pg.display.set_mode(screen_dim)

origin: Vec2 = Vec2(screen_dim[0] / 2, screen_dim[1] / 2)

# undertale
clock = pg.time.Clock()
delta: float = 1000 / clock.tick(60)

running: bool = True

# camera
class Camera:
def __init__(self, pos: Vec3, fov: float) -> None:
self.pos: Vec3 = pos
self.fov: float = fov

camera: Camera = Camera(Vec3(0, 0, -1), 120)

# vertex
class Vertex:
def __init__(self, pos: Vec3) -> None:
self.pos: Vec3 = pos

vertices = []

# creation
def create_vertex(pos: Vec3) -> None:
vertices.append(Vertex(pos))

def create_line(pos1: Vec3, pos2: Vec3) -> None:
vertices.append(Vertex(pos1))
vertices.append(Vertex(pos2))

def create_plane(pos: Vec3, dim: Vec2, rot: Vec3) -> None:
for i in range(-1, 2, 2):
for j in range(-1, 2, 2):
x_pos: float = dim.x / 2 * i
y_pos: float = dim.y / 2 * j
z_pos: float = 0

vertices.append(Vertex(Vec3(
pos.x + \
x_pos*(cos(rot.y)*cos(rot.z)) + \
y_pos*(cos(rot.z)*sin(rot.x)*sin(rot.y) - cos(rot.x)*sin(rot.z)) + \
z_pos*(cos(rot.x)*cos(rot.z)*sin(rot.y) + sin(rot.x)*sin(rot.z)), # y * z

pos.y + \
x_pos*(cos(rot.y)*sin(rot.z)) + \
y_pos*(cos(rot.x)*cos(rot.z) + sin(rot.x)*sin(rot.y)*sin(rot.z)) + \
z_pos*(cos(rot.x)*sin(rot.y)*sin(rot.z) - cos(rot.z)*sin(rot.x)), # x * z

pos.z + \
x_pos*(-sin(rot.y)) + \
y_pos*(cos(rot.y)*sin(rot.x)) + \
z_pos*(cos(rot.x)*cos(rot.y)) # x * y
)))

def calculate_vertex(vertex: Vertex) -> tuple[float, float]:
return (origin.x + (vertex.pos.x-camera.pos.x) * camera.fov/(vertex.pos.z-camera.pos.z),
origin.y + (vertex.pos.y-camera.pos.y) * camera.fov/(vertex.pos.z-camera.pos.z))

n: Vec3 = Vec3(0, 0, 0)

# drawing
def draw_vertex(vert_id: int, color: str, radius: float) -> None:
# NOTE: "vert_id" refers to the index of a vertex in th list
vertex: Vertex = vertices[vert_id]

pg.draw.circle(screen, color, calculate_vertex(vertex), radius)

def draw_line(vert_id: int, other_vert_id: int, color: str, width: float) -> None:
vertex: Vertex = vertices[vert_id]
other_vertex: Vertex = vertices[other_vert_id]

pg.draw.line(
screen, color,
calculate_vertex(vertex),
calculate_vertex(other_vertex),
width
)

# wireframe
def draw_plane_wf(vert_id: int, color: str, width: float) -> None:
if width == 0:
raise ValueError('it has wf for a reason')

pg.draw.polygon(
screen, color,
[calculate_vertex(vertices[vert_id]),
calculate_vertex(vertices[vert_id + 2]),
calculate_vertex(vertices[vert_id + 1]),
calculate_vertex(vertices[vert_id + 3])],
width
)

# filled in color

def draw_plane(vert_id, color: str) ->  None:
vertex: Vertex = vertices[vert_id]

create_line(Vec3(1, 1, 1), Vec3(-1, -1, 1))
create_plane(Vec3(0, 0, 1), Vec2(1, 1), Vec3.zero())

while running:
delta: float = clock.tick(60) / 1000

# loop
for ev in pg.event.get():
if ev.type == pg.QUIT:
running = False

# update
del vertices[2:-1]

create_plane(Vec3(0, 0, 1), Vec2(1, 1), n)

n += Vec3(0, tau, 0) * delta

# draw
screen.fill('black')

for i in range(len(vertices)):
draw_vertex(i, 'white', 2)

draw_line(0, 1, 'red', 1)
draw_plane_wf(2, 'green', 2)

pg.display.flip()
И еще, при обновлении глючит только ось Y, а не остальные оси.


Подробнее здесь: https://stackoverflow.com/questions/798 ... -in-python
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»