Skip to content

Instantly share code, notes, and snippets.

@omaraflak
Created August 2, 2021 08:36
Show Gist options
  • Save omaraflak/e0808139d2442123b12a14f5c05e56e8 to your computer and use it in GitHub Desktop.
Save omaraflak/e0808139d2442123b12a14f5c05e56e8 to your computer and use it in GitHub Desktop.
Spinning Donut
import numpy as np
import pyglet
def draw_points(points, format="v2f"):
pyglet.graphics.draw(
len(points),
pyglet.gl.GL_POINTS,
(format, tuple([x for p in points for x in p]))
)
def rotate_x(angle):
return [
[1, 0, 0],
[0, np.cos(angle), -np.sin(angle)],
[0, np.sin(angle), np.cos(angle)]
]
def rotate_y(angle):
return [
[np.cos(angle), 0, np.sin(angle)],
[0, 1, 0],
[-np.sin(angle), 0, np.cos(angle)]
]
def rotate_z(angle):
return [
[np.cos(angle), -np.sin(angle), 0],
[np.sin(angle), np.cos(angle), 0],
[0, 0, 1]
]
def generate_donut_points(scale=100):
radius = 1
center = [1.5, 0, 0]
circle = [
np.array(center) + [radius * np.cos(t), radius * np.sin(t), 0]
for t in np.linspace(0, 2 * np.pi, 50)
]
return [
scale * np.dot(rotate_y(angle), point)
for angle in np.linspace(0, 2 * np.pi, 100)
for point in circle
]
window = pyglet.window.Window(1000, 1000, caption="Donut")
center = np.array([window.height // 2, window.width // 2, 0])
rotation = np.dot(
np.dot(
rotate_x(np.pi / 100),
rotate_y(np.pi / 150)
),
rotate_z(np.pi / 200)
)
projection = [[1, 0, 0], [0, 1, 0]]
points = generate_donut_points()
projected = []
def update_points(value):
global points, projected
points = np.transpose(np.dot(rotation, np.transpose(points)))
projected = np.transpose(np.dot(projection, np.transpose(center + points)))
@window.event
def on_draw():
window.clear()
draw_points(projected)
pyglet.clock.schedule_interval(update_points, 0.01)
pyglet.app.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment