Skip to content

Instantly share code, notes, and snippets.

@RicherMans
Last active August 29, 2015 14:23
Show Gist options
  • Select an option

  • Save RicherMans/984f3f849966324a39fb to your computer and use it in GitHub Desktop.

Select an option

Save RicherMans/984f3f849966324a39fb to your computer and use it in GitHub Desktop.
Raytraceing example
import numpy as np
from collections import namedtuple
from scipy.misc import imsave
from matplotlib import pyplot as plt
import functools
import time
import argparse
AMBIENT = 0.1
SCENE_W = 300
SCENE_H = 400
InterSection = namedtuple('InterSection', ['point', 'dist', 'normal', 'obj'])
SPECULAR_K = 30.
LIGHT_COLOR = np.ones(3)
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument()
return parser.parse_args()
def Vec3(x=0, y=0, z=0):
return np.array([x, y, z])
def normalize(vec):
return vec / np.sqrt((vec ** 2).sum(-1))[..., np.newaxis]
class Ray:
def __init__(self, pos, direction):
self.direction = normalize(direction)
self.pos = pos
class Plane:
def __init__(self, point, normal, color):
'''
Function: __init__
Summary:
Examples:
Attributes:
@param (self):
@param (point):
@param (normal):
@param (color):
Returns:
'''
self.normal = normal
self.point = point
self.color = color
self.diffuse_c = 0.75
self.specular_c = 0.80
@property
def diffuse_c(self):
return self._diffuse_c
@property
def specular_c(self):
return self._specular_c
def intersect(self, ray):
# Projection of the plane normal to the ray, aka, if its orthogonal
# there is no way we can have an intersection
ndot = self.normal.dot(ray.direction.T)
if (ndot == 0):
return None
dist = (self.normal.dot((self.point - ray.pos).T) / ndot)
return InterSection(ray.pos + ray.direction * dist, dist, self.normal, self)
class Poly(Plane):
def __init__(self, verts, n, color):
self.verts = verts
Plane.__init__(self, point=verts[0], normal=n, color=color)
def intersect(self, ray):
x = Plane.intersect(self, ray)
if x is None:
return None
for i in xrange(1, len(self.verts)):
if self._sameside(self.verts[i], self.verts[i - 1], x.point) < 0:
return None
return x
def _sameside(self, a, b, x):
return self.normal.dot(np.cross((b - a), (x - a)))
class Triangle(Poly):
def __init__(self, a, b, c, n, color):
Poly.__init__(self, verts=[a, b, c], n=n, color=color)
class Rect():
def __init__(self, a, b, n, color):
self.a = a
self.b = b
self.normal = n
self.color = color
def intersect(self, ray):
tx1 = (self.a[0] - ray.pos[0])
tx2 = (self.b[0] - ray.pos[0])
tmin = min(tx1, tx2)
tmax = max(tx1, tx2)
class Sphere():
def __init__(self, center, radius, color):
self.center = center
self.radius = radius
self.color = color
self.diffuse_c = 0.89
self.specular_c = 0.7
@property
def diffuse_c(self):
return self._diffuse_c
@property
def specular_c(self):
return self._specular_c
def intersect(self, ray):
# d=-(\mathbf{l}\cdot(\mathbf{o}-\mathbf{c})) \pm
# \sqrt{(\mathbf{l}\cdot(\mathbf{o}-\mathbf{c}))^2-\left\Vert\mathbf{o}-\mathbf{c}\right\Vert^2+r^2}
posMCenter = ray.pos - self.center
decision = ray.direction.dot(
posMCenter.T)**2 - posMCenter.dot(posMCenter.T) + self.radius**2
if decision < 0:
return None
lhs = - ray.direction.dot(posMCenter.T)
d1 = lhs - np.sqrt(decision)
d2 = lhs + np.sqrt(decision)
d = min(d1, d2)
if d < 0:
return None
return InterSection(ray.pos + ray.direction * d, d, self._normal(ray.pos + ray.direction * d), self)
def _normal(self, vec):
return normalize(vec - self.center)
class Cylinder:
def __init__(self, center, radius, height, color):
self.center = center
self.radius = radius
self.height = height
self.color = color
class Cube(Poly):
def __init__(self, a, b, c, d, n, color):
Poly.__init__(self, [a, b, c, d], n, color)
class Scene:
def __init__(self, camera):
self.objs = []
self.lightsources = []
self.camera = camera
def addObj(self, obj):
self.objs.append(obj)
def addLight(self, light):
self.lightsources.append(light)
@property
def camera(self):
return self._camera
def _intersectRay(self, ray, ignoreobj=None):
intersection = None
maxdistance = np.i
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment