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.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: 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