Check out the Pastebin Gadgets Shop. We have thousands of fun, geeky & affordable gadgets on sale :-)Want more features on Pastebin? Sign Up, it's FREE!
tweet

# Untitled

By: a guest on Jan 10th, 2013  |  syntax: Python  |  size: 5.61 KB  |  views: 48  |  expires: Never
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
1. #tiny-tracer-no-vector-class. 2x speedup.
2.
3. #original pastebin: http://pastebin.com/F8f5GHJZ
5.
6. import timeit
7.
8. from math import sqrt, pow, pi
9. import Image, sys
10.
11. def vMul(a,b):  return ( a[0]*b[0], a[1]*b[1], a[2]*b[2] )
12. def vMulD(a,b): return ( a[0]*b,    a[1]*b,    a[2]*b    )
13. def vAdd(a,b):  return ( a[0]+b[0], a[1]+b[1], a[2]+b[2] )
14. def vAddD(a,b): return ( a[0]+b,    a[1]+b,    a[2]+b    )
15. def vSub(a,b):  return ( a[0]-b[0], a[1]-b[1], a[2]-b[2] )
16. def vSubD(a,b): return ( a[0]-b,    a[1]-b,    a[2]-b    )
17. def vNeg(a):    return (-a[0],     -a[1],     -a[2]      )
18. def vPow(a,b):  return ( a[0]**b,   a[1]**b,   a[2]**b   )
19.
20. def vDot(a,b):  return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]
21. def vSqr(a):    return vDot(a,a)
22. def vLen(a):    return sqrt(vSqr(a))
23. def vNorm(a):   return vMulD(a, 1.0/vLen(a))
24.
25. class Sphere( object ):
26.
27.         def __init__(self, center, radius, color):
28.                 self.c = center
30.                 self.col = color
31.
32.         def intersection(self, l):
33.                 q = vDot(l.d, vSub(l.o, self.c))**2 - vSqr(vSub(l.o, self.c)) + self.r**2
34.                 if q < 0:
35.                         return Intersection( (0,0,0), -1, (0,0,0), self)
36.                 else:
37.                         d = -vDot(l.d, vSub(l.o, self.c))
38.                         d1 = d - sqrt(q)
39.                         d2 = d + sqrt(q)
40.                         if 0 < d1 and ( d1 < d2 or d2 < 0):
42.                         elif 0 < d2 and ( d2 < d1 or d1 < 0):
44.                         else:
45.                                 return Intersection( (0,0,0), -1, (0,0,0), self)
46.
47.         def normal(self, b):
48.                 return vNorm(vSub(b,self.c))
49.
50. class Plane( object ):
51.
52.         def __init__(self, point, normal, color):
53.                 self.n = normal
54.                 self.p = point
55.                 self.col = color
56.
57.         def intersection(self, l):
58.                 d = vDot(l.d, self.n)
59.                 if d == 0:
60.                         return Intersection( (0,0,0), -1, vector(0,0,0), self)
61.                 else:
62.                         d = vDot(vSub(self.p,l.o),self.n) / d
63.                         return Intersection(vAdd(l.o,vMulD(l.d,d)), d, self.n, self)
64.
65. class Ray( object ):
66.
67.         def __init__(self, origin, direction):
68.                 self.o = origin
69.                 self.d = direction
70.
71. class Intersection( object ):
72.
73.         def __init__(self, point, distance, normal, obj):
74.                 self.p = point
75.                 self.d = distance
76.                 self.n = normal
77.                 self.obj = obj
78.
79. def testRay(ray, objects, ignore=None):
80.         intersect = Intersection( (0,0,0), -1, (0,0,0), None)
81.
82.         for obj in objects:
83.                 if obj is not ignore:
84.                         currentIntersect = obj.intersection(ray)
85.                         if currentIntersect.d > 0 and intersect.d < 0:
86.                                 intersect = currentIntersect
87.                         elif 0 < currentIntersect.d < intersect.d:
88.                                 intersect = currentIntersect
89.         return intersect
90.
91. def trace(ray, objects, light, maxRecur):
92.         if maxRecur < 0:
93.                 return (0,0,0)
94.         intersect = testRay(ray, objects)
95.         if intersect.d == -1:
96.                 col = (AMBIENT,AMBIENT,AMBIENT)
97.         elif vDot(intersect.n, vSub(light,intersect.p)) < 0:
98.                 col = vMulD(intersect.obj.col, AMBIENT)
99.         else:
100.                 lightRay = Ray(intersect.p, vNorm(vSub(light,intersect.p)))
101.                 if testRay(lightRay, objects, intersect.obj).d == -1:
102.                         lightIntensity = 1000.0/(4*pi*vLen(vSub(light,intersect.p))**2)
103.                         col = vMulD(intersect.obj.col, max(vDot(vNorm(intersect.n),vMulD(vNorm(vSub(light,intersect.p)),lightIntensity)), AMBIENT))
104.                 else:
105.                         col = vMulD(intersect.obj.col, AMBIENT)
106.         return col
107.
108. def gammaCorrection(color,factor):
109.         return (int(pow(color[0]/255.0,factor)*255),
110.                         int(pow(color[1]/255.0,factor)*255),
111.                         int(pow(color[2]/255.0,factor)*255))
112.
113. AMBIENT = 0.1
114. GAMMA_CORRECTION = 1/2.2
115. MAX_RECURSION = 10
116.
117. #these are left global so we don't have to pass them to apply_async each pixel
118. objs = ( Sphere((-2, 0,-10), 2,   (0,255,0)),
119.          Sphere(( 2, 0,-10), 3.5, (255,0,0)),
120.          Sphere(( 0,-4,-10), 3,   (0,0,255)),
121.          Plane((0,0,-12), (0,0,1), (255,255,255)) )
122.
123. lightSource = (0,10,0)
124. cameraPos = (0,0,20)
125.
126. def main():
127.         img = Image.new("RGB",(500,500))
128.         for x in range(500):
129.                 results = []
130.                 for y in range(500):
131.                         ray =  Ray(cameraPos, vNorm(vSub((x/50.0-5, y/50.0-5, 0), cameraPos)))
132.                         col = trace(ray, objs, lightSource, MAX_RECURSION)
133.                         img.putpixel((x,499-y),gammaCorrection(col,GAMMA_CORRECTION))
134.         img.save("trace.bmp","BMP")
135.
136. if __name__ == '__main__':
137.         timer = timeit.Timer(stmt='main()',setup="from __main__ import main")
138.         t = timer.timeit(number=1)
139.         print "t = %f"%t
clone this paste RAW Paste Data
Top