Exemplo n.º 1
0
    def hit(self, ray: vector.Ray, t_min: float, t_max: float):

        oc = ray.origin - self.center
        a = ray.direction.length_squared()
        half_b = vector.dot(oc, ray.direction)
        c = oc.length_squared() - self.radius * self.radius
        discriminant = half_b * half_b - a * c

        if discriminant > 0:
            root = math.sqrt(discriminant)
            temp = (-half_b - root) / a
            if t_min < temp < t_max:
                hit_rec = HitRecord(None, None, None, None)
                hit_rec.t = temp
                hit_rec.position = ray.at(hit_rec.t)
                hit_rec.material = self.m
                outward_normal = (hit_rec.position - self.center).divide(
                    self.radius)
                hit_rec.set_face_normal(ray, outward_normal)
                return True, hit_rec

            temp = (-half_b + root) / a
            if t_min < temp < t_max:
                hit_rec = HitRecord(None, None, None, None)
                hit_rec.t = temp
                hit_rec.position = ray.at(hit_rec.t)
                hit_rec.material = self.m
                outward_normal = (hit_rec.position - self.center).divide(
                    self.radius)
                hit_rec.set_face_normal(ray, outward_normal)
                return True, hit_rec

        return False, None
Exemplo n.º 2
0
	def test_intersect5(self):
		r = Ray(point(0, 0, 5), vector(0, 0, 1))
		s = Sphere()
		i = s.intersect(r)
		self.assertEqual(2, len(i))
		self.assertEqual(-6.0, i[0].t)
		self.assertEqual(-4.0, i[1].t)
Exemplo n.º 3
0
    def scatter(self, ray_in: Ray, collision: HitRecord) -> MaterialRecord:
        color = Color(1, 1, 1)

        if collision.resultant_outward:
            incoming_index, outgoing_index = 1.0, self.index_of_refraction
        else:
            incoming_index, outgoing_index = self.index_of_refraction, 1.0

        index_ratio = incoming_index / outgoing_index
        direction = ray_in.direction.unit()
        normal = collision.resultant.direction

        cos_theta = -direction @ normal
        sin_theta = sqrt(max(1 - cos_theta**2, 0))

        # Use the Schlick approximation to calculate reflectance
        r_0 = ((1 - index_ratio) / (1 + index_ratio))**2
        reflectance = r_0 + (1 - r_0) * (1 - cos_theta)**5

        snell_solvable = sin_theta * index_ratio <= 1.0
        schlick_within_range = reflectance <= random()
        can_refract = snell_solvable and schlick_within_range

        if can_refract:
            outgoing_direction = refract_across(direction, normal, index_ratio)
        else:
            outgoing_direction = reflect_across(direction, normal)

        outgoing_ray = Ray(collision.resultant.base, outgoing_direction)
        return MaterialRecord(color=color, outgoing_ray=outgoing_ray)
Exemplo n.º 4
0
def loop_simulation(dt):
    global slave_error

    if (run_auto):
        if (slave_device_pos_tween.done() and slave_device_rot_tween.done()):
            scene_vectormanager.clear()
            update_slave_sensor()

    slave_device.pos = slave_device_pos_tween.step(dt * 10)
    slave_device.rot = slave_device_rot_tween.step(dt * 10)

    scene_vectormanager.clear(15)
    for r in view_rays:
        scene_vectormanager.addRay(r, color=(0, 0, 1, 1), group=15)

    if print_timer.tick():
        scene_vectormanager.clear(10)
        target_rays = lighthouse.getRays(target_device)
        delta_vecs = []
        for ray, sp in zip(target_rays, [
                slave_device.pos + rsp.rotate(slave_device.rot)
                for rsp in slave_device.sensorpos
        ]):
            np = ray.nearest(sp)
            if np:
                delta_vecs.append(np - sp)
                scene_vectormanager.addRay(Ray(sp, np - sp),
                                           color=(1, 1, 1, 1),
                                           group=10)

        slave_error = sum([vec.magnitude() for vec in delta_vecs])
        print "E:", slave_error, "FS:", face_sums
Exemplo n.º 5
0
	def test_intersect_sphere1(self):
		s = Sphere()
		r = Ray(point(0, 0, -5), vector(0, 0, 1))
		s.set_transform(xf_scale(2, 2, 2))
		i = s.intersect(r)
		self.assertEqual(2, len(i))
		self.assertEqual(i[0].t, 3.0)
		self.assertEqual(i[1].t, 7.0)
Exemplo n.º 6
0
    def get_ray(self, horizontal_component, vertical_component):
        offset = self._get_offset()
        base = self.look_from + offset

        direction = self.lower_left +\
            (horizontal_component * self.horizontal) +\
            (vertical_component * self.vertical) -\
            base

        return Ray(base, direction)
Exemplo n.º 7
0
    def scatter(self, ray_in: Ray, collision: HitRecord) -> MaterialRecord:
        base = collision.resultant.base
        direction = collision.resultant.direction.unit()

        reflected_direction = direction + random_in_hemisphere(direction)
        if reflected_direction.near_zero():
            reflected_direction = direction

        reflected_ray = Ray(base, reflected_direction)
        color = self.albedo

        return MaterialRecord(outgoing_ray=reflected_ray, color=color)
Exemplo n.º 8
0
    def scatter(self, ray_in: Ray, collision: HitRecord) -> MaterialRecord:
        base = collision.resultant.base
        incoming_direction = ray_in.direction.unit()
        normal = collision.resultant.direction.unit()
        fuzz = random_in_sphere() * self.fuzziness

        reflected_direction = reflect_across(incoming_direction, normal) + fuzz
        if reflected_direction.near_zero():
            reflected_direction = direction

        reflected_ray = Ray(base, reflected_direction)
        color = self.albedo
        absorbed = (reflected_direction @ normal) < 0

        return MaterialRecord(outgoing_ray=reflected_ray,
                              color=color,
                              absorbed=absorbed)
Exemplo n.º 9
0
    def hit(self, ray: Ray, t_min=0, t_max=INF) -> HitRecord:
        base_to_center = ray.base - self.center

        a = ray.direction @ ray.direction
        b = ray.direction @ base_to_center
        c = base_to_center @ base_to_center - self.radsquared

        discriminant = b**2 - a * c

        # Not hit
        if discriminant <= 0:
            return HitRecord()

        sqrt_discriminant = np.sqrt(discriminant)

        def roots():
            yield from [(-b - sqrt_discriminant) / a,
                        (-b + sqrt_discriminant) / a]

        for sphere_hit_coordinate in roots():
            in_bounds = t_min < sphere_hit_coordinate < t_max
            if not in_bounds:
                continue

            sphere_boundary = ray(sphere_hit_coordinate)
            outward_normal = (sphere_boundary - self.center) / self.radius
            normal = Ray(sphere_boundary, outward_normal)

            record = HitRecord(resultant=normal,
                               t=sphere_hit_coordinate,
                               material=self.material)

            record.orient(ray, outward_normal)
            return record

        return HitRecord()
Exemplo n.º 10
0
	def test_translate_ray2(self):
		r = Ray(point(1, 2, 3), vector(0, 1, 0))
		m = xf_scale(2, 3, 4)
		r2 = r.transform(m)
		self.assertEqual(r2.origin, point(2, 6, 12))
		self.assertEqual(r2.direction, vector(0, 3, 0))
Exemplo n.º 11
0
	def test_translate_ray1(self):
		r = Ray(point(1, 2, 3), vector(0, 1, 0))
		m = xf_translate(3, 4, 5)
		r2 = r.transform(m)
		self.assertEqual(r2.origin, point(4, 6, 8))
		self.assertEqual(r2.direction, vector(0, 1, 0))
Exemplo n.º 12
0
	def test_intersect3(self):
		r = Ray(point(0, 2, -5), vector(0, 0, 1))
		s = Sphere()
		i = s.intersect(r)
		self.assertEqual(0, len(i))
Exemplo n.º 13
0
	def test_ray_postion1(self):
		r = Ray(point(2, 3, 4), vector(1, 0, 0))
		self.assertEqual(r.position(0), point(2, 3, 4))
		self.assertEqual(r.position(1), point(3, 3, 4))
		self.assertEqual(r.position(-1), point(1, 3, 4))
		self.assertEqual(r.position(2.5), point(4.5, 3, 4))
Exemplo n.º 14
0
def update_slave_sensor():
    global slave_state
    global slave_rays
    global slave_pos_delta
    global slave_rot_delta
    global slave_device_pos_tween
    global slave_device_rot_tween
    global target_index
    global slave_error
    global face_sums

    slave_device.pos = slave_device_pos_tween.finish()
    slave_device.rot = slave_device_rot_tween.finish()

    _slave_rays = lighthouse.getRays(slave_device)
    scene_vectormanager.clear(4)
    for ray in _slave_rays:
        scene_vectormanager.addRay(ray, color=(1, 0.5, 0.5, 1), group=4)

    if slave_state == SS_CAST_RAYS:

        slave_rays = lighthouse.getRays(target_device)
        for ray in slave_rays:
            scene_vectormanager.addRay(ray, color=(1, 1, 0, 1), group=1)
        slave_state = SS_COMPUTE_POS_DELTA

    elif slave_state == SS_COMPUTE_POS_DELTA:

        translation_rays = []
        face_sums = []

        slave_sensorpos = slave_device.getWorldSensorPos()
        target_sensorpos = []

        for ray, sp, rsp in zip(
                slave_rays, slave_sensorpos,
            [sp.rotate(slave_device.rot) for sp in slave_device.sensorpos]):
            np = ray.nearest(sp)
            if np:
                target_sensorpos.append(np)
                translation_ray = Ray(sp, np - sp)
                translation_rays.append(translation_ray)
                scene_vectormanager.addRay(translation_ray,
                                           color=(1, 0, 0, 1),
                                           group=2)
                face_sums.append(math.copysign(1.0, (np - sp).dot(rsp)))

        slave_aabb = Vector3.enclosingAABB(slave_sensorpos)
        target_aabb = Vector3.enclosingAABB(target_sensorpos)

        target_pos = Vector3.average(target_sensorpos)
        lighthouse_vector = target_pos - lighthouse.pos

        target_aabb_size = (target_aabb[0] - target_aabb[1]).magnitude()
        if (target_aabb_size > 0):
            lighthouse_vector = (lighthouse_vector *
                                 ((slave_aabb[0] - slave_aabb[1]).magnitude() /
                                  target_aabb_size - 1.0))
        else:
            lighthouse_vector = Vector3.zero

        average_vec = Vector3.average([tr.vec for tr in translation_rays])

        #if(face_sum < 0):
        #    average_vec *= abs(face_sum)

        scene_vectormanager.addVector(slave_device.pos,
                                      average_vec,
                                      color=(1, 1, 1, 1),
                                      group=2)
        scene_vectormanager.addVector(slave_device.pos + average_vec,
                                      lighthouse_vector,
                                      color=(1, 1, 1, 1),
                                      group=2)

        slave_pos_delta = average_vec + lighthouse_vector
        slave_state = SS_APPLY_POS_DELTA

    elif slave_state == SS_APPLY_POS_DELTA:

        scene_vectormanager.clear(2)
        slave_device_pos_tween.__init__(slave_device.pos,
                                        slave_device.pos + slave_pos_delta,
                                        10.0)
        slave_state = SS_COMPUTE_ROT_DELTA

    elif slave_state == SS_COMPUTE_ROT_DELTA:

        rotation_rays = []
        rotation_quats = []

        options = zip(
            slave_rays, slave_device.getWorldSensorPos(),
            [sp.rotate(slave_device.rot) for sp in slave_device.sensorpos])
        for ray, sp, rsp in options:
            np = ray.nearest(sp)
            if np:
                rotation_ray = Ray(sp, np - sp)
                rnp = np - slave_device.pos
                rotation_rays.append(rotation_ray)
                scene_vectormanager.addRay(rotation_ray,
                                           color=(0, 1, 0, 1),
                                           group=3)

                rotation_quats.append(Quaternion.rotationBetween(rsp, rnp))

        average_rot = Quaternion.average(rotation_quats)
        average_rotation = average_rot

        scene_vectormanager.addVector(slave_device.pos,
                                      average_rotation.toAxisAngle()[0],
                                      color=(1, 1, 1, 1),
                                      group=3)

        slave_rot_delta = average_rotation
        slave_state = SS_APPLY_ROT_DELTA

    elif slave_state == SS_APPLY_ROT_DELTA:

        scene_vectormanager.clear(3)
        slave_device_rot_tween.__init__(slave_device.rot,
                                        slave_rot_delta * slave_device.rot,
                                        10.0)
        slave_state = SS_COMPUTE_POS_DELTA