def local_intersect(self, shape_ray: Ray) -> GroupIntersections: # TODO: Could avoid having to check all six faces? xtmin, xtmax = check_axis(shape_ray.origin.x, shape_ray.direction.x) ytmin, ytmax = check_axis(shape_ray.origin.y, shape_ray.direction.y) ztmin, ztmax = check_axis(shape_ray.origin.z, shape_ray.direction.z) tmin = max(xtmin, ytmin, ztmin) tmax = min(xtmax, ytmax, ztmax) if tmin > tmax: return GroupIntersections() return GroupIntersections(Intersection(tmin, self), Intersection(tmax, self))
def intersect_caps(self, shape_ray: Ray, xs: GroupIntersections): # caps only matter if the cylinder is closed, and might possibly be # intersected by the ray. if not self.closed or abs(shape_ray.direction.y) < EPSILON: return # check for an intersection with the lower end cap by intersecting # the ray with the plane at y=cyl.minimum t = (self.minimum - shape_ray.origin.y) / shape_ray.direction.y if check_cap(shape_ray, t, self.minimum): xs.add_intersection(Intersection(t, self)) # check for an intersection with the upper end by intersecting # the ray with the plane at y=cyl.maximum t = (self.maximum - shape_ray.origin.y) / shape_ray.direction.y if check_cap(shape_ray, t, self.maximum): xs.add_intersection(Intersection(t, self))
def local_intersect(self, shape_ray: Ray) -> GroupIntersections: a = shape_ray.direction.x ** 2 - shape_ray.direction.y ** 2 + shape_ray.direction.z ** 2 b = 2 * shape_ray.origin.x * shape_ray.direction.x - \ 2 * shape_ray.origin.y * shape_ray.direction.y + \ 2 * shape_ray.origin.z * shape_ray.direction.z xs = GroupIntersections() # if a == 0 and b == 0: if abs(a) < EPSILON and abs(b) < EPSILON: self.intersect_caps(shape_ray, xs) return xs c = (shape_ray.origin.x ** 2) - (shape_ray.origin.y ** 2) + (shape_ray.origin.z ** 2) if abs(a) < EPSILON: t = -c / (2 * b) xs.add_intersection(Intersection(t, self)) self.intersect_caps(shape_ray, xs) return xs discriminant = b ** 2 - 4 * a * c # ray does not intersect the cylinder if discriminant < 0: return GroupIntersections() t0 = (-b - math.sqrt(discriminant)) / (2 * a) t1 = (-b + math.sqrt(discriminant)) / (2 * a) if t0 > t1: t0, t1 = t1, t0 y0 = shape_ray.origin.y + t0 * shape_ray.direction.y if self.minimum < y0 < self.maximum: xs.add_intersection(Intersection(t0, self)) y1 = shape_ray.origin.y + t1 * shape_ray.direction.y if self.minimum < y1 < self.maximum: xs.add_intersection(Intersection(t1, self)) self.intersect_caps(shape_ray, xs) return xs
def local_intersect(self, shape_ray: Ray) -> GroupIntersections: # the vector from the sphere's center, to the ray origin # remember: the sphere is centered at the world origin sphere_to_ray = shape_ray.origin - point(0, 0, 0) a = Vec3.dot(shape_ray.direction, shape_ray.direction) b = 2 * Vec3.dot(shape_ray.direction, sphere_to_ray) c = Vec3.dot(sphere_to_ray, sphere_to_ray) - 1 discriminant = (b**2) - (4 * a * c) if discriminant < 0: return GroupIntersections() else: t1 = Intersection((-b - math.sqrt(discriminant)) / (2 * a), self) if discriminant == 0: return GroupIntersections(t1, t1) t2 = Intersection((-b + math.sqrt(discriminant)) / (2 * a), self) return GroupIntersections( t1, t2) if t1 < t2 else GroupIntersections(t2, t1)
def step_impl(context): context.xs = GroupIntersections(Intersection(2.0, context.A), Intersection(2.75, context.B), Intersection(3.25, context.C), Intersection(4.75, context.B), Intersection(5.25, context.C), Intersection(6.0, context.A))
def local_intersect(self, shape_ray: Ray) -> GroupIntersections: a = shape_ray.direction.x**2 + shape_ray.direction.z**2 # ray is parallel to the y axis if a < EPSILON: xs = GroupIntersections() self.intersect_caps(shape_ray, xs) return xs b = 2 * shape_ray.origin.x * shape_ray.direction.x +\ 2 * shape_ray.origin.z * shape_ray.direction.z c = shape_ray.origin.x**2 + shape_ray.origin.z**2 - 1 discriminant = b**2 - 4 * a * c # ray does not intersect the cylinder if discriminant < 0: return GroupIntersections() t0 = (-b - math.sqrt(discriminant)) / (2 * a) t1 = (-b + math.sqrt(discriminant)) / (2 * a) if t0 > t1: t0, t1 = t1, t0 xs = GroupIntersections() y0 = shape_ray.origin.y + t0 * shape_ray.direction.y if self.minimum < y0 < self.maximum: xs.add_intersection(Intersection(t0, self)) y1 = shape_ray.origin.y + t1 * shape_ray.direction.y if self.minimum < y1 < self.maximum: xs.add_intersection(Intersection(t1, self)) self.intersect_caps(shape_ray, xs) return xs
def local_intersect(self, shape_ray: Ray) -> GroupIntersections: result = GroupIntersections() dir_cross_e2 = Vec3.cross(shape_ray.direction, self.e2) det = Vec3.dot(self.e1, dir_cross_e2) if abs(det) < EPSILON: return result f = 1.0 / det p1_to_origin = shape_ray.origin - self.p1 u = f * Vec3.dot(p1_to_origin, dir_cross_e2) if u < 0 or u > 1: return result origin_cross_e1 = Vec3.cross(p1_to_origin, self.e1) v = f * Vec3.dot(shape_ray.direction, origin_cross_e1) if v < 0 or (u + v) > 1: return result t = f * Vec3.dot(self.e2, origin_cross_e1) return GroupIntersections(Intersection(t, self))
def step_impl(context, t): context.i2 = Intersection(t, context.s)
def step_impl(context, t, attribute): instance = getattr(context, attribute) context.i = Intersection(t, instance)
def step_impl(context): context.xs = GroupIntersections(Intersection(1.8589, context.shape))
def step_impl(context): context.xs = GroupIntersections(Intersection(-1, context.shape), Intersection(1, context.shape))
def step_impl(context): context.xs = GroupIntersections( Intersection(-0.7071067811865476, context.shape), Intersection(0.7071067811865476, context.shape))
def step_impl(context): context.xs = GroupIntersections( Intersection(1.4142135623730951, context.floor))
def step_impl(context): context.xs = GroupIntersections(Intersection(-0.9899, context.A), Intersection(-0.4899, context.B), Intersection(0.4899, context.B), Intersection(0.9899, context.A))