def ray4(FOVh, FOVv):
     '''
     Parameters:
         FOVh (float): Horizontal field of view in radians
         FOVv (float): Vertical field of view in radians
     Returns:
         vector3d.vector.Vector: normalised vector
     '''
     ray = Vector(-math.tan(FOVv / 2), math.tan(FOVh / 2), -1)
     return ray.normalize()
    def rotateRays(ray1, ray2, ray3, ray4, roll, pitch, yaw):
        """Rotates the four ray-vectors around all 3 axes
        Parameters:
            ray1 (vector3d.vector.Vector): First ray-vector
            ray2 (vector3d.vector.Vector): Second ray-vector
            ray3 (vector3d.vector.Vector): Third ray-vector
            ray4 (vector3d.vector.Vector): Fourth ray-vector
            roll float: Roll rotation
            pitch float: Pitch rotation
            yaw float: Yaw rotation
        Returns:
            Returns new rotated ray-vectors
        """
        sinAlpha = math.sin(yaw)
        sinBeta = math.sin(pitch)
        sinGamma = math.sin(roll)
        cosAlpha = math.cos(yaw)
        cosBeta = math.cos(pitch)
        cosGamma = math.cos(roll)
        m00 = cosAlpha * cosBeta
        m01 = cosAlpha * sinBeta * sinGamma - sinAlpha * cosGamma
        m02 = cosAlpha * sinBeta * cosGamma + sinAlpha * sinGamma
        m10 = sinAlpha * cosBeta
        m11 = sinAlpha * sinBeta * sinGamma + cosAlpha * cosGamma
        m12 = sinAlpha * sinBeta * cosGamma - cosAlpha * sinGamma
        m20 = -sinBeta
        m21 = cosBeta * sinGamma
        m22 = cosBeta * cosGamma

        # Matrix rotationMatrix = new Matrix(new double[][]{{m00, m01, m02}, {m10, m11, m12}, {m20, m21, m22}})
        rotationMatrix = np.array([[m00, m01, m02], [m10, m11, m12],
                                   [m20, m21, m22]])

        # Matrix ray1Matrix = new Matrix(new double[][]{{ray1.x}, {ray1.y}, {ray1.z}})
        # Matrix ray2Matrix = new Matrix(new double[][]{{ray2.x}, {ray2.y}, {ray2.z}})
        # Matrix ray3Matrix = new Matrix(new double[][]{{ray3.x}, {ray3.y}, {ray3.z}})
        # Matrix ray4Matrix = new Matrix(new double[][]{{ray4.x}, {ray4.y}, {ray4.z}})
        ray1Matrix = np.array([[ray1.x], [ray1.y], [ray1.z]])
        ray2Matrix = np.array([[ray2.x], [ray2.y], [ray2.z]])
        ray3Matrix = np.array([[ray3.x], [ray3.y], [ray3.z]])
        ray4Matrix = np.array([[ray4.x], [ray4.y], [ray4.z]])

        res1 = rotationMatrix.dot(ray1Matrix)
        res2 = rotationMatrix.dot(ray2Matrix)
        res3 = rotationMatrix.dot(ray3Matrix)
        res4 = rotationMatrix.dot(ray4Matrix)

        rotatedRay1 = Vector(res1[0, 0], res1[1, 0], res1[2, 0])
        rotatedRay2 = Vector(res2[0, 0], res2[1, 0], res2[2, 0])
        rotatedRay3 = Vector(res3[0, 0], res3[1, 0], res3[2, 0])
        rotatedRay4 = Vector(res4[0, 0], res4[1, 0], res4[2, 0])
        rayArray = [rotatedRay1, rotatedRay2, rotatedRay3, rotatedRay4]

        return rayArray
    def getBoundingPolygon(FOVh, FOVv, altitude, roll, pitch, heading):
        '''Get corners of the polygon captured by the camera on the ground. 
        The calculations are performed in the axes origin (0, 0, altitude)
        and the points are not yet translated to camera's X-Y coordinates.
        Parameters:
            FOVh (float): Horizontal field of view in radians
            FOVv (float): Vertical field of view in radians
            altitude (float): Altitude of the camera in meters
            heading (float): Heading of the camera (z axis) in radians
            roll (float): Roll of the camera (x axis) in radians
            pitch (float): Pitch of the camera (y axis) in radians
        Returns:
            vector3d.vector.Vector: Array with 4 points defining a polygon
        '''
        # import ipdb; ipdb.set_trace()
        ray11 = CameraCalculator.ray1(FOVh, FOVv)
        ray22 = CameraCalculator.ray2(FOVh, FOVv)
        ray33 = CameraCalculator.ray3(FOVh, FOVv)
        ray44 = CameraCalculator.ray4(FOVh, FOVv)

        rotatedVectors = CameraCalculator.rotateRays(ray11, ray22, ray33,
                                                     ray44, roll, pitch,
                                                     heading)

        origin = Vector(0, 0, altitude)
        intersections = CameraCalculator.getRayGroundIntersections(
            rotatedVectors, origin)

        return intersections
Esempio n. 4
0
def render(screen: pygame.Surface, objects: Tuple[Geometry],
           lights: Tuple[Light]):
    screen.lock()

    for j in range(-int(SCREEN[1] / 2), int(SCREEN[1] / 2)):
        for i in range(-int(SCREEN[0] / 2), int(SCREEN[0] / 2)):
            x = (2 * (i + 0.5)) / (SCREEN[0] - 1) * math.tan(FOV / 2.0) * int(
                SCREEN[0]) / SCREEN[1]
            y = -(2 * (j + 0.5)) / (SCREEN[1] - 1) * math.tan(FOV / 2.0)
            direction = Vector(x, y, -1).normalize()

            screen.set_at((i + int(SCREEN[0] / 2), j + int(SCREEN[1] / 2)),
                          cast_ray(Vector(0, 0, 0), direction, tuple(objects),
                                   tuple(lights)))
        pygame.display.flip()
    screen.unlock()
Esempio n. 5
0
def cast_ray(orig: Vector,
             direction: Vector,
             objects: Tuple[Geometry],
             lights: Tuple[Light],
             depth=0):
    c = None

    res, hit, N, obj_hit = scene_intersect(orig, direction, objects)
    if depth > 4 or not res:
        return (128, 200, 255)

    refl_dir = reflect(direction, N).normalize()
    refl_orig = hit - N * 0.001 if refl_dir * N < 0 else hit + N * 0.001
    refl_color = cast_ray(refl_orig, refl_dir, objects, lights, depth + 1)

    obj_to_render = obj_hit

    if hit:
        diffuse_light_intens = 0
        specular_light_intens = 0
        for light in lights:
            light_dir = (light.pos - hit).normalize()
            diffuse_light_intens += light.intensity * max(0.0, light_dir * N)
            specular_light_intens += pow(
                max(0.0, -reflect(-light_dir, N) * direction),
                obj_to_render.specular()) * light.intensity

        c = obj_to_render.diffuse_color(
        ) * diffuse_light_intens * obj_to_render.albedo().x + Vector(
            1.0, 1.0,
            1.0) * specular_light_intens * 255 * obj_to_render.albedo(
            ).y + Vector(*refl_color) * obj_to_render.albedo().z

        if c.x > 255:
            c.x = 255
        if c.y > 255:
            c.y = 255
        if c.z > 255:
            c.z = 255

    return (int(c.x), int(c.y), int(c.z))
    def findRayGroundIntersection(ray, origin):
        """
        Finds a ray-vector's intersection with the ground approximated by a planeç
        Parameters:
            ray (vector3d.vector.Vector): Ray-vector
            origin (vector3d.vector.Vector): Camera's position
        Returns:
            vector3d.vector.Vector
        """
        # Parametric form of an equation
        # P = origin + vector * t
        x = Vector(origin.x, ray.x)
        y = Vector(origin.y, ray.y)
        z = Vector(origin.z, ray.z)

        # Equation of the horizontal plane (ground)
        # -z = 0

        # Calculate t by substituting z
        t = -(z.x / z.y)

        # Substitute t in the original parametric equations to get points of intersection
        return Vector(x.x + x.y * t, y.x + y.y * t, z.x + z.y * t)
Esempio n. 7
0
    def getBoundingPolygon(FOVh,
                           FOVv,
                           roll,
                           pitch,
                           yaw,
                           camera_pos=(0.0, 0.0, 100.0),
                           units="feet"):
        '''Get corners of the polygon captured by the camera on the ground. 
        The calculations are performed in the axes origin (0, 0, altitude)
        and the points are not yet translated to camera's X-Y coordinates.
        Parameters:
            FOVh (float): Horizontal field of view in degrees
            FOVv (float): Vertical field of view in degrees
            roll (float): Roll of the camera (x axis) in degrees
            yaw (float): Heading of the camera (z axis) in degrees
            pitch (float): Pitch of the camera (y axis) in degrees
            camera_pos (float): Tuple. XYZ coordinate of camera
            units (str): Units label
        Returns:
            vector3d.vector.Vector: Array with 4 points defining a polygon
        '''
        # import ipdb; ipdb.set_trace()

        # Convert into radians
        FOVh = np.radians(float(FOVh))
        FOVv = np.radians(float(FOVv))
        roll = np.radians(float(roll))
        pitch = np.radians(float(pitch))
        yaw = np.radians(float(yaw))
        ray11 = CameraCalculator.ray1(FOVh, FOVv)
        ray22 = CameraCalculator.ray2(FOVh, FOVv)
        ray33 = CameraCalculator.ray3(FOVh, FOVv)
        ray44 = CameraCalculator.ray4(FOVh, FOVv)

        rotatedVectors = CameraCalculator.rotateRays(ray11, ray22, ray33,
                                                     ray44, roll, pitch, yaw)

        origin = Vector(camera_pos[0], camera_pos[1], camera_pos[2])
        intersections = CameraCalculator.getRayGroundIntersections(
            rotatedVectors, origin)

        return intersections
Esempio n. 8
0
def main():
    objects = [
        Sphere(Vector(-3, 0, -16), 4,
               Material(Vector(0.0, 0.4, 0.9), (Vector(255, 255, 255)), 50)),
        Sphere(Vector(9, 1, -16), 7,
               Material(Vector(0.9, 0.1, 0.2), Vector(255, 128, 255), 10)),
        Sphere(Vector(-8, 5, -16), 2,
               Material(Vector(0.4, 0.5, 0.4), Vector(0, 128, 0), 100))
    ]
    lights = [
        Light(Vector(-20, 20, 20), 1.5),
        Light(Vector(30, 50, -25), 1.3),
        Light(Vector(30, 20, 30), 0.7)
    ]

    pygame.init()

    pygame.display.set_caption("SW RT")

    screen = pygame.display.set_mode((int(SCREEN[0]), int(SCREEN[1])))

    while True:
        st = time.time()
        render(screen, objects, lights)
        print(time.time() - st)
        pygame.display.flip()
        objects[0].pos.x += 1
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return