This repository was archived by the owner on Apr 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIntersectable.py
More file actions
101 lines (74 loc) · 2.99 KB
/
Intersectable.py
File metadata and controls
101 lines (74 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import numpy as np
from utility import *
# incomplete material class
class Material:
def __init__(self, reflection, color):
self.reflection = reflection
self.color = np.array([color[0], color[1], color[2]]) if color else None
class Intersectable:
def intersect_test(self, ray):
pass
def get_color(self, intersection=None):
pass
def get_normal(self):
pass
class Sphere(Intersectable):
def __init__(self, center, radius, material):
self.origin = np.array(center) # 3D coordinates of sphere center
self.radius = radius
self.material = material
def get_normal(self, intersection):
return normalize(intersection - self.origin)
def get_color(self, intersection=None):
return self.material.color
def intersect_test(self, ray):
return solve_quadratic_equation(ray, self)
class Plane(Intersectable):
def __init__(self, origin, normal, material):
self.origin = np.array(origin)
self.normal = np.array(normal)
self.material = material
self.checker = False if self.material.color else True
def get_normal(self, intersection):
return normalize(self.normal)
def intersect_test(self, ray):
rD = ray.direction
rO = ray.origin
pN = self.normal
pO = self.origin
rOY = rO[1] # ray origin y component
pOY = pO[1] # plane origin y component
rDY = rD[1] # ray direction y component
d = -((rOY - pOY) / rDY)
#d = -(np.dot(rO, pN) + 1) / np.dot(rD, pN)
if d > 0.001 and d < 1e6: # prevent shadow acne by checking above 0.001
return d
return None
def get_color(self, intersection=None):
if self.checker:
return self.checker_color(intersection)
return self.material.color
# checkerboard pattern logic borrowed from here:
# https://github.com/carl-vbn/pure-java-raytracer/blob/23300fca6e9cb6eb0a830c0cd875bdae56734eb7/src/carlvbn/raytracing/solids/Plane.java#L32
def checker_color(self, intersection):
point = intersection - self.origin
pX = int(point[0])
pZ = int(point[2])
# for every other x and z position that is even, color the pixel white, otherwise beige
if ((pX % 2 == 0) == (pZ % 2 == 0)):
return np.array([252, 204, 116])
else:
return np.array([30,30,30])
class Light(Intersectable):
def __init__(self, position, intensity, material):
self.origin = np.array(position)
self.radius = 0.1
self.intensity = intensity
self.material = material
# treat light points as a sphere
def intersect_test(self, ray):
return solve_quadratic_equation(ray, self)
def get_color(self, intersection=None):
return self.material.color
def get_normal(self, intersection):
return normalize(intersection - self.origin)