-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpatterns.py
More file actions
107 lines (72 loc) · 2.48 KB
/
patterns.py
File metadata and controls
107 lines (72 loc) · 2.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from matrix import Matrix
from tuples import colour
from math import floor
class Pattern:
"""
#TODO: Patterns are implemented as if they are 'cut out' of 3d shapes with
the given pattern. For more realistic surface mapped patterns,
we'll need to implement UV mapping, which is a method to convert
3D (x, y, z) points to 2D (u, v) coordinates.
"""
def __init__(
self,
a=colour(1, 1, 1),
b=colour(0, 0, 0),
transform=Matrix.identity
):
self.a = a
self.b = b
self.transform = transform
def colour_at_object(self, _object, world_point):
object_point = _object.transform.inverse * world_point
return self.colour_at_point(object_point)
def colour_at_point(self, object_point):
local_point = self.transform.inverse * object_point
c = self.colour_at(local_point)
return c if isinstance(c, colour) else c.colour_at_point(local_point)
class StripePattern(Pattern):
def colour_at(self, point):
return self.a if floor(point.x) % 2 == 0 else self.b
class GradientPattern(Pattern):
def colour_at(self, point):
distance = self.b - self.a
fraction = point.x - floor(point.x)
return self.a + distance * fraction
class RingPattern(Pattern):
def colour_at(self, point):
return (
self.a
if floor(
((point.x ** 2) + (point.z ** 2)) ** 0.5
) % 2 == 0
else self.b
)
class RadialGradientPattern(Pattern):
def colour_at(self, point):
distance = self.b - self.a
fraction = (((point.x ** 2) + (point.z ** 2)) ** 0.5) % 2
return (
self.a + distance * fraction
if floor(fraction) == 0
else self.a + distance * fraction
)
class CheckersPattern(Pattern):
def colour_at(self, point):
return (
self.a
if (floor(point.x) + floor(point.y) + floor(point.z)) % 2 == 0
else self.b
)
class ImagePattern(Pattern):
def colour_at(self, point):
h = len(self.a)
w = len(self.a[0])
return self.a[floor((point.y + 1)/2 * -h)][floor((point.x + 1)/2 * w)]
class BlendedPattern(Pattern):
def colour_at(self, point):
return (
self.a.colour_at_point(point) + self.b.colour_at_point(point)
) / 2
class _TestPattern(Pattern):
def colour_at(self, point):
return colour(point.x, point.y, point.z)