-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathlight.py
executable file
·61 lines (51 loc) · 1.6 KB
/
light.py
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
#from colour import Colour
from geom3 import *
import math
class Light(object):
"""A Basic light at inifinite distance"""
def __init__(self, scene, dir, colour):
self.colour = colour
self.dir = dir
self.scene = scene
self.offset = 0.0000001 * self.dir
def atPoint(self, point):
shadowRay = Ray3(point + self.offset, self.dir)
shadowTest = self.scene.intersect(shadowRay)
if shadowTest.entry is ():
return LightHit(self.colour, self.dir)
return None
class LightHit(object):
def __init__(self, colour, vector):
self.colour = colour
self.vector = vector
class PointLight(object):
def __init__(self, scene, point, colour):
self.colour = colour
self.point = point
self.scene = scene
self.offset = 0.0000001
def atPoint(self, point):
dir = unit(self.point - point)
shadowRay = Ray3(point + self.offset * dir, dir)
shadowTest = self.scene.intersect(shadowRay)
if shadowTest is None or shadowTest.entry > length(self.point - point):
return LightHit(self.colour, dir)
return None
class SpotLight(object):
def __init__(self, scene, point, lookAt, angle, colour):
self.colour = colour
self.point = point
self.vector = unit(point - lookAt)
self.angle = math.cos(math.radians(angle))
self.scene = scene
self.offset = 0.0000001
def atPoint(self, point):
dir = unit(self.point - point)
angle = dot(dir, self.vector)
if angle < self.angle:
return None
shadowRay = Ray3(point + self.offset * dir, dir)
shadowTest = self.scene.intersect(shadowRay)
if shadowTest is None or shadowTest.entry > length(self.point - point):
return LightHit(self.colour, dir)
return None