88
99import math
1010import pathlib
11+ from typing import Final
12+
13+ type Vector = tuple [float , float , float ]
14+ type Face = tuple [int , int , int ]
15+ type Color = tuple [int , int , int ]
1116
1217ASSETS_DIR = pathlib .Path (__file__ ).parent / "src" / "pretzel" / "assets"
1318
14- SEGMENTS = 240
15- RING_POINTS = 16
16- TUBE_RADIUS = 0.62
19+ SEGMENTS : Final = 240
20+ RING_POINTS : Final = 16
21+ TUBE_RADIUS : Final = 0.62
1722
18- WALLPAPER_SIZE = 512
19- WALLPAPERS = {
23+ WALLPAPER_SIZE : Final = 512
24+ WALLPAPERS : Final = {
2025 "bakery_dawn.ppm" : ((252 , 210 , 153 ), (146 , 90 , 118 ), (255 , 236 , 179 )),
2126 "bakery_noon.ppm" : ((214 , 235 , 251 ), (245 , 232 , 201 ), (255 , 255 , 224 )),
2227 "bakery_dusk.ppm" : ((94 , 63 , 107 ), (233 , 156 , 90 ), (255 , 214 , 138 )),
2328}
2429
2530
26- def trace_trefoil (t ) :
31+ def trace_trefoil (t : float ) -> Vector :
2732 return (
2833 math .sin (t ) + 2.0 * math .sin (2.0 * t ),
2934 math .cos (t ) - 2.0 * math .cos (2.0 * t ),
3035 - math .sin (3.0 * t ) * 1.2 ,
3136 )
3237
3338
34- def subtract (a , b ) :
39+ def subtract (a : Vector , b : Vector ) -> Vector :
3540 return (a [0 ] - b [0 ], a [1 ] - b [1 ], a [2 ] - b [2 ])
3641
3742
38- def cross (a , b ) :
43+ def cross (a : Vector , b : Vector ) -> Vector :
3944 return (
4045 a [1 ] * b [2 ] - a [2 ] * b [1 ],
4146 a [2 ] * b [0 ] - a [0 ] * b [2 ],
4247 a [0 ] * b [1 ] - a [1 ] * b [0 ],
4348 )
4449
4550
46- def dot (a , b ) :
51+ def dot (a : Vector , b : Vector ) -> float :
4752 return a [0 ] * b [0 ] + a [1 ] * b [1 ] + a [2 ] * b [2 ]
4853
4954
50- def normalize (vector ) :
55+ def normalize (vector : Vector ) -> Vector :
5156 length = math .sqrt (dot (vector , vector )) or 1.0
5257 return (vector [0 ] / length , vector [1 ] / length , vector [2 ] / length )
5358
5459
55- def sweep_tube ():
60+ def sweep_tube () -> tuple [ list [ Vector ], list [ Face ]] :
5661 step = 2.0 * math .pi / SEGMENTS
5762 centers = [trace_trefoil (index * step ) for index in range (SEGMENTS )]
5863 tangents = [
@@ -96,7 +101,7 @@ def sweep_tube():
96101 return vertices , faces
97102
98103
99- def write_mesh (path ) :
104+ def write_mesh (path : pathlib . Path ) -> None :
100105 vertices , faces = sweep_tube ()
101106 with path .open ("w" , encoding = "utf-8" ) as file :
102107 file .write (f"# Trefoil-knot pretzel: { len (vertices )} vertices," )
@@ -108,14 +113,16 @@ def write_mesh(path):
108113 print (f"Wrote { path } ({ len (vertices )} vertices, { len (faces )} faces)" )
109114
110115
111- def blend (low , high , amount ) :
116+ def blend (low : Color , high : Color , amount : float ) -> Color :
112117 return tuple (
113118 round (low [channel ] + (high [channel ] - low [channel ]) * amount )
114119 for channel in range (3 )
115120 )
116121
117122
118- def write_wallpaper (path , top , bottom , glow ):
123+ def write_wallpaper (
124+ path : pathlib .Path , top : Color , bottom : Color , glow : Color
125+ ) -> None :
119126 size = WALLPAPER_SIZE
120127 lights = [
121128 (size * 0.25 , size * 0.3 , size * 0.22 ),
@@ -139,7 +146,7 @@ def write_wallpaper(path, top, bottom, glow):
139146 print (f"Wrote { path } ({ size } x{ size } )" )
140147
141148
142- def main ():
149+ def main () -> None :
143150 ASSETS_DIR .mkdir (parents = True , exist_ok = True )
144151 write_mesh (ASSETS_DIR / "pretzel.mdl" )
145152 for name , (top , bottom , glow ) in WALLPAPERS .items ():
0 commit comments