Exemple #1
0
    def test_does_it_fit(self):
        self.assertTrue(PlaneValidator.does_it_fit(Plane("U", 3, "D")))
        self.assertTrue(PlaneValidator.does_it_fit(Plane("D", 5, "D")))
        self.assertTrue(PlaneValidator.does_it_fit(Plane("L", 4, "C")))
        self.assertTrue(PlaneValidator.does_it_fit(Plane("R", 4, "F")))

        self.assertFalse(PlaneValidator.does_it_fit(Plane("U", 1, "A")))
Exemple #2
0
def main():
    screen = pygame.display.set_mode((600, 400))
    pygame.display.set_caption("Plane")
    
    background = pygame.Surface(screen.get_size())
    background.fill((0, 0, 0))

    plane = Plane()
    airplanes = pygame.sprite.Group(plane)
    
    clock = pygame.time.Clock()
    keepGoing = True
    while keepGoing:
        clock.tick(30)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                keepGoing = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    plane.plane_right()
                if event.key == pygame.K_LEFT:
                    plane.plane_left()

        airplanes.clear(screen, background)
        airplanes.draw(screen)
        pygame.display.flip()
Exemple #3
0
    def __init__(self, screen):
        self.name = "Space X"
        self.plane = Plane(screen)
        self.targets = []
        self.backGroundImage = pygame.transform.scale(pygame.image.load("images/png/BG.png"),
                                                      (screen.get_width(), screen.get_height()))
        self.backGroundImageX = 0
        self.backGroundImageY = 0
        self.backGroundImageY2 = -screen.get_height()
        self.screen = screen
        width = screen.get_width()
        height = screen.get_height()
        self.x = width / 2
        self.y = height / 2
        self.flyImages = [pygame.transform.scale(pygame.image.load("images/spaceship13.png"), (100, 100))]
        self.rectangle = self.flyImages[0].get_rect(center=(self.x, self.y))
        self.exposedImage = pygame.transform.scale(pygame.image.load("images/gameover2.png"),
                                              (self.rectangle[1], self.rectangle[2]))


        self.exposed = False
        self.exposedEvent = pygame.event.Event(pygame.USEREVENT, attr1='planeExposedEvent')
        self.time=100

        self.targetOrder = 0;
        # 2 saniyede bir hedef üretilmeli
        # bunun için kendi yazdığımız timer sınıfını kulllıyoruz

        self.pgenerateTargetTimer = pTimer(2, self.generateTarget, screen)
        self.tim = pTimer(1, self.decreaseTimer, screen)

        self.finishEvent = pygame.event.Event(pygame.USEREVENT, attr1='finishEvent')
Exemple #4
0
def board_plane(ordering, average_aisle_to_seat_time, sd_aisle_to_seat_time):
    # Assumptions
    num_rows = 30
    distance_between_rows = 10
    distance_between_passengers = 2
    walking_speed = 8
    lower_bound_aisle_to_seat_time = 1
    upper_bound_aisle_to_seat_time = 200

    # Create passengers and order them
    passengers = construct_passengers(num_rows * 6, average_aisle_to_seat_time,
                                      sd_aisle_to_seat_time,
                                      lower_bound_aisle_to_seat_time,
                                      upper_bound_aisle_to_seat_time)
    line_of_passengers = passenger_ordering(passengers, ordering,
                                            distance_between_passengers)

    # Create and board plane
    plane = Plane()
    ticks = 0
    while not plane.is_finished_boarding():
        on_tick(line_of_passengers, walking_speed, distance_between_rows,
                ticks, plane)
        ticks += 1
    return ticks / 60
Exemple #5
0
 def __init__(self, center, radius, color = Color()):
     self._pp = Plane(Vector(), Vector(), Color())
     self._pn = Plane(Vector(),Vector(), Color())
     Sphere.__init__(self, center, radius, color)
     self.set_reflectivity(0.2)
     self.set_orientation( Vector() )
     self.set_cosine(1.0)
Exemple #6
0
 def __init__(self, center, radius, color=Color()):
     self._pp = Plane(Vector(), Vector(), Color())
     self._pn = Plane(Vector(), Vector(), Color())
     Sphere.__init__(self, center, radius, color)
     self.set_reflectivity(0.2)
     self.set_orientation(Vector())
     self.set_cosine(1.0)
Exemple #7
0
  def test_combo(self):
    """
    Test odds of a plane that needs to land
    add to queue
    """
    i = random.randrange(1, 7)
    odds_to_land_arrival = 0.75
    odds_to_takeoff_arrival = 0.89


    q = []
    for clock_tick in range(0, i):
      #there lies a possiblity where a random number adds both a landing and take off to the queu
      random_gen = random.random()

      if  random_gen < odds_to_land_arrival:
        status = "to_land"
        new_plane = Plane.generate_Plane(status,i)
        q.append(new_plane)

      if  random_gen < odds_to_takeoff_arrival:
        status = "to_takeoff"
        new_plane = Plane.generate_Plane(status,i)
        q.append(new_plane)

      if  random_gen > odds_to_takeoff_arrival and random_gen > odds_to_land_arrival:
        status = "None"
        new_plane = Plane.generate_Plane(status,i)
        q.append(new_plane)
Exemple #8
0
 def __create(self):
     one = Point(-self.a / 2, self.b / 2, 0)
     two = Point(self.a / 2, self.b / 2, 0)
     three = Point(self.a / 2, -self.b / 2, 0)
     four = Point(-self.a / 2, -self.b / 2, 0)
     five = Point(-self.c / 2, 0, self.h)
     six = Point(self.c / 2, 0, self.h)
     line12 = Line(one, two)
     line14 = Line(one, four)
     line15 = Line(one, five)
     line23 = Line(two, three)
     line26 = Line(two, six)
     line34 = Line(three, four)
     line36 = Line(three, six)
     line45 = Line(four, five)
     line56 = Line(five, six)
     plane1234 = Plane([line12, line14, line23, line34], one, two, three)
     plane154 = Plane([line15, line14, line45], one, five, four)
     plane236 = Plane([line23, line26, line36], two, three, six)
     plane1265 = Plane([line12, line15, line56, line26], one, two, five)
     plane5643 = Plane([line56, line36, line34, line45], five, four, three)
     self.planes.append(plane1234)
     self.planes.append(plane154)
     self.planes.append(plane236)
     self.planes.append(plane1265)
     self.planes.append(plane5643)
Exemple #9
0
def normTolIntersect(plane: Plane, obstacle: Obstacle, tolerance):
    planeVel = plane.getVelocityRT()
    obstacleCenter = obstacle.getCenter()
    planeCenter = plane.getRect().center
    distTranslation = numpy.subtract(obstacleCenter, planeCenter)
    distPolar = magnitude(distTranslation), math.atan2(distTranslation[1],
                                                       distTranslation[0])
    pole = distPolar[0] * math.cos(distPolar[1] - planeVel[1])
    minDistance = math.sqrt(math.pow(distPolar[0], 2) - math.pow(pole, 2))
    clearance = magnitude(plane.getRect().size) / math.sqrt(2) + magnitude(
        [obstacle.xSize, obstacle.ySize]) / math.sqrt(2)
    if pole < 0:
        return None
    if minDistance <= clearance:
        return "Red", pole * math.cos(
            planeVel[1]) + planeCenter[0], pole * math.sin(
                planeVel[1]) + planeCenter[1]
    elif minDistance <= clearance + tolerance:
        return "Yellow", pole * math.cos(
            planeVel[1]) + planeCenter[0], pole * math.sin(
                planeVel[1]) + planeCenter[1]
    else:
        return "Green", pole * math.cos(
            planeVel[1]) + planeCenter[0], pole * math.sin(
                planeVel[1]) + planeCenter[1]
Exemple #10
0
 def __init__(self, mission, propulsionType="combustion", config={}):
     self.verbose = True
     self.savePlot = True
     self.propulsionType = propulsionType
     ini = Ini(mission.NAME)
     self.stepWidth = int(ini.get("general", "step"))
     self.p = Plane(mission, propulsionType=propulsionType, config=config)
     self.m = mission
Exemple #11
0
 def test_plane_planetype_true(self):
     sor = self.plane_setup()
     sor.instructor = None
     p = Plane('107LE')
     p.planetype = 'C-172'
     sor.plane = p
     sor.plane.planetype = 'C-172'
     self.assertTrue(sor.feasible())
Exemple #12
0
 def test_plane_planetype_false(self):
     sor = self.plane_setup()
     sor.instructor = None
     p = Plane('107LE')
     p.planetype = 'PA-28'
     sor.plane = p
     # sor.plane.planetype = 'PA-28'
     self.assertFalse(sor.feasible())
Exemple #13
0
 def translate_plane(self, plane, h, i):
     new_pt = plane.pt_on_plane + plane.perp_vec * h
     #         print(new_pt, '--')
     p = Plane(plane.perp_vec,
               np.dot(plane.perp_vec, new_pt),
               self.options,
               plane_id=i)
     p.pt_on_plane = new_pt
     return p
 def __init__(self):
     self.iteration = 0
     cfg.load()
     self.plane = Plane(cfg.get("width"), cfg.get("height"), cfg.get("radius"), cfg.get("map_type"))
     self.population = Population()
     self.population.scatter(self.plane)
     self.drawer = Drawer()
     print(len(self.plane.hexagons))
     pass
Exemple #15
0
    def test_cockpit_coords(self):
        upwards_plane = Plane("U", 3, "D")
        downwards_plane = Plane("D", 6, "D")
        leftwards_plane = Plane("L", 4, "C")
        rightwards_plane = Plane("R", 4, "F")

        self.assertEqual(upwards_plane.cockpit_coords, (2, 3))
        self.assertEqual(downwards_plane.cockpit_coords, (5, 3))
        self.assertEqual(leftwards_plane.cockpit_coords, (3, 2))
        self.assertEqual(rightwards_plane.cockpit_coords, (3, 5))
Exemple #16
0
 def plot(self):
     # input to plane
     # self.a = self.a -10
     w0 = self.weights[0]
     w1 = self.weights[1]
     w2 = self.weights[2]
     w3 = self.weights[3]
     self.plane = Plane(w3, w2, w1, w0, self.Size, self.c)
     # self.plane.change(self.a,0);
     self.plane.draw()
Exemple #17
0
 def __init__(self,
         normal = Vector(0.0,1.0,0.0),
         origin = Vector(0.0,0.0,0.0),
         orientation = Vector(1.0,0.0,0.0),
         c1 = Color(0.01,0.01,0.01),
         c2 = Color(0.99,0.99,0.99)):
     """Initializes plane and plane colors."""
     Plane.__init__(self, normal, origin)
     self.set_orientation(orientation)
     self.set_colors(c1,c2)
Exemple #18
0
class perceptron:
    # n is  number of weights
    # l is  learning Rate
    # sizeOfPlane it use for make boundry size of plane

    def __init__(self, n, l, sizeOfPlane):
        self.weights = []
        self.learning_Rate = l

        #set random weights
        for i in range(n):
            self.weights.append(random(0, 1))

        print(self.weights)
        self.Size = sizeOfPlane
        # make a random  color
        self.c = [random(255), random(255), random(255)]

    def plot(self):
        # input to plane
        # self.a = self.a -10
        w0 = self.weights[0]
        w1 = self.weights[1]
        w2 = self.weights[2]
        w3 = self.weights[3]
        self.plane = Plane(w3, w2, w1, w0, self.Size, self.c)
        # self.plane.change(self.a,0);
        self.plane.draw()

    def guss(self, input):
        w0 = self.weights[0]
        w1 = self.weights[1]
        w2 = self.weights[2]
        w3 = self.weights[3]

        if (0 < len(input) <= 3):
            # give input as X,Y,Z
            value = w3 * input[0] + w2 * input[1] + w1 * input[2] + w0

            if (value >= 1): return 1
            else: return -1
        # to error identification
        else:
            return 0

    def train(self, error, inputs):

        for i in range(1, 4):
            self.weights[3 - i +
                         1] += inputs[i - 1] * self.learning_Rate * error

        self.weights[0] += self.learning_Rate * error
        print(self.weights, error, inputs)
        self.plot()
Exemple #19
0
def intersect(plane: Plane, obstacle: Obstacle):
    planeCenter = plane.getRect().center
    planeVelocity = plane.getVelocityRT()
    obstacleDimensions = obstacle.getBoundaries()
    DistTL = [obstacleDimensions[0] - planeCenter[0], obstacleDimensions[1] - planeCenter[1]]
    thetaTL = math.atan2(DistTL[1], DistTL[0])
    DistBL = [obstacleDimensions[0] - planeCenter[0], obstacleDimensions[3] - planeCenter[1]]
    thetaBL = math.atan2(DistBL[1], DistBL[0])
    print(thetaBL, planeVelocity[1], thetaTL)

    if math.pi / -2 < thetaTL < planeVelocity[1] < thetaBL < math.pi / 2:
        return "left"
    return "none"
Exemple #20
0
    def __init__(self, screen):
        self.name = "Haydi Başla"
        self.Plane = Plane(screen)
        self.targets = []
        self.backGroundImage = pygame.transform.scale(pygame.image.load("images/png/BG.png"),
                                                      (screen.get_width(), screen.get_height()))
        self.backGroundImageX = 0
        self.backGroundImageY = 0
        self.screen = screen

        self.pgenerateTargetTimer = pTimer(2, self.generateTarget, screen)
        self.finishEvent = pygame.event.Event(pygame.USEREVENT, {"EventName": "FinishEvent"})
        self.Targets = (TargetOne,TargetTwo,TargetThree)
 def __init__(self, SH, SW, screen):
     self.enemies = []
     self.collectables = []
     self.SW = SW
     self.SH = SH
     self.screen = screen
     self.score = 0
     self.coins = 0
     self.isGameOver = False
     self.plane = Plane(screen)
     self.sound_mgr = SoundManager()
     self.snd_collectable = self.sound_mgr.LoadSound('collectable')
     self.snd_fire = self.sound_mgr.LoadSound('fire_plane')
     self.sound_mgr.PlayMusic('background')
Exemple #22
0
 def circumcenter(self):
     plane_1 = Plane(self)
     mid_1 = Point([0.5 * (self[0][i] + self[1][i]) for i in range(3)])
     vnor_1 = Vector([mid_1[i] - self[0][i] for i in range(3)]).unit()
     plane_2 = Plane([mid_1, vnor_1])
     mid_2 = Point([0.5 * (self[0][i] + self[2][i]) for i in range(3)])
     vnor_2 = Vector([mid_2[i] - self[0][i] for i in range(3)]).unit()
     plane_3 = Plane([mid_2, vnor_2])
     print '-------------'
     print plane_1
     print '-------------'
     print plane_2
     print '-------------'
     print plane_3
     return intersect_3_planes(plane_1, plane_2, plane_3)
Exemple #23
0
    def test_body_length(self):
        upwards_plane = Plane("U", 3, "D")
        downwards_plane = Plane("D", 6, "D")
        leftwards_plane = Plane("L", 4, "C")
        rightwards_plane = Plane("R", 4, "F")

        u_body = upwards_plane.body
        d_body = downwards_plane.body
        l_body = leftwards_plane.body
        r_body = rightwards_plane.body

        self.assertEqual(len(u_body), 9)
        self.assertEqual(len(d_body), 9)
        self.assertEqual(len(l_body), 9)
        self.assertEqual(len(r_body), 9)
Exemple #24
0
class MyTesting(unittest.TestCase):
    def setUp(self):
        self.plane = Plane()

    def test_getAngle(self):
        self.assertEqual(self.plane.getAngle(), 0.0)

    def test_Plane_init(self):
        plane = Plane()
        self.assertEqual(plane._angle, 0.0)

    def test_increaseAngleByGaussian(self):
        self.plane.increaseAngleByGaussian()
        self.assertTrue(self.plane.getAngle() < 10
                        or self.plane.getAngle() > 0)
Exemple #25
0
    def __init__(self,screen):
        self.name="Let's Start"
        self.plane= Plane(screen)
        self.targets=[]
        self.backGroundImage=pygame.transform.scale(pygame.image.load("images/png/BG.png"),(screen.get_width(), screen.get_height()))
        self.backGroundImageX=0
        self.backGroundImageY=0
        self.screen= screen

        #2 saniyede bir hedef üretilmeli
        #bunun için kendi yazdığımız timer sınıfını kulllıyoruz
        #bu işlem için uygun olan threadlerdir ancak bu konuya sonra geleceğiz
        self.pgenerateTargetTimer=pTimer(2,self.generateTarget,screen)

        self.finishEvent=pygame.event.Event(pygame.USEREVENT, attr1='finishEvent')
Exemple #26
0
    def __init__(self, A, b, pt, options=Options()):
        self.A = A
        self.b = b
        self.dimension = A.shape[1]
        self.num_planes = A.shape[0]
        self.options = options

        self.planes = []
        for i in range(self.num_planes):
            p = Plane(A[i], b[i], self.options, plane_id=i)
            #             print(p.pt_on_plane)
            p = self.translate_plane(p, options.depth, i)
            print(p.perp_vec, p.pt_on_plane)
            self.planes.append(p)

        self.point = pt

        self.cur_lines__ = [[self.point, self.point]]
        self.pts = []
        self.averages = []
        self.centroid_distance = []
        self.centroid_change = []
        self.facet_hit = []
        self.angles = []
        #self.marginal_direction = np.zeros(self.dimension)
        #self.marginal_direction[0] = 1
        self.marginal_direction = np.random.random(self.dimension)
        self.marginal_direction /= np.linalg.norm(self.marginal_direction)
        self.last_marginal = []
        self.it = 10
        self.all_marginals = []
        self.all_marginal_diffs = []
class Simulator:
    def __init__(self):
        self.iteration = 0
        cfg.load()
        self.plane = Plane(cfg.get("width"), cfg.get("height"), cfg.get("radius"), cfg.get("map_type"))
        self.population = Population()
        self.population.scatter(self.plane)
        self.drawer = Drawer()
        print(len(self.plane.hexagons))
        pass

    def tick(self) -> None:
        print("Iteration {}".format(self.iteration))
        self.iteration += 1
        self.report()
        print()
        # self.drawer.draw_hexes(self.plane.hexagons, self.population.population)
        for person in self.population.population:
            person.go_brr(self.population, self.plane.get_surrounding(person.coordinates))
        # print(self.population)
        # sleep(1)

    def report(self):
        print("SUSCEPTIBLE: {:>7}".format(self.population.get_susceptible_count()))
        print("INFECTIOUS:  {:>7}".format(self.population.get_infectious_count()))
        print("DECEASED:    {:>7}".format(self.population.get_deceased_count()))
        print("RECOVERED:   {:>7}".format(self.population.get_recovered_count()))
Exemple #28
0
    def loadSquirrel(self):
        print("____Load the fast Squirrel____")
        file = open('squirrel_aligned_lowres.obj')
        vertices = []
        faces = []
        for lines in file:
            if lines.split()[0] == 'v':
                vertices.append(
                    tuple((-float(lines.split()[1]), float(lines.split()[2]),
                           -float(lines.split()[3]))))
            if lines.split()[0] == 'f':
                faces.append(
                    tuple((int(lines.split()[1]), int(lines.split()[2]),
                           int(lines.split()[3]))))

        self.objects.append(
            Plane(np.array([0, -2, 5]), np.array([0, 1, 0]), self.grey))
        triscount = 0
        for face in faces:
            self.objects.append(
                Rectangle(np.array(vertices[face[0] - 1]),
                          np.array(vertices[face[1] - 1]),
                          np.array(vertices[face[2] - 1]), self.grey2))
            triscount += 1

        print(triscount, "Dreiecke erstellt. Starte Rendern.")
Exemple #29
0
def intersect(plane: Plane, obstacle: Obstacle):
    planeDimensions = plane.getBoundaries()
    planeVelocity = plane.getVelocityRT()
    obstacleDimensions = obstacle.getBoundaries()
    # rectangle sides are 0-3 clockwise with left == 0
    # gets the near miss angle by calculating angle from "closest corners"
    DistPlaneTLtoObjBR = [
        obstacleDimensions[2] - planeDimensions[0],
        obstacleDimensions[3] - planeDimensions[1]
    ]
    thetaTLBR = math.atan2(DistPlaneTLtoObjBR[1], DistPlaneTLtoObjBR[0])
    DistPlaneTRtoObjBL = [
        obstacleDimensions[0] - planeDimensions[2],
        obstacleDimensions[3] - planeDimensions[1]
    ]
    thetaTRBL = math.atan2(DistPlaneTRtoObjBL[1], DistPlaneTRtoObjBL[0])
    DistPlaneBRtoObjTL = [
        obstacleDimensions[0] - planeDimensions[2],
        obstacleDimensions[1] - planeDimensions[3]
    ]
    thetaBRTL = math.atan2(DistPlaneBRtoObjTL[1], DistPlaneBRtoObjTL[0])
    DistPlaneBLtoObjTR = [
        obstacleDimensions[2] - planeDimensions[0],
        obstacleDimensions[1] - planeDimensions[3]
    ]
    thetaBLTR = math.atan2(DistPlaneBLtoObjTR[1], DistPlaneBLtoObjTR[0])

    # compares velocity direction with near miss angles
    if -math.pi < thetaTRBL <= planeVelocity[1] <= thetaTLBR <= 0:
        return "bottom"
    elif math.pi / -2 <= thetaBRTL <= planeVelocity[
            1] <= thetaTRBL <= math.pi / 2:
        return "left"
    elif 0 <= thetaBLTR <= planeVelocity[1] <= thetaBRTL <= math.pi:
        return "top"
    # polar coordinates are discontinuous range shift into continuous by adding 2pi
    else:
        if thetaBLTR < 0:
            thetaBLTR += 2 * math.pi
            if thetaTLBR < 0:
                thetaTLBR += 2 * math.pi
            if planeVelocity[1] < 0:
                planeVelocity[1] += 2 * math.pi
        if math.pi / 2 <= thetaTLBR <= planeVelocity[
                1] <= thetaBLTR <= 3 * math.pi / 2:
            return "right"
    return "none"
Exemple #30
0
def randSmallPlane():
    randID = ''.join(random.choice(string.ascii_uppercase)
                     for i in range(2)) + str(randint(100, 999))
    fuel = randint(5, 15)
    capacity = fuel + randint(5, 15)
    passengers = randint(2, 25)
    arrival = randint(0, 1200)
    return Plane(randID, fuel, capacity, passengers, 0, arrival)
    def multiply_coefficient_and_row(self, coefficient, row):
        n = self[row].normal_vector
        k = self[row].constant_term

        new_normal_vector = n.scalar(coefficient)
        new_constant_term = k * coefficient
        self[row] = Plane(normal_vector=new_normal_vector,
                          constant_term=new_constant_term)
Exemple #32
0
  def test_Tower(self):
    """
    Test odds of a plane that needs to land
    add to queue
    """
    print('here')
    tower = Tower()
    ran_num = random.randrange(3, 7)
    for i in range(0, ran_num):
      if (i % 2 ) == 0:
        new_plane = Plane("Takeoff", i)
        tower.add_to_Q(new_plane)
      else:
        new_plane = Plane("Landing", i)
        tower.add_to_PriorityQ(new_plane)

      tower.serve_plane(i)
	def __generateInitialData(self, nr):
		toGenerate = randint(0, nr)
		self.currentNumber += toGenerate
		if self.plecariModel is not None:
			self.plecariModel.triggerDataChanging()
			self.sosiriModel.triggerDataChanging()
			

		for i in range(1, toGenerate):
			plane = Plane.generateRandomPlane()
			if plane.status == 0:
				self.plecariIn.append(plane)
			else:
				self.sosiriIn.append(plane)
		self.plecariIn.sort()
		self.sosiriIn.sort()
		if self.plecariModel is not None:
			self.plecariModel.triggerDataChanged()
			self.sosiriModel.triggerDataChanged()
Exemple #34
0
class TruncSphere(Sphere):
    
    center = Vector()
    radius = 0.0
    R = 0.0
    color = [0.01,0.01,0.01]
    
    def p(self):
        """Returns the name of the type of body this is."""
        return 'TrunkSphere'
    
    def normal(self, point):
        """Returns normal vector of body at given point."""
        s = point - self.center
        if abs(s.dot(s) - self.R) < bounds.small:
            return s.norm()
        else:
            if s.dot(self._orientation) > 0.0:
                sign = 1
            else:
                sign = -1
            return self._orientation.dup().scale(sign)
    
    def set_color(self, c):
        self.color = c
        self._pp.set_color(c)
        self._pn.set_color(c)
        return self
    
    def set_reflectivity(self, r):
        r = max(0.0,min(1.0,r))
        self._r = r
        self._pp.set_reflectivity(r)
        self._pn.set_reflectivity(r)
        return self
    
    def set_orientation(self, v):
        self._orientation = v.norm()
        self._pp.set_normal(v.dup())
        self._pn.set_normal(v.dup().scale(-1.0))
        return self
    
    def set_cosine(self, c):
        self._cosine = c
        cp = self.center.dup().add(self._orientation, c * self.radius)
        cn = self.center.dup().add(self._orientation, -1 * c * self.radius)
        self._pp.set_position(cp)
        self._pn.set_position(cn)
        return self
    
    def __init__(self, center, radius, color = Color()):
        self._pp = Plane(Vector(), Vector(), Color())
        self._pn = Plane(Vector(),Vector(), Color())
        Sphere.__init__(self, center, radius, color)
        self.set_reflectivity(0.2)
        self.set_orientation( Vector() )
        self.set_cosine(1.0)
        
    
    def intersection(self, ray):
        """Returns distance from ray to closest intersection with sphere."""
        
        S = ray.o - self.center
        SD = S.dot( ray.d )
        SS = S.dot(S)
        
        # no hit if sphere is really far away
        if SS > bounds.too_far ** 2:
            return -1.0
        
        radical = SD ** 2 + self.R - SS
        # negative radical implies no solutions
        if radical < 0.0:
            return -1.0
        
        radical **= 0.5
        hits = [-1 * SD - radical,  -1 * SD + radical]
        if hits[0] < bounds.too_close:
            if hits[1] < bounds.too_small:
                return -1.0
        
        pp = self._pp.intersection(ray)
        pn = self._pn.intersection(ray)
        
        if pp < pn:
            hitp = [pp,pn]
        else:
            hitp = [pn,pp]
        
        # if two plane hits before sphere hits, we miss
        if hitp[1] < hits[0]:
            return -1.0
        
        # if two sphere hits before plane hits, we miss
        if hits[1] < hitp[0]:
            return -1.0
        
        # if the second thing hit is forward, that's our distance
        hit = max(hits[0],hitp[0])
        if hit > 0:
            return hit
        # otherwise it's the third hit (if positive)
        hit = min(hits[1],hitp[1])
        if hit > 0:
            return hit
        # otherwise, we didn't hit anything
        else:
            return -1.0