Skip to content

Commit cf251ab

Browse files
committed
Implemented shadows
1 parent 123a522 commit cf251ab

File tree

3 files changed

+38
-27
lines changed

3 files changed

+38
-27
lines changed

geometry.py

+4-7
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def intersection_value(self, line):
4545
if a == 0:
4646
return []
4747
t = float(self.cte - line.start[2])/line.slope[2]
48-
if t >= 0:
48+
if t > 0.01:
4949
return [t]
5050
else:
5151
return []
@@ -75,7 +75,7 @@ def intersection_value(self, line):
7575
A = v.squared_norm()
7676
B = 2*v.scalar_product(q)
7777
C = q.squared_norm() - self.radius**2
78-
return solve_quadradic((A, B, C))
78+
return solve_quadradic(A, B, C)
7979

8080
def color_at_point(self, p):
8181
return self.color
@@ -118,14 +118,11 @@ def project(self, v2):
118118
n = float(self.scalar_product(v2))/v2.scalar_product(v2)
119119
return v2.mul_by_number(n)
120120

121-
def solve_quadradic(coef):
122-
a = coef[0]
123-
b = coef[1]
124-
c = coef[2]
121+
def solve_quadradic(a, b, c):
125122
delta = b**2 - 4*a*c
126123
if delta < 0:
127124
return []
128125
ans = []
129126
ans.append((-b - sqrt(delta))/(2.0*a))
130127
ans.append((-b + sqrt(delta))/(2.0*a))
131-
return filter(lambda x: x >= 0, ans)
128+
return filter(lambda x: x > 0.01, ans)

render.py

+28-16
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,43 @@ def coordinates(num, sz = size):
1414

1515
def create_world():
1616
S1 = Sphere((4, 4, 2), 2, (100, 220, 0))
17-
S2 = Sphere((7, 7, 1), 1, (200, 10, 200))
17+
S2 = Sphere((2, 2, 1), 1, (0, 100, 200))
1818
S3 = Sphere((3, 1, 1), 1, (100, 100, 200))
19-
P = HorizontalPlane(0, (200, 100, 200), (10, 200, 10))
19+
P = HorizontalPlane(0, (200, 100, 200), (0, 20, 200))
2020
return [S1, S2, S3, P]
2121

22+
def first_intersection(scene, line):
23+
ans = []
24+
for S in scene:
25+
ts = S.intersection_value(line)
26+
if ts:
27+
p = line.point_after_t(ts[0])
28+
ans.append((ts[0], S, p.coords))
29+
if not ans:
30+
return []
31+
ans.sort()
32+
return [ans[0]]
33+
34+
def first_intersection_color(scene, line):
35+
ans = first_intersection(scene, line)
36+
if not ans:
37+
return (255, 255, 255)
38+
to_light = first_intersection(scene, Line.through_points(ans[0][2], light))
39+
if to_light and to_light[0][0] < 1:
40+
return (0, 0, 0)
41+
return ans[0][1].color_at_point(ans[0][2])
42+
2243
world = create_world()
2344
camera = (3, -1, 3)
24-
light = (0, 10, 0)
45+
light = (3, -1, 5)
2546

2647
# Colouring each pixel
2748
for i in range(size):
2849
x0 = coordinates(i)
29-
for j in range(size):
30-
y0 = coordinates(j)
50+
for k in range(size):
51+
y0 = coordinates(k)
52+
j = size - 1 - k
3153
l = Line.through_points(camera, (x0, 0, y0))
32-
ans = []
33-
for S in world:
34-
ts = S.intersection_value(l)
35-
if ts:
36-
p = l.point_after_t(ts[0])
37-
ans.append((ts[0], S, p.coords))
38-
if not ans:
39-
rays[i, size - 1 - j] = (255, 255, 255)
40-
else:
41-
ans.sort()
42-
rays[i, size - 1 -j] = ans[0][1].color_at_point(ans[0][2])
54+
rays[i, j] = first_intersection_color(world, l)
4355

4456
tmp.save(path)

testing.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
from geometry import *
22

3+
# Testing sphere methods
4+
35
def test_intersect_True():
46
S = Sphere((0, 0, 0), 1, (10, 200, 20))
5-
l = Line.throughPoints((0, 1, 0), (0, 1, 1))
6-
assert S.intersect(l)
7+
l = Line.through_points((0, 1, 0), (0, 1, 1))
8+
assert S.intersection_value(l) != []
79

810
def test_intersect_False():
911
S = Sphere((100, 100, 100), 0.1, (10, 200, 20))
10-
l = Line.throughPoints((0, 0, 1), (0, 0, 2))
11-
assert S.intersect(l) == False
12+
l = Line.through_points((0, 0, 1), (0, 0, 2))
13+
assert S.intersection_value(l) == []
1214

1315
# Testing vector methods
1416

0 commit comments

Comments
 (0)