Permalink
Browse files

Finding the closest sphere

  • Loading branch information...
adusca committed Dec 24, 2014
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
View
@@ -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)
View
@@ -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)
View
@@ -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

0 comments on commit a9c55cf

Please sign in to comment.