This commit is contained in:
Alexander Bass 2024-04-14 10:38:11 -04:00
commit fd7b0ec647
11 changed files with 584 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
progress
__pycache__

19
dirt.ppm Normal file
View file

@ -0,0 +1,19 @@
P3
16 16
255
185 133 92 150 108 74 150 108 74 121 85 58 121 85 58 185 133 92 150 108 74 150 108 74 121 85 58 121 85 58 89 61 41 121 85 58 121 85 58 185 133 92 121 85 58 185 133 92
121 85 58 150 108 74 89 61 41 121 85 58 121 85 58 150 108 74 135 135 135 89 61 41 121 85 58 185 133 92 150 108 74 121 85 58 185 133 92 150 108 74 89 61 41 89 61 41
185 133 92 121 85 58 121 85 58 89 61 41 185 133 92 121 85 58 121 85 58 121 85 58 185 133 92 121 85 58 121 85 58 121 85 58 89 61 41 89 61 41 185 133 92 121 85 58
150 108 74 108 108 108 185 133 92 121 85 58 150 108 74 89 61 41 121 85 58 185 133 92 150 108 74 150 108 74 121 85 58 150 108 74 121 85 58 185 133 92 150 108 74 121 85 58
150 108 74 121 85 58 150 108 74 185 133 92 89 61 41 150 108 74 121 85 58 121 85 58 150 108 74 89 61 41 121 85 58 108 108 108 121 85 58 150 108 74 89 61 41 121 85 58
121 85 58 89 61 41 150 108 74 150 108 74 121 85 58 150 108 74 89 61 41 89 61 41 89 61 41 121 85 58 121 85 58 89 61 41 121 85 58 121 85 58 121 85 58 185 133 92
185 133 92 121 85 58 121 85 58 121 85 58 135 135 135 121 85 58 121 85 58 185 133 92 185 133 92 121 85 58 185 133 92 185 133 92 121 85 58 150 108 74 121 85 58 150 108 74
121 85 58 121 85 58 185 133 92 185 133 92 150 108 74 150 108 74 121 85 58 121 85 58 150 108 74 89 61 41 150 108 74 150 108 74 121 85 58 121 85 58 150 108 74 150 108 74
150 108 74 121 85 58 121 85 58 150 108 74 121 85 58 150 108 74 121 85 58 89 61 41 121 85 58 150 108 74 150 108 74 121 85 58 121 85 58 121 85 58 89 61 41 121 85 58
121 85 58 150 108 74 89 61 41 121 85 58 121 85 58 89 61 41 89 61 41 121 85 58 121 85 58 121 85 58 121 85 58 121 85 58 185 133 92 185 133 92 121 85 58 150 108 74
121 85 58 150 108 74 121 85 58 185 133 92 185 133 92 121 85 58 185 133 92 150 108 74 89 61 41 185 133 92 185 133 92 89 61 41 150 108 74 150 108 74 135 135 135 121 85 58
150 108 74 121 85 58 121 85 58 150 108 74 150 108 74 185 133 92 121 85 58 150 108 74 108 108 108 150 108 74 150 108 74 121 85 58 89 61 41 150 108 74 121 85 58 89 61 41
121 85 58 89 61 41 150 108 74 121 85 58 150 108 74 150 108 74 185 133 92 121 85 58 121 85 58 121 85 58 121 85 58 121 85 58 121 85 58 121 85 58 185 133 92 185 133 92
121 85 58 150 108 74 121 85 58 121 85 58 116 88 68 121 85 58 150 108 74 150 108 74 121 85 58 89 61 41 185 133 92 89 61 41 121 85 58 185 133 92 150 108 74 150 108 74
150 108 74 121 85 58 89 61 41 185 133 92 121 85 58 89 61 41 121 85 58 89 61 41 185 133 92 185 133 92 121 85 58 150 108 74 121 85 58 121 85 58 150 108 74 150 108 74
150 108 74 121 85 58 185 133 92 150 108 74 150 108 74 121 85 58 135 135 135 121 85 58 150 108 74 150 108 74 121 85 58 121 85 58 150 108 74 150 108 74 121 85 58 89 61 41

25
entity.py Normal file
View file

@ -0,0 +1,25 @@
# Alexander Bass
# Created 4/13/24
# Last Edited 4/13/24
class Entity:
def update(self, t):
pass
class PointBlobEntity(Entity):
def __init__(self):
super().__init__()
self.points = []
def get_points(self):
return self.points
def add_point(self, point):
self.points.append(point)
def rotate(self, transform):
for p in self.points:
p.rotate(transform)
def set_points(self, points):
self.points = points

107
grass_donut.py Normal file
View file

@ -0,0 +1,107 @@
# Alexander Bass
# Created 4/13/24
# Last Edited 4/13/24
from point import Point, Rotator
from util import to_rad
import ppm
from itertools import product
from entity import PointBlobEntity
import math
DIRT = ppm.load_ppm(open("dirt.ppm", "r"))
GRASS_TOP = ppm.load_ppm(open("grass_side.ppm", "r"))
GRASS_SIDE = ppm.load_ppm(open("grass_top.ppm", "r"))
def mix_color_transparency(left, right):
for a in left:
if a > 0:
return left
return right
def mul_color(a, b):
return (a[0] * b[0], a[1] * b[1], a[2] * b[2])
def mul_color_scalar(a, b):
return (a[0] * b, a[1] * b, a[2] * b)
def cube(dirt, g_sides, g_top, face_x, face_y):
GRASS_COLOR_MUL = (0.4, 1, 0.4)
out = []
image_size = 16
point_count = 20
world_width = 16
for x, y in product(range(point_count), range(point_count)):
# Scale x and y to be from 0 to 1 to be later scaled back for any respective coordinate system
x /= point_count
y /= point_count
dirt_color = dirt[round(y * image_size)][round(x * image_size)]
top_col = g_top[round(y * image_size)][round(x * image_size)]
grass_side_color = g_sides[int(y * image_size)][int(x * image_size)]
grass_side_color = mul_color(grass_side_color, GRASS_COLOR_MUL)
top_col = mul_color(top_col, GRASS_COLOR_MUL)
side_color = mix_color_transparency(grass_side_color, dirt_color)
b_red, b_green, b_blue = dirt_color
t_red, t_green, t_blue = top_col
s_red, s_green, s_blue = side_color
x_w = x * world_width
y_w = y * world_width
w_w = world_width
if face_x == -1 or face_x == 1 and face_y == 0:
out.append(Point().set_xyz(0, x_w, y_w).set_color(s_red, s_green, s_blue))
if face_x == 1 or face_x == -1 and face_y == 0:
out.append(Point().set_xyz(w_w, x_w, y_w).set_color(s_red, s_green, s_blue))
if face_y == -1 or face_y == 1 and face_x == 0:
out.append(Point().set_xyz(x_w, 0, y_w).set_color(s_red, s_green, s_blue))
if face_y == 1 or face_y == -1 and face_x == 0:
out.append(Point().set_xyz(x_w, w_w, y_w).set_color(s_red, s_green, s_blue))
# Top and bottom faces
out.append(Point().set_xyz(x_w, y_w, w_w).set_color(b_red, b_green, b_blue))
out.append(Point().set_xyz(x_w, y_w, 0).set_color(t_red, t_green, t_blue))
for p in out:
p.translate_x(face_x * world_width - world_width / 2)
p.translate_y(face_y * world_width - world_width / 2)
p.translate_z(-world_width / 2)
p.rotate_z(to_rad(90))
p.rotate_y(45 * 3)
pass
return out
class DonutEntity(PointBlobEntity):
def __init__(self):
super().__init__()
points = []
for x, y in product((-1, 0, 1), (-1, 0, 1)):
if x == y == 0:
continue
points.extend(cube(DIRT, GRASS_TOP, GRASS_SIDE, x, y))
self.set_points(points)
def update(self, t):
tf = Rotator()
tf.rotate_y(math.cos(t / 25) * 0.5)
# tf.rotate_z(0.02)
tf.rotate_x(math.sin(t / 20) * 0.5 + 0.02)
tf.build()
for p in self.points:
p.rotate(tf)
pass
def shift(self, x, y, z):
for p in self.points:
p.translate(x, y, z)

19
grass_side.ppm Normal file
View file

@ -0,0 +1,19 @@
P3
16 16
255
169 169 169 144 144 144 150 150 150 140 140 140 169 169 169 144 144 144 169 169 169 150 150 150 150 150 150 159 159 159 169 169 169 159 159 159 178 178 178 129 129 129 159 159 159 150 150 150
169 169 169 140 140 140 169 169 169 144 144 144 178 178 178 0 0 0 169 169 169 130 130 130 178 178 178 150 150 150 169 169 169 147 147 147 169 169 169 140 140 140 169 169 169 139 139 139
150 150 150 0 0 0 178 178 178 132 132 132 169 169 169 0 0 0 144 144 144 0 0 0 169 169 169 159 159 159 150 150 150 173 173 173 0 0 0 119 119 119 150 150 150 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 145 145 145 0 0 0 0 0 0 0 0 0 127 127 127 0 0 0 141 141 141 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

19
grass_top.ppm Normal file
View file

@ -0,0 +1,19 @@
P3
16 16
255
148 148 148 195 195 195 147 147 147 134 134 134 134 134 134 143 143 143 127 127 127 140 140 140 158 158 158 150 150 150 138 138 138 135 135 135 137 137 137 167 167 167 112 112 112 141 141 141
149 149 149 140 140 140 160 160 160 151 151 151 153 153 153 128 128 128 153 153 153 130 130 130 127 127 127 169 169 169 166 166 166 147 147 147 195 195 195 140 140 140 135 135 135 139 139 139
163 163 163 141 141 141 125 125 125 132 132 132 137 137 137 136 136 136 144 144 144 144 144 144 148 148 148 159 159 159 168 168 168 173 173 173 135 135 135 119 119 119 128 128 128 182 182 182
118 118 118 133 133 133 138 138 138 151 151 151 145 145 145 153 153 153 125 125 125 146 146 146 127 127 127 131 131 131 141 141 141 151 151 151 143 143 143 139 139 139 167 167 167 125 125 125
162 162 162 131 131 131 173 173 173 131 131 131 172 172 172 174 174 174 136 136 136 172 172 172 186 186 186 117 117 117 128 128 128 167 167 167 171 171 171 126 126 126 136 136 136 141 141 141
153 153 153 152 152 152 120 120 120 166 166 166 129 129 129 150 150 150 149 149 149 155 155 155 135 135 135 149 149 149 136 136 136 131 131 131 120 120 120 136 136 136 142 142 142 148 148 148
126 126 126 156 156 156 165 165 165 144 144 144 146 146 146 131 131 131 138 138 138 127 127 127 132 132 132 135 135 135 181 181 181 172 172 172 145 145 145 167 167 167 151 151 151 143 143 143
143 143 143 135 135 135 157 157 157 139 139 139 144 144 144 124 124 124 164 164 164 132 132 132 151 151 151 173 173 173 135 135 135 129 129 129 143 143 143 160 160 160 127 127 127 169 169 169
167 167 167 155 155 155 182 182 182 170 170 170 172 172 172 129 129 129 173 173 173 156 156 156 179 179 179 170 170 170 130 130 130 146 146 146 133 133 133 147 147 147 158 158 158 126 126 126
151 151 151 130 130 130 183 183 183 141 141 141 140 140 140 152 152 152 170 170 170 128 128 128 135 135 135 145 145 145 146 146 146 169 169 169 142 142 142 179 179 179 143 143 143 129 129 129
155 155 155 158 158 158 151 151 151 165 165 165 130 130 130 182 182 182 142 142 142 147 147 147 192 192 192 121 121 121 167 167 167 131 131 131 143 143 143 136 136 136 151 151 151 143 143 143
132 132 132 173 173 173 134 134 134 163 163 163 151 151 151 132 132 132 146 146 146 137 137 137 151 151 151 146 146 146 140 140 140 123 123 123 179 179 179 127 127 127 125 125 125 138 138 138
186 186 186 151 151 151 129 129 129 138 138 138 153 153 153 145 145 145 133 133 133 122 122 122 138 138 138 145 145 145 138 138 138 125 125 125 159 159 159 165 165 165 121 121 121 151 151 151
129 129 129 168 168 168 118 118 118 146 146 146 125 125 125 153 153 153 129 129 129 195 195 195 161 161 161 147 147 147 168 168 168 155 155 155 160 160 160 136 136 136 168 168 168 174 174 174
163 163 163 161 161 161 192 192 192 123 123 123 179 179 179 171 171 171 148 148 148 147 147 147 126 126 126 149 149 149 149 149 149 135 135 135 169 169 169 157 157 157 139 139 139 121 121 121
133 133 133 150 150 150 136 136 136 137 137 137 164 164 164 152 152 152 148 148 148 147 147 147 142 142 142 191 191 191 124 124 124 169 169 169 132 132 132 144 144 144 136 136 136 158 158 158

129
point.py Normal file
View file

@ -0,0 +1,129 @@
# Alexander Bass
# Created 4/13/24
# Last Edited 4/13/24
from math import cos, sin
class Point:
def __init__(self):
self.__color = (1, 1, 1)
self.__x, self.__y, self.__z = 0, 0, 0
def set_xyz(self, x, y, z):
self.__x, self.__y, self.__z = x, y, z
return self
def rotate_x(self, angle):
cos_a = cos(angle)
sin_a = sin(angle)
y_1 = self.__y * cos_a - self.__z * sin_a
z_1 = self.__y * sin_a + self.__z * cos_a
self.set_xyz(self.__x, y_1, z_1)
return self
def rotate_z(self, angle):
cos_a = cos(angle)
sin_a = sin(angle)
x_1 = self.__x * cos_a - self.__y * sin_a
y_1 = self.__x * sin_a + self.__y * cos_a
self.set_xyz(x_1, y_1, self.__z)
return self
def rotate_y(self, angle):
cos_a = cos(angle)
sin_a = sin(angle)
x_1 = self.__x * cos_a + self.__z * sin_a
z_1 = self.__z * cos_a - self.__x * sin_a
self.set_xyz(x_1, self.__y, z_1)
return self
def translate(self, x, y, z):
self.__x += x
self.__y += y
self.__z += z
def translate_x(self, x):
self.__x += x
def translate_y(self, y):
self.__y += y
def translate_z(self, z):
self.__z += z
def get_xyz(self):
return (self.__x, self.__y, self.__z)
def rotate(self, transform):
x_n, y_n, z_n = transform.run(*self.get_xyz())
self.set_xyz(x_n, y_n, z_n)
def get_rgb(self):
return self.__color
def set_color(self, r, g, b):
if r > 255 or g > 255 or b > 255 or r < 0 or g < 0 or b < 0:
raise ValueError("Color is greater than 255 or less than 0")
self.__color = (r, g, b)
return self
class Rotator:
def __init__(self):
self.__alpha = 0.0
self.__beta = 0.0
self.__gamma = 0.0
self.__sin_alpha = 0.0
self.__cos_alpha = 0.0
self.__sin_beta = 0.0
self.__cos_beta = 0.0
self.__sin_gamma = 0.0
self.__cos_gamma = 0.0
def rotate_x(self, angle):
self.__alpha += angle
return self
def rotate_y(self, angle):
self.__beta += angle
return self
def rotate_z(self, angle):
self.__gamma += angle
return self
def build(self):
self.__sin_alpha = sin(self.__alpha)
self.__cos_alpha = cos(self.__alpha)
self.__sin_beta = sin(self.__beta)
self.__cos_beta = cos(self.__beta)
self.__sin_gamma = sin(self.__gamma)
self.__cos_gamma = cos(self.__gamma)
return self
def run(self, xI, yI, zI):
x_0 = xI
y_0 = yI
z_0 = zI
x_1, y_1 = 0, 0
# if self.__alpha != 0.0:
y_1 = y_0 * self.__cos_alpha - z_0 * self.__sin_alpha
z_0 = y_0 * self.__sin_alpha + z_0 * self.__cos_alpha
y_0 = y_1
# if self.__beta != 0.0:
x_1 = x_0 * self.__cos_beta + z_0 * self.__sin_beta
z_0 = z_0 * self.__cos_beta - x_0 * self.__sin_beta
x_0 = x_1
# if self.__gamma != 0.0:
x_1 = x_0 * self.__cos_gamma - y_0 * self.__sin_gamma
y_0 = x_0 * self.__sin_gamma + y_0 * self.__cos_gamma
x_0 = x_1
return x_0, y_0, z_0

46
ppm.py Normal file
View file

@ -0,0 +1,46 @@
# Alexander Bass
# Created 4/12/24
# Last Edited 4/13/24
def load_ppm(file):
header = next(file).strip().upper()
assert header == "P3"
dimensions = next(file).strip()
split_dimensions = dimensions.split()
assert len(split_dimensions) == 2
width = split_dimensions[0]
height = split_dimensions[-1]
width = int(width)
height = int(height)
# not really doing anything with this
color_depth = next(file).strip()
assert color_depth == "255"
image = []
for y, line in enumerate(file):
assert y < height
t = [int(value) for value in line.strip().split()]
pixels = []
assert len(t) % 3 == 0
assert len(t) // 3 <= width
highest = 0
for x in range(0, len(t), 3):
red = t[0 + x]
green = t[1 + x]
blue = t[2 + x]
highest = x // 3
pixels.append((red, green, blue))
assert highest == width - 1
image.append(pixels)
assert len(image) == height
file.close()
return image
if __name__ == "__main__":
print(load_ppm(open("dirt.ppm")))

51
real_donut.py Normal file
View file

@ -0,0 +1,51 @@
# Alexander Bass
# Created 4/13/24
# Last Edited 4/13/24
from point import Point, Rotator
from util import to_rad
from entity import PointBlobEntity
from math import sin, cos
RADIUS = 10
DISTANCE = 15
POINTS_PER_CIRCLE = 70
NUMBER_CIRCLES = 360
class RealDonutEntity(PointBlobEntity):
def __init__(self):
super().__init__()
points = []
rot = Rotator().rotate_x(to_rad(-30))
rot.build()
for phi_t in range(NUMBER_CIRCLES):
phi_percent = phi_t / NUMBER_CIRCLES
phi = phi_percent * 360
temp_points = []
for theta in range(POINTS_PER_CIRCLE):
percent_theta = theta / POINTS_PER_CIRCLE
theta = percent_theta * 360
x = DISTANCE + RADIUS * cos(to_rad(theta))
y = RADIUS * sin(to_rad(theta))
new_point = Point().set_xyz(x, y, 0).set_color(255, 255, 0)
# temp_points
new_point.rotate_y(to_rad(phi))
temp_points.append(new_point)
points.extend(temp_points)
temp_points.clear()
for p in points:
p.rotate(rot)
self.set_points(points)
def update(self, t):
tf = Rotator()
tf.rotate_y(0.03)
tf.rotate_x(0.02 * cos(t / 120))
tf.build()
for p in self.points:
p.rotate(tf)
# pass
def shift(self, x, y, z):
for p in self.points:
p.translate(x, y, z)

136
spiral.py Normal file
View file

@ -0,0 +1,136 @@
# Alexander Bass
# Created 4/10/24
# Last Edited 4/13/24
import time
from math import pi, cos, sin, sqrt # noqa: F401
from point import Point, Rotator
from grass_donut import DonutEntity
from real_donut import RealDonutEntity
from entity import Entity, PointBlobEntity
from util import to_rad
WIDTH = 150
HEIGHT = 100
DEPTH = WIDTH
HALF_WIDTH = WIDTH / 2
HALF_HEIGHT = HEIGHT // 2
HALF_DEPTH = DEPTH // 2
NEGATIVE_DEPTH = -DEPTH
def world_to_screen(p_x, p_y, p_z):
s_x = round(p_x + HALF_WIDTH)
s_y = round(p_y + HALF_HEIGHT)
s_z = (p_z + HALF_DEPTH) / DEPTH
return s_x, s_y, s_z
def format_grid(entities, screen):
for x in range(WIDTH):
for y in range(HEIGHT):
screen[y][x] = None
for entity in entities:
for p in entity.get_points():
p_x, p_y, p_z = p.get_xyz()
s_x, s_y, s_z = world_to_screen(p_x, p_y, p_z)
if s_x in range(WIDTH) and s_y in range(HEIGHT):
val = screen[s_y][s_x]
if val is None:
red, green, blue = p.get_rgb()
screen[s_y][s_x] = (red, green, blue, s_z)
elif val[3] < s_z:
red, green, blue = p.get_rgb()
screen[s_y][s_x] = (red, green, blue, s_z)
s = ""
last_color = (0, 0, 0)
for y in range(HEIGHT):
for x in range(WIDTH):
cell = screen[y][x]
if cell is None or 0 > cell[3] > 255:
s += " "
continue
red, green, blue, depth = cell
scale = depth
red *= scale
green *= scale
blue *= scale
if (red, green, blue) != last_color:
s += f"\033[38;2;{round(red)};{round(green)};{round(blue)}m"
last_color = (red, green, blue)
s += "██"
s += "\n"
return s
def update_entities(entities, t):
for e in entities:
e.update(t)
class AxisEntity(PointBlobEntity):
def __init__(self):
self.points = []
for x in range(WIDTH // 2 + 1):
tx = x - WIDTH / 4
for y in range(WIDTH // 2 + 1):
ty = y - WIDTH / 4
self.add_point(Point().set_xyz(0, tx, ty).set_color(1, 1, 0))
r = (
Rotator()
.rotate_z(to_rad(80))
.rotate_y(to_rad(30))
.rotate_x(to_rad(30))
.build()
)
self.rotate(r)
self.rotor = Rotator().rotate_z(to_rad(0.6)).rotate_y(to_rad(0.06)).build()
def update(self, t):
t = t + 6 * 30
self.rotate(self.rotor)
for p in self.points:
x, y, z = p.get_xyz()
x, y = abs(x), abs(y)
p.set_color(255 * abs(sin(x * t / 99)), 255 * abs(sin(y * t / 100)), 0)
class Origin(PointBlobEntity):
def __init__(self):
super().__init__()
self.points = [Point().set_xyz(0, 0, 0).set_color(255, 0, 0)]
def main():
entities = []
# entities.append(AxisEntity())
# entities.append(Origin())
entities.append(RealDonutEntity())
entities.append(DonutEntity())
t = 1
last_time = time.time()
dt = 0
grid = [[None for x in range(WIDTH)] for y in range(HEIGHT)]
while True:
print("\033c", end="")
print(format_grid(entities, grid))
update_entities(entities, t)
current_time = time.time()
dt = current_time - last_time
wait = 1 / 45 - dt
last_time = current_time
time.sleep(max(wait, 0))
t += 1 + 1 / 45 - dt
main()

31
util.py Normal file
View file

@ -0,0 +1,31 @@
# Alexander Bass
# Created 4/13/24
# Last Edited 4/13/24
from math import sin, cos, atan2, acos, sqrt
import math
def to_rad(deg):
return math.pi * deg / 180.0
def sign(f):
if f == 0:
return f
return f / math.fabs(f)
def to_cart(r, theta, phi):
y = r * sin(theta) * cos(phi)
x = r * cos(theta)
z = r * sin(theta) * sin(phi)
return x, y, z
def to_spherical(x, y, z):
r = sqrt(x**2 + y**2 + z**2)
theta = acos(z / r)
x = x if x != 0 else 1
phi = math.atan(y / x)
return r, theta, phi