Permalink
Browse files

Better 3D effects

  • Loading branch information...
adusca committed Dec 28, 2014
1 parent cf251ab commit 3da6d8185c4621aa059453823605f07b4c15e620
Showing with 43 additions and 26 deletions.
  1. +15 −3 geometry.py
  2. +28 −23 render.py
View
@@ -50,12 +50,15 @@ def intersection_value(self, line):
else:
return []
def color_at_point(self, p):
if int(p[0]) % 2 == int(p[1]) % 2:
def color_at_point(self, point):
if int(point[0]) % 2 == int(point[1]) % 2:
return self.color1
else:
return self.color2
def normal(self, point):
return Vector((0, 0, 1))
class Sphere():
def __init__(self, center, radius, color):
"""
@@ -77,9 +80,14 @@ def intersection_value(self, line):
C = q.squared_norm() - self.radius**2
return solve_quadradic(A, B, C)
def color_at_point(self, p):
def color_at_point(self, point):
return self.color
def normal(self, point):
line = Line.through_points(self.center, point)
q = Vector(line.slope)
return q.normalize()
class Vector():
def __init__(self, coords):
self.coords = coords
@@ -118,6 +126,10 @@ def project(self, v2):
n = float(self.scalar_product(v2))/v2.scalar_product(v2)
return v2.mul_by_number(n)
def normalize(self):
n = 1.0/self.norm()
return self.mul_by_number(n)
def solve_quadradic(a, b, c):
delta = b**2 - 4*a*c
if delta < 0:
View
@@ -1,19 +1,14 @@
from geometry import *
from PIL import Image
path = "./rays.png"
size = 300
tmp = Image.new('RGB', (size, size), "white")
rays = tmp.load()
def coordinates(num, sz = size):
def coordinates(num, sz):
"""
Take a number in range(size) and returns the proportional value between 1 and 5
"""
return 4.0*num/(sz - 1) + 1
def create_world():
S1 = Sphere((4, 4, 2), 2, (100, 220, 0))
S1 = Sphere((1, 4, 2), 2, (100, 220, 0))
S2 = Sphere((2, 2, 1), 1, (0, 100, 200))
S3 = Sphere((3, 1, 1), 1, (100, 100, 200))
P = HorizontalPlane(0, (200, 100, 200), (0, 20, 200))
@@ -31,26 +26,36 @@ def first_intersection(scene, line):
ans.sort()
return [ans[0]]
def first_intersection_color(scene, line):
def first_intersection_color(scene, line, light):
ans = first_intersection(scene, line)
if not ans:
return (255, 255, 255)
to_light = first_intersection(scene, Line.through_points(ans[0][2], light))
l = Line.through_points(ans[0][2], light)
to_light = first_intersection(scene, l)
if to_light and to_light[0][0] < 1:
return (0, 0, 0)
return ans[0][1].color_at_point(ans[0][2])
a, b, c = ans[0][1].color_at_point(ans[0][2])
vector1 = Vector(l.slope).normalize()
vector2 = ans[0][1].normal(ans[0][2])
cos = vector1.scalar_product(vector2)
return (int(a*cos), int(b*cos), int(c*cos))
world = create_world()
camera = (3, -1, 3)
light = (3, -1, 5)
def render(size):
path = "./rays.png"
tmp = Image.new('RGBA', (size, size), "white")
rays = tmp.load()
world = create_world()
camera = (2, -1, 3)
light = (3, -1, 10)
# Colouring each pixel
for i in range(size):
x0 = coordinates(i, size)
for k in range(size):
y0 = coordinates(k, size)
j = size - 1 - k
l = Line.through_points(camera, (x0, 0, y0))
rays[i, j] = first_intersection_color(world, l, light)
tmp.save(path)
# Colouring each pixel
for i in range(size):
x0 = coordinates(i)
for k in range(size):
y0 = coordinates(k)
j = size - 1 - k
l = Line.through_points(camera, (x0, 0, y0))
rays[i, j] = first_intersection_color(world, l)
tmp.save(path)
render(300)

0 comments on commit 3da6d81

Please sign in to comment.