示例#1
0
文件: ball.py 项目: Nabiz/PoolGame
 def other_balls_collision(self, rack):
     for another_ball in rack:
         if another_ball.ball.visible:
             pos_a = self.ball.pos
             pos_b = another_ball.ball.pos
             vel_a = self.velocity
             vel_b = another_ball.velocity
             radius = self.ball.radius
             if self != another_ball and mag(pos_a - pos_b) < 2 * radius:
                 a = mag(vel_a - vel_b)**2
                 b = dot(-2 * (pos_a - pos_b), (vel_a - vel_b))
                 c = mag(pos_a - pos_b)**2 - (2 * radius)**2
                 delta = b**2 - 4 * a * c
                 if a != 0 and delta > 0:
                     dtprim = (-b + sqrt(delta)) / (2 * a)
                     pos_a = pos_a - vel_a * dtprim
                     pos_b = pos_b - vel_b * dtprim
                     tmp = (dot(vel_a - vel_b,
                                (pos_a - pos_b) / mag(pos_a - pos_b))) * (
                                    (pos_a - pos_b) / mag(pos_a - pos_b))
                     vel_a -= tmp
                     vel_b += tmp
                     pos_a += vel_a * dtprim
                     pos_b += vel_b * dtprim
                     self.ball.pos = pos_a
                     self.set_velocity(vel_a)
                     another_ball.pos = pos_b
                     another_ball.set_velocity(vel_b)
def collision_node_edge(body1, body2):
    DISTANCE_TOLERANCE = 0.03

    for pt1, (pt2, pt2_next) in it.product(body1.vertices, zip(body2.vertices, body2.vertices[1:]+body2.vertices[:1])):
        edge = pt2_next - pt2
        edge_normal = vp.norm(edge)

        p = pt1 - pt2
        proj_on_edge = edge_normal * vp.dot(p, edge_normal)

        if vp.mag(proj_on_edge + edge) <= edge.mag or proj_on_edge.mag > edge.mag:
            continue

        # Perpendicular distance to edge
        dist_to_edge = vp.mag(vp.cross(p, edge_normal))
        if dist_to_edge > DISTANCE_TOLERANCE:
            continue

        collision_pt1 = pt1 - body1.pos
        collision_pt2 = pt1 - body2.pos

        collision_normal = vp.norm(vp.cross(vp.cross(edge_normal, p), edge_normal))

        vel1 = body1.vel + vp.cross(body1.ang_vel, collision_pt1)
        vel2 = body2.vel + vp.cross(body2.ang_vel, collision_pt2)
        relative_vel = vel1 - vel2

        if is_collision_course(relative_vel, collision_normal):
            return Collision(body1, body2, collision_pt1, collision_pt2, relative_vel, collision_normal)

    return None
示例#3
0
    def __init__(self, v, arrow_label, arrow_color, arrow_pos):

        if arrow_label == 'x':
            vec_u = Arrow.vec_i
        elif arrow_label == 'y':
            vec_u = Arrow.vec_j
        elif arrow_label == 'z':
            vec_u = Arrow.vec_k
        else:
            vec_u = vp.vector(v.x * Arrow.vec_i.x, v.y * Arrow.vec_j.y,
                              v.z * Arrow.vec_k.z)

        self.rod_radius = vp.mag(vec_u) * 0.01
        scaled_arrow_pos = vp.vector(arrow_pos.x * Arrow.vec_i.x,
                                     arrow_pos.y * Arrow.vec_i.y,
                                     arrow_pos.z * Arrow.vec_i.z)
        self.rod = vp.cylinder(pos=scaled_arrow_pos,
                               axis=vec_u,
                               radius=self.rod_radius,
                               color=arrow_color)
        self.cone = vp.cone(pos=vec_u,
                            axis=0.1 * vec_u,
                            radius=vp.mag(vec_u) * 0.03,
                            color=arrow_color)
        if arrow_label in 'xyz':
            self.axis_text = vp.text(text=arrow_label,
                                     pos=self.cone.pos + 0.1 * vec_u,
                                     color=arrow_color)
示例#4
0
文件: ball.py 项目: Nabiz/PoolGame
 def move(self, dt):
     self.ball.pos = self.ball.pos + dt * self.velocity
     self.ball.rotate(angle=mag(self.velocity) * 0.0002 * pi,
                      axis=self.rotation_axis)
     self.set_velocity(self.velocity - self.velocity * 0.005)
     if mag(self.velocity) < 1:
         self.set_velocity(vec(0, 0, 0))
 def amplitude(self, delta):
     if hasattr(self, '_amp'):
         if vp.mag(delta) > vp.mag(self.amplitude):
             self._amp = delta
             #print the maxium distance from rest position, during the entire oscillation
             print("\rMeasured amplitude:", vp.mag(delta), end='')
     else:
         self._amp = delta
示例#6
0
def evita_traslapes(pos_i):
    for i in pos_i:
        for j in pos_i:
            if j != i:
                if vp.mag(j.pos - i.pos) < 2 * r_p:
                    lambda_1 = (2 * r_p -
                                (vp.mag(i.pos - j.pos))) / (vp.mag(i.vel))
                    i.pos = i.pos + lambda_1 * i.vel
示例#7
0
def mediciones(lista_de_particulas):
    suma_energias_cin = 0
    suma_energias_pot = 0
    for i in lista_de_particulas:
        suma_energias_cin = suma_energias_cin + (1 / 2) * (
            vp.mag(i.vel)**2
        )  #<-- agregar masa en general recuerda que la masa es de 1 y los radios todos son iguales, podriamos generalizar en un futuro
        suma_energias_pot = suma_energias_pot + vp.mag(
            campo_grav) * np.absolute(
                i.pos.y + long_rect)  #<- aqui iría tambien en mgh
    return ((suma_energias_cin, suma_energias_pot))
示例#8
0
def eval_gravitational_force(p1: vp.sphere, p2: vp.sphere):
    G = 1
    r = p1.pos - p2.pos
    distance = vp.mag(r)
    rhat = r / distance
    force = -rhat * G * p1.mass * p2.mass / distance ** 2
    return force
def escenario3_avance(dt):
    global particulas, t, n, conversion
    for i in range(len(particulas)):
        # Verifica si la particula esta en el punto de choque
        if round(particulas[i][0].posicion.x, 0) == 10 and particulas[i][1]:
            #genera el choque
            velocidad_nueva, l_nueva = choque(particulas[i][0])
            #actualiza las propiedades
            particulas[i][0].cambiar_velocidad(velocidad_nueva)
            particulas[i][0].cambiar_longitud_onda(l_nueva)
            #evolucion temporal
            particulas[i][0].evolucion_temporal(dt)
            #la particula choco
            particulas[i][1] = False
            n += 1
        else:
            particulas[i][0].evolucion_temporal(dt)

        #detiende la particula si se ha alejado mas de 10
        if vp.mag(particulas[i][0].posicion - vp.vector(10, 0, 0)) >= 10.0:
            particulas[i][0].velocidad = vp.vector(0, 0, 0)
        #genera particulas nuevas cada cierto tiempo
        if t >= 2.5:
            particulas.append([
                mod.Photon(vp.vector(4, 0, 0), vp.vector(0, 0, 0), 380,
                           conversion), True
            ])
            t = 0
    t += dt
示例#10
0
def create_line(pos1, pos2, scene):
    """
    Create a line from position 1 to position 2.

    :param scene: The scene in which to draw the object
    :type scene: class:`vpython.canvas`
    :param pos1: 3D position of one end of the line.
    :type pos1: class:`vpython.vector`
    :param pos2: 3D position of the other end of the line.
    :type pos2: class:`vpython.vector`
    """

    # Length of the line using the magnitude
    line_len = mag(pos2-pos1)

    # Position of the line is the midpoint (centre) between the ends
    position = (pos1 + pos2) / 2

    # Axis direction of the line (to align the box (line) to intersect the two points)
    axis_dir = pos2 - pos1

    # Return a box of thin width and height to resemble a line
    thickness = 0.01
    return box(canvas=scene,
               pos=position,
               axis=axis_dir,
               length=line_len,
               width=thickness,
               height=thickness,
               color=color.black)
示例#11
0
def mediciones(lista_de_particulas):
    suma_energias = 0
    for i in lista_de_particulas:
        suma_energias = suma_energias + (1 / 2) * (
            vp.mag(i.vel)**2
        )  #<-- agregar masa en general recuerda que la masa es de 1 y los radios todos son iguales, podriamos generalizar en un futuro
    return (suma_energias)
示例#12
0
def reDrawLines():
    global fwd_line, mouse_line, cam_dist, ray, scene_size, linelen
    linelen = scene_size + vs.mag(cam_frame.axis.norm() * cam_dist +
                                  cam_frame.pos)
    reDrawLine(fwd_line, vs.vector(cam_dist, 0, 0), linelen,
               vs.vector(-1, 0, 0))
    reDrawLine(mouse_line, vs.vector(cam_dist, 0, 0), linelen, ray)
示例#13
0
def acceleration(A: vp.sphere, B: vp.sphere) -> vp.vec:
    """Returns the acceleration on A from B due to gravitational attraction.
        Note: returns a vp.vec object."""
    denom = vp.mag(A.pos - B.pos)**3
    if np.isclose(denom, 0):
        return vp.vec(1E20, 1E20, 1E20)
    return -G * B.mass * (A.pos - B.pos) / denom
示例#14
0
 def __init__(self, pos, mass, orbitalParentmass, orbitalParentpos,
              orbitalParentv):
     self.age = 0
     self.mass = mass
     self.planet = sphere(pos=pos,
                          radius=((3 * self.mass) / (4 * pi * 3000))**(1 /
                                                                       3),
                          make_trail=True,
                          retain=5000)
     self.colorMe()
     self.G = 6.7e-11
     r = orbitalParentpos.x - self.planet.pos.x
     rmag = abs(r)
     inner = self.G * orbitalParentmass / rmag
     self.v = vector(
         orbitalParentv.x, 0,
         orbitalParentv.z + (random.choice([-1, 1]) * math.sqrt(inner)) +
         random.randint(0, 100))
     self.p = self.mass * self.v
     self.Vol = (4 * pi * (self.planet.radius**3)) / 3
     self.name = (''.join(
         [random.choice(string.ascii_letters) for n in range(4)])).lower()
     self.name = self.name.capitalize()
     self.label = label(pos=self.planet.pos,
                        height=16,
                        yoffset=5,
                        text=self.name + "\n" + str(int(mag(self.v))) +
                        "m/s",
                        line=False)
     print("New Planet " + self.name)
    def update_grid(self):
        """
        Update the grid axes and numbers if the camera position/rotation has changed.
        """
        # Obtain the new camera settings
        new_camera_pos = vector(self.__scene.camera.pos)
        new_camera_axes = vector(self.__scene.camera.axis)

        old_camera_pos = vector(self.camera_pos)
        old_camera_axes = vector(self.camera_axes)

        # Update old positions
        self.camera_pos = new_camera_pos
        self.camera_axes = new_camera_axes

        distance_from_center = mag(self.__scene.center -
                                   self.__scene.camera.pos)
        new_scale = round(distance_from_center / 30.0, 1)
        if not new_scale == self.__scale:
            self.set_scale(new_scale)

        # If camera is different to previous: update
        if (not new_camera_axes.equals(old_camera_axes)) or (
                not new_camera_pos.equals(old_camera_pos)):
            # Update grid
            self.__move_grid_objects()
            update_grid_numbers(self.__focal_point,
                                self.grid_object[self.__labels_idx],
                                self.__num_squares, self.__scale, self.__is_3d,
                                self.__scene)
示例#16
0
def force_grav(A,B):
    """
    Renvoie un vecteur de la force exercé par A sur B
    """
    d = mag(A.sph.pos - B.sph.pos) # distance entre les deux objets
    u = norm(A.sph.pos - B.sph.pos) # vecteur unitaire entre les deux objets
    F = u*((G* A.mass * B.mass)/(d**2)) # Calcul de F, le force gravitationnelle entre les deux objets
    return F
示例#17
0
def create_line(pos1,
                pos2,
                scene,
                colour=None,
                thickness=0.01,
                opacity=1):  # pragma nocover
    """
    Create a line from position 1 to position 2.

    :param scene: The scene in which to draw the object
    :type scene: class:`vpython.canvas`
    :param pos1: 3D position of one end of the line.
    :type pos1: class:`vpython.vector`
    :param pos2: 3D position of the other end of the line.
    :type pos2: class:`vpython.vector`
    :param colour: RGB list to colour the line to
    :type colour: `list`
    :param thickness: Thickness of the line
    :type thickness: `float`
    :param opacity: Opacity of the line
    :type opacity: `float`
    :raises ValueError: RGB colour must be normalised between 0->1
    :raises ValueError: Thickness must be greater than 0
    :return: A box resembling a line
    :rtype: class:`vpython.box`
    """
    # Set default colour
    # Stops a warning about mutable parameter
    if colour is None:
        colour = [0, 0, 0]

    if colour[0] > 1.0 or colour[1] > 1.0 or colour[2] > 1.0 or \
            colour[0] < 0.0 or colour[1] < 0.0 or colour[2] < 0.0:
        raise ValueError("RGB values must be normalised between 0 and 1")

    if thickness < 0.0:
        raise ValueError("Thickness must be greater than 0")

    # Length of the line using the magnitude
    line_len = mag(pos2 - pos1)

    # Position of the line is the midpoint (centre) between the ends
    position = (pos1 + pos2) / 2

    # Axis direction of the line (to align the box (line) to intersect the
    # two points)
    axis_dir = pos2 - pos1

    # Return a box of thin width and height to resemble a line
    # thickness = 0.01
    return box(canvas=scene,
               pos=position,
               axis=axis_dir,
               length=line_len,
               width=thickness,
               height=thickness,
               color=vector(colour[0], colour[1], colour[2]),
               opacity=opacity)
示例#18
0
 def update(self, dt):
     # forces
     axis, theta = _euler.euler2axangle(self.pqr.x, self.pqr.y, self.pqr.z)
     axis = _vp.vector(axis[0], axis[1], axis[2])
     up = _vp.rotate(_vp.vector(0,1,0), theta, axis)
     a = _vp.vector(0, -_gravity, 0)
     a = a + (self.thrust1+self.thrust2+self.thrust3+self.thrust4)/self.mass * up + self.wind/self.mass
     a = a - (_lin_drag_coef * _vp.mag(self.xyz_dot)**2)/self.mass * self.xyz_dot
     self.xyz_dot = self.xyz_dot + a * dt
     # torques (ignoring propeller torques)
     cg = self.cgpos * up
     tpos1 = _vp.rotate(_vp.vector(1.3*_size,0,0), theta, axis)
     tpos2 = _vp.rotate(_vp.vector(0,0,1.3*_size), theta, axis)
     tpos3 = _vp.rotate(_vp.vector(-1.3*_size,0,0), theta, axis)
     tpos4 = _vp.rotate(_vp.vector(0,0,-1.3*_size), theta, axis)
     torque = _vp.cross(cg, _vp.vector(0, -_gravity, 0))
     torque = torque + _vp.cross(tpos1, self.thrust1 * up)
     torque = torque + _vp.cross(tpos2, self.thrust2 * up)
     torque = torque + _vp.cross(tpos3, self.thrust3 * up)
     torque = torque + _vp.cross(tpos4, self.thrust4 * up)
     torque = torque - _rot_drag_coef * self.pqr_dot
     aa = torque/self.inertia
     if _vp.mag(aa) > 0:
         aai, aaj, aak = _euler.axangle2euler((aa.x, aa.y, aa.z), _vp.mag(aa))
         aa = _vp.vector(aai, aaj, aak)
         self.pqr_dot = self.pqr_dot + aa * dt
     else:
         self.pqr_dot = _vp.vector(0,0,0)
     # ground interaction
     if self.xyz.y <= 0:
         self.xyz.y = 0
         if self.xyz_dot.y <= 0:
             self.xyz_dot.x = self.xyz_dot.x * _ground_friction
             self.xyz_dot.y = 0
             self.xyz_dot.z = self.xyz_dot.z * _ground_friction
             self.pqr_dot = self.pqr_dot * _ground_friction
     # energy update
     self.energy += _power_coef * (self.thrust1**1.5 + self.thrust2**1.5 + self.thrust3**1.5 + self.thrust4**1.5) * dt
     # time update
     self.xyz += self.xyz_dot * dt
     self.pqr += self.pqr_dot * dt
     # callback
     if self.updated is not None:
         self.updated(self)
     self.draw()
def urto_elastico(body0, body1):
    '''collisione elastica in 3 dimensioni'''
    vrel = body0.velocity - body1.velocity
    rrel = body0.pos - body1.pos
    distance = mag(rrel)
    ratio0 = 2 * body1.mass / (body0.mass + body1.mass)
    ratio1 = 2 * body0.mass / (body0.mass + body1.mass)
    body0.velocity += -ratio0 * dot(vrel, rrel) / distance**2 * rrel
    body1.velocity += -ratio1 * dot(-vrel, -rrel) / distance**2 * (-rrel)
示例#20
0
def colision_part_2(obj_1, obj_2):
    if vp.mag(obj_1.pos - obj_2.pos) < 2 * r_p:
        delta_v_1 = obj_1.vel - obj_2.vel
        delta_p_1 = obj_1.pos - obj_2.pos
        delta_v_2 = obj_2.vel - obj_1.vel
        delta_p_2 = obj_2.pos - obj_1.pos

        coef_1 = (vp.dot(delta_v_1, delta_p_1)) / (vp.dot(
            delta_p_1, delta_p_1))
        coef_2 = (vp.dot(delta_v_2, delta_p_2)) / (vp.dot(
            delta_p_2, delta_p_2))

        obj_1.vel = obj_1.vel - coef_1 * (obj_1.pos - obj_2.pos)
        obj_2.vel = obj_2.vel - coef_2 * (obj_2.pos - obj_1.pos)

        lambda_1 = (2 * r_p -
                    (vp.mag(obj_1.pos - obj_2.pos))) / (vp.mag(obj_1.vel))
        obj_1.pos = obj_1.pos + lambda_1 * obj_1.vel
 def check_collisions(self):
     for index, body in enumerate(self.bodies):
         for other_index, other_body in enumerate(self.bodies):
             if index != other_index:
                 distance = mag(body.pos - other_body.pos)
                 if distance <= (body.radius + other_body.radius):
                     if [other_index, index] not in self.collided_couples:
                         self.collided_couples.append([index, other_index])
     return (self.collided_couples)
示例#22
0
def init_acc(centr_body, position):
    ''' Calculates acceleration of an orbiting object due to the centr_body '''
    # neglect forces from bodies other than the one it is orbiting
    if position != centr_body.position:
        radius_vec = position - centr_body.position
        acceleration = -G * centr_body.mass * radius_vec / vp.mag(radius_vec)**3
    else:
        acceleration = vp.vector(0,0,0)  # for sun
        
    return acceleration 
示例#23
0
    def calculate_acceleration(self, other=None):
        if other is None:
            super().calculate_acceleration()
        else:
            r0 = self.body.pos - self.origin
            l0 = self.length
            dl0 = vp.mag(r0) - l0
            self.dl = dl0  # useful to calculate potential energy
            r1 = other.body.pos - other.origin
            l1 = other.length
            dl1 = vp.mag(r1) - l1

            if dl0 / l0 < -0.95 or dl1 / l1 < -0.95:
                raise ValueError('Spring too compressed')
            else:
                dr0 = r0 * (dl0 / vp.mag(r0))
                dr1 = r1 * (dl1 / vp.mag(r1))
                self.acceleration = -(self.k * dr0) / self.m + (other.k *
                                                                dr1) / self.m
示例#24
0
    def __universal_gravitation(self, sphere_one, sphere_two):
        """ Uses Newton's Law of Universal Gravitation to find the force of gravity on
        the first sphere due to the second sphere.

        :param sphere_one: (Sphere) VPython sphere for first sphere.
        :param sphere_two: (Sphere) VPython sphere for second sphere.
        :return: (VPython vector) Force vector due to gravity on sphere_one from sphere_two.
        """

        position_vector = sphere_one.pos - sphere_two.pos
        return -self._gravity*sphere_one.mass*sphere_two.mass*position_vector/mag(position_vector)**3
def choque(
        foton: object) -> list:  #choque de un foton, cambia longitud de onda.
    v = vp.mag(foton.velocidad)
    theta = np.random.random() * np.pi * 2
    phi = np.arccos(np.random.random() * 2 - 1)
    vx = v * np.sin(theta) * np.cos(phi)
    vy = v * np.sin(theta) * np.sin(phi)
    vz = v * np.cos(theta)
    wave_lenghtf = theta_a_wl(theta)
    #retorna la direción de la velocidad nueva y la longitud de onda nueva
    return vp.vector(vx, vy, vz), wave_lenghtf
示例#26
0
 def update(self, dt, solarObjects):
     self.age = self.age + dt
     Ftotal = vector(0, 0, 0)
     for solarObject in solarObjects:
         if solarObject.name == self.name:
             continue
         r = solarObject.planet.pos - self.planet.pos
         rmag = mag(r)
         if rmag < (self.planet.radius + solarObject.planet.radius):
             if self.mass > solarObject.mass:
                 solarObject.planet.visible = 0
                 solarObject.planet.clear_trail()
                 solarObject.label.visible = False
                 self.Vol = self.Vol + solarObject.Vol
                 self.planet.radius = ((self.Vol * 3) / (4 * pi))**(1 / 3)
                 self.mass = self.mass + solarObject.mass
                 self.v = (self.p + solarObject.p) / self.mass
                 solarObjects.remove(solarObject)
                 print(solarObject.name + " collided with " + self.name)
             else:
                 self.planet.visible = 0
                 self.planet.clear_trail()
                 self.label.visible = False
                 solarObject.Vol = self.Vol + solarObject.Vol
                 solarObject.planet.radius = ((solarObject.Vol * 3) /
                                              (4 * pi))**(1 / 3)
                 solarObject.mass = self.mass + solarObject.mass
                 solarObject.v = (self.p + solarObject.p) / solarObject.mass
                 solarObjects.remove(self)
                 print(self.name + " collided with " + solarObject.name)
             self.colorMe()
         Fmag = self.G * self.mass * solarObject.mass / (rmag**2)
         rhat = r / rmag
         Fnet = Fmag * rhat
         Ftotal = Ftotal + Fnet
     self.v = self.v + ((Ftotal / self.mass) * dt)
     self.p = self.v * self.mass
     self.planet.pos = self.planet.pos + (self.v * dt)
     self.label.pos = self.planet.pos
     self.label.text = self.name + "\n" + str(int(mag(self.v))) + "m/s"
     return solarObjects
示例#27
0
 def doAutoscale(self):
     if len(self.drawables_[0].activeDia) == 0:
         print("Warning: No values to display in Moogli view ", self.title)
         return
     cmin = self.drawables_[0].coordMin
     cmax = self.drawables_[0].coordMax
     diamax = max(self.drawables_[0].activeDia)
     v0 = vp.vector(cmin[0], cmin[1], cmin[2])
     v1 = vp.vector(cmax[0], cmax[1], cmax[2])
     #self.scene.camera.axis = self.scene.forward * vp.mag(v1 - v0) * 4
     self.scene.center = (v0 + v1) / 2.0
     self.scene.range = (diamax + vp.mag(v0 - v1)) / 1.5
 def partially_inelastic_collision(self):
     # totally inelastic collision, but if the couple of bodies collides with others can breack
     for indexs in self.collided_couples:
         body0 = self.bodies[indexs[0]]
         body1 = self.bodies[indexs[1]]
         m0 = body0.mass
         m1 = body1.mass
         # grow body 1
         cm_pos = (body0.pos * m0 + body1.pos * m1) / (m0 + m1)
         cm_velocity = (body0.velocity * m0 + body1.velocity * m1) / (m0 +
                                                                      m1)
         dr0 = body0.pos - cm_pos
         dv0 = body0.velocity - cm_velocity
         dr1 = body1.pos - cm_pos
         dv1 = body1.velocity - cm_velocity
         omega0 = cross(-dv0, dr0) / mag(dr0)**2
         omega1 = cross(-dv1, dr1) / mag(dr1)**2
         #assert omega0 == omega1
         body0.velocity = cm_velocity + cross(omega0, dr0)
         body1.velocity = cm_velocity + cross(omega1, dr1)
     self.collided_couples.clear()
示例#29
0
def calc_forces(dt, body1, body2):
    dist = vp.mag(body1.pos - body2.pos)
    if dist <= body1.radius or dist <= body2.radius:
        print('Impact. The end.')
        exit()

    grav_mag = (GRAVITY_ACC * body1.mass * body2.mass) / (dist**2)

    dir1 = vp.norm(body2.pos - body1.pos)
    dir2 = vp.norm(body1.pos - body2.pos)
    body1.force += dir1 * grav_mag
    body2.force += dir2 * grav_mag
 def calculate_center_of_mass_and_energy(self):
     c_m = vector(0, 0, 0)
     v_m = vector(0, 0, 0)
     m_tot = 0
     KE = 0
     for index, body in enumerate(self.bodies):
         c_m += body.mass * body.pos
         v_m += body.mass * body.velocity
         m_tot += body.mass
         KE += 1 / 2 * body.mass * mag(body.velocity)**2
     print('Kinetic Energy (J):', KE)
     #print('Center of Mass velocity:', mag(v_m/m_tot))
     return c_m / m_tot, KE