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
Esempio n. 4
0
    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))
Esempio n. 6
0
    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))
Esempio n. 8
0
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))