Пример #1
0
                #pixel center in space
                p = self.c + px * self.u_x + py * self.u_y
                #direction vector
                if self._orth:
                    u = self.direction
                else:
                    u = (p - self.position) / norm(p - self.position)
                yield Ray(p, u)
            yield None #next row

if __name__ == '__main__':
    import pixmap
    s = objects.Sphere(Vector(0,0,0), 2)
    cpos = Vector(0, 0, 6)
    u = Vector.normalize(0, 0, -1)
    c = Camera(cpos, u, scale=0.25)
    image = []
    l, h = 2**20, 0
    for r in c.rays():
        if r is not None:
            if s.intersects(r):
                col = s.intersectionDistance(r)
                if col > h:
                    h = col
                if col < l:
                    l = col
                image += [col]
            else:
                image += [-1]
        else:
Пример #2
0
class Ball:
    def __init__(self, v, circle, parent):
        self.v = v
        self.circle = circle
        self.parent = parent

    def update(self, t):
        time_left = t
        while time_left > 0:
            self.collisions = []

            # left wall
            self.add_collision(
                geometry.wall_collision(x=0,
                                        y1=0,
                                        y2=inf,
                                        ball=self.circle.pos,
                                        v=self.v * time_left), objects.wall)

            # right wall
            self.add_collision(
                geometry.wall_collision(x=window_width - ballsize,
                                        y1=0,
                                        y2=inf,
                                        ball=self.circle.pos,
                                        v=self.v * time_left), objects.wall)

            # floor
            self.add_collision(
                geometry.floor_collision(y=0,
                                         x1=0,
                                         x2=window_width,
                                         ball=self.circle.pos,
                                         v=self.v * time_left), objects.floor)

            # nodes
            for i in range(2):
                self.add_collision(
                    geometry.node_collision(
                        list(self.parent.halves[i].node.pos),
                        list(self.circle.pos), self.v * time_left),
                    objects.node, i)

            # net left wall
            self.add_collision(
                geometry.wall_collision(x=window_width / 2 - ballsize -
                                        net_width,
                                        y1=0,
                                        y2=window_height / 2,
                                        ball=self.circle.pos,
                                        v=self.v * time_left), objects.wall)

            # net right wall
            self.add_collision(
                geometry.wall_collision(x=window_width / 2 + net_width,
                                        y1=0,
                                        y2=window_height / 2,
                                        ball=self.circle.pos,
                                        v=self.v * time_left), objects.wall)

            # net top plate
            self.add_collision(
                geometry.floor_collision(y=window_height / 2,
                                         x1=window_width / 2 - ballsize -
                                         net_width,
                                         x2=window_width / 2 + net_width,
                                         ball=self.circle.pos,
                                         v=self.v * time_left), objects.plate)

            if self.collisions == []:
                collides = False
            else:
                closest_collision = None

                for elem in self.collisions:
                    try:
                        if elem.inside:
                            closest_collision = elem
                            collides = True
                            break
                    except AttributeError:
                        continue

                if closest_collision is None:
                    closest_collision = min(
                        self.collisions,
                        key=lambda x: distance(x.point, self.circle.pos))

                    closest_collision_time = distance(
                        closest_collision.point,
                        self.circle.pos) / self.v.speed()
                    if closest_collision_time > time_left:
                        collides = False
                    else:
                        collides = True

            if not collides:
                self.circle.pos = [
                    self.circle.pos[0] + self.v.x * time_left,
                    self.circle.pos[1] + self.v.y * time_left
                ]
                self.v.y -= g * t
                time_left = 0
            else:
                stop_needed, restart_needed = \
                    self.handle_collision(closest_collision)

                if stop_needed:
                    return (stop_needed, restart_needed)

                closest_collision_time = distance(
                    closest_collision.point, self.circle.pos) / self.v.speed()

                time_left -= closest_collision_time
                self.v.y -= g * closest_collision_time
        return (False, False)

    def add_collision(self, *args):
        point = args[0]
        kind = args[1]
        if len(args) == 2:
            if point is not None:
                self.collisions.append(Object(kind=kind, point=point))
        else:
            node_id = args[2]
            if point is not None:
                point, inside = point
                self.collisions.append(
                    Object(kind=kind,
                           point=point,
                           node_id=node_id,
                           inside=inside))

    def handle_collision(self, collision):
        self.circle.pos = collision.point

        if collision.kind == objects.wall:
            self.v.x = -self.v.x

        elif collision.kind == objects.floor:
            if self.circle.pos[0] < window_width / 2:
                self.parent.add_goal(0)
            else:
                self.parent.add_goal(1)

            return (True, self.parent.stop())

        elif collision.kind == objects.plate:
            self.v.y = -self.v.y

        elif collision.kind == objects.node:
            half = self.parent.halves[collision.node_id]
            node_pos = half.node.pos

            speed = self.v.speed()
            self.v = Vector(begin=node_pos, end=self.circle.pos)
            self.v.normalize()
            self.v *= speed
            self.v += half.vector

        self.v *= spring_ability
        return (False, False)
Пример #3
0
def test_vector_normalize():
    v1 = Vector([4, 5, 6])
    normed = v1.normalize()
    assert normed.is_unit_vector()
Пример #4
0
class VectorCase(unittest.TestCase):
    
    def setUp(self):
        
        self.a = Vector(1.0, 1.0, 1.0)
        self.b = Vector(1.0, 0.0, 0.0)
        self.c = Vector(0.0, 0.0, 1.0)
    
    def tearDown(self):
        
        del self.a
        del self.b
        del self.c
    
    def test_richmap(self):
        

        
        self.assertTrue(self.a==self.a)     # Test equality
        self.assertFalse(self.a==self.b)    # Test equality
        
        self.assertTrue(self.a!=self.b)     # Test unequality
        
        self.assertRaises(TypeError, operator.gt, self.a, self.b)  # Test not implemented operators.

        self.assertFalse(self.a==3.0)   # Test other type
        self.assertFalse(3.0==self.a)   # Test other type
    
    def test_arithmetics(self):
        
        """add and mul"""
        self.assertAlmostEqual( self.a + self.a, 2.0 * self.a)
        
        """sub"""
        self.assertAlmostEqual( self.a - self.a, Vector(0.0, 0.0, 0.0))
        
        """div and truediv"""
        self.assertAlmostEqual( self.a / 2.0, Vector(0.5, 0.5, 0.5))
        
        """pow"""
        
        """neg"""
        self.assertEqual( -self.a, Vector(-1.0, -1.0, -1.0))
        
    
    def test_dot(self):
        
        self.assertEqual( self.a.dot(self.b) , 1.0)
        self.assertEqual( self.b.dot(self.a) , 1.0)
    
    def test_cross(self):
        
        self.assertEqual( self.a.cross(self.b), Vector(0.0, +1.0, -1.0) )
        self.assertEqual( self.b.cross(self.a), Vector(0.0, -1.0, +1.0) )
        
        self.assertEqual( self.b.cross(self.c), Vector(0.0, -1.0, 0.0) )
        self.assertEqual( self.c.cross(self.b), Vector(0.0, +1.0, 0.0) )
        
        self.assertEqual( self.a.cross(self.c), Vector(+1.0, -1.0, 0.0) )
        self.assertEqual( self.c.cross(self.a), Vector(-1.0, +1.0, 0.0) )
        
    def test_norm(self):
        
        # Comparing floating point numbers.
        self.assertAlmostEqual(self.a.norm(), 3.0**(0.5))
        self.assertAlmostEqual(self.b.norm(), 1.0)
        self.assertAlmostEqual(self.c.norm(), 1.0)
    
    def test_normal(self):
        
        self.assertIs(type(self.a.normalize()), Vector)   # Check that we get a vector back.
        
        self.assertEqual(self.b, self.b.normalize())
        
        self.assertAlmostEqual(self.a.normalize(), self.a/self.a.norm())
    
    
    def test_cosines_with(self):
        
        self.assertAlmostEqual(self.b.cosines_with(self.c), 0.0) # Vectors are orthogonal, so cos(90)=0
        self.assertAlmostEqual(self.b.cosines_with(self.b), 1.0) # Vectors are parralel