{{ message }}

Finding the closest sphere
1 parent 8e27e37 commit a9c55cf147658903a5a3e112d378cb5625e5e68e
Showing with 49 additions and 19 deletions.
1. +23 −4 geometry.py
2. +24 −13 render.py
3. +2 −2 testing.py
 @@ -41,10 +41,17 @@ def __init__(self, center, radius, color): self.color = color def intersect(self, line): if line.distanceToPoint(self.center) <= self.radius: return self.color else: return (255, 255, 255) return line.distanceToPoint(self.center) <= self.radius def intersection_value(self, line): v = Vector(line.slope) s = Vector(line.start) c = Vector(self.center) q = s.subtract(c) A = sum(x*x for x in v.coords) B = sum(-2*x*y for (x, y) in zip(v.coords, q.coords)) C = sum(y*y for y in q.coords) - self.radius**2 return solve_quadradic((A, B, C)) class Vector(): def __init__(self, coords): @@ -77,3 +84,15 @@ def mul_by_number(self, num): def project(self, v2): n = float(self.scalar_product(v2))/v2.scalar_product(v2) return v2.mul_by_number(n) def solve_quadradic(coef): a = coef[0] b = coef[1] c = coef[2] delta = b**2 - 4*a*c ans = [] ans.append(-b + sqrt(delta)/2.0*a) x = -b - sqrt(delta)/2.0*a if x >= 0: ans.append(x) return min(ans)
 @@ -2,26 +2,37 @@ from PIL import Image path = "./rays.png" tmp = Image.new('RGB', (200, 200), "white") size = 300 tmp = Image.new('RGB', (size, size), "white") rays = tmp.load() def coordinates(num): def coordinates(num, sz = size): """ Take a number between 0 and 199 and returns the proportional value between -2 and 2 Take a number in range(size) and returns the proportional value between -2 and 2 """ return 8.0*num/199.0 - 2.0 S = Sphere((0, 0, 0), 0.5, (0, 0, 0)) origin = (-10, 0, 0) return 4.0*num/(sz - 1) - 2.0 # Creating the world S1 = Sphere((1, 0, 0), 0.5, (10, 220, 0)) S2 = Sphere((0.6, 0, 0), 0.5, (200, 10, 200)) camera = (0, 0, -8) world = [S1, S2] for i in range(200): # Colouring each pixel for i in range(size): x0 = coordinates(i) for j in range(200): for j in range(size): y0 = coordinates(j) l = Line.throughPoints(origin, (x0, y0, -5)) rays[i, j] = S.intersect(l) l = Line.throughPoints(camera, (x0, y0, -5)) ans = [] for S in world: if S.intersect(l): ans.append((S.intersection_value(l), S)) if not ans: rays[i, j] = (255, 255, 255) else: ans.sort() rays[i, j] = ans[0][1].color tmp.save(path)
 @@ -3,12 +3,12 @@ def test_intersect_True(): S = Sphere((0, 0, 0), 1, (10, 200, 20)) l = Line.throughPoints((0, 1, 0), (0, 1, 1)) assert S.intersect(l) == (10, 200, 20) assert S.intersect(l) def test_intersect_False(): S = Sphere((100, 100, 100), 0.1, (10, 200, 20)) l = Line.throughPoints((0, 0, 1), (0, 0, 2)) assert S.intersect(l) == (255, 255, 255) assert S.intersect(l) == False # Testing vector methods