def intersect(self, raypos, raydir): tr = self.transform raydir = tr.inv_transform_vector(raydir) scale = 1.0 / length(raydir) raydir = mul(raydir, scale) # normalize raypos = tr.inv_transform_point(raypos) s = dot(neg(raypos), raydir) lsq = dot(raypos, raypos) if s < 0.0 and lsq > 1.0: return [] msq = lsq - s * s if msq > 1.0: return [] q = math.sqrt(1.0 - msq) t1 = s + q t2 = s - q if t1 > t2: t1, t2 = t2, t1 ts = [] if t1 > 0.0: ts.append( Intersection(scale, t1, raypos, raydir, self, Intersection.ENTRY, 0)) if t2 > 0.0: ts.append( Intersection(scale, t2, raypos, raydir, self, Intersection.EXIT, 0)) return ts
def get_intensity(self, pos): q = sub(self.pos, pos) dsq = dot(q, q) invlend = 1 / math.sqrt(dsq) cosangle = -dot(q, self.d) * invlend if cosangle < self.coscutoff: return (0.0, 0.0, 0.0) i = pow(dot(self.d, mul(d, -invlend)), self.exp) return mul(self.color, i * 100.0 / (99.0 + dsq))
def trace(amb, lights, scene, depth, raypos, raydir): i = scene.intersect(raypos, raydir) if i: #for ic in i: # print ic #print isect = i[0] if isect.t == Intersection.EXIT: return (0.0, 0.0, 0.0) sc, kd, ks, n = isect.primitive.get_surface(isect) c = get_ambient(sc, amb, kd) diffuse = (0.0, 0.0, 0.0) specular = (0.0, 0.0, 0.0) pos = isect.wpos normal = isect.normal for light in lights: lightdir, lightdistance = light.get_direction(pos) df = dot(normal, lightdir) if df > 0.0: poseps = add(pos, mul(lightdir, 1e-7)) i = scene.intersect(poseps, lightdir) if not i or (lightdistance and (lightdistance < i[0].distance)): ic = cmul(sc, light.get_intensity(pos)) if kd > 0.0: diffuse = add(diffuse, mul(ic, df)) if ks > 0.0: specular = add( specular, get_specular(ic, lightdir, normal, pos, raypos, n)) c = add(c, add(mul(diffuse, kd), mul(specular, ks))) if ks > 0.0 and depth > 0: refl_raydir = normalize( sub(raydir, mul(normal, 2 * dot(raydir, normal)))) poseps = add(pos, mul(refl_raydir, 1e-7)) rc = trace(amb, lights, scene, depth - 1, poseps, refl_raydir) return add(c, mul(cmul(rc, sc), ks)) else: return c else: return (0.0, 0.0, 0.0)
def intersect(self, raypos, raydir): tr = self.transform raydir = tr.inv_transform_vector(raydir) scale = 1.0 / length(raydir) raydir = mul(raydir, scale) # normalize raypos = tr.inv_transform_point(raypos) np = self.np denom = dot(np, raydir) if abs(denom) < 1e-7: return [] t = -dot(np, raypos) / denom if t < 0.0: return [] if denom > 0.0: return [ Intersection(scale, t, raypos, raydir, self, Intersection.EXIT, 0) ] else: return [ Intersection(scale, t, raypos, raydir, self, Intersection.ENTRY, 0) ]
def get_specular(ic, lightdir, sn, pos, raypos, n): halfway = normalize(add(lightdir, normalize(sub(raypos, pos)))) sp = dot(sn, halfway) if sp > 0.0: return mul(ic, pow(sp, n)) return (0.0, 0.0, 0.0)
def get_intensity(self, pos): d = sub(self.pos, pos) dsq = dot(d, d) return mul(self.color, 100.0 / (99.0 + dsq))
def covariance(x, y): n = len(x) return vecmat.dot(de_mean(x), de_mean(y)) / (n - 1)
def test1(self): self.assertEqual(vecmat.dot(v, w), 32)