コード例 #1
0
def n_sphere_collide(centreA, radiusA, centreB, radiusB, nmetric=2):
    """
    Find whether two spheres intersect.
    Also consider convex and concave p-spheres.
    """
    distance = metrics.general_n_euclid_metric(centreA, centreB, nmetric)

    collision = distance < radiusA + radiusB

    # for convex objects, collision occurs when the distance
    if nmetric >= 1:
        # convex
        pass  # collision test already done

    else:
        # concave

        # for concave objects, need to check all the corners.
        #                                                   ^
        # Rotation is simple, always orientated like this  < >
        #                                                   v
        cont = not collision
        n = len(centreA)
        corner_ls = list(centreA.components)
        i = 0

        while cont:
            if i == n:
                cont = False
            else:
                corner_ls[i] = corner_ls[i] + radiusA
                corner_vec = vector.Vector(corner_ls)

                collision = metrics.general_n_euclid_metric(
                    corner_vec, centreB, nmetric) < radiusB
                cont = not collision

                corner_ls[i] = corner_ls[i] - radiusA

                if cont:
                    corner_ls[i] = corner_ls[i] - radiusA
                    corner_vec = vector.Vector(corner_ls)

                    collision = metrics.general_n_euclid_metric(
                        corner_vec, centreB, nmetric) < radiusB
                    cont = not collision

                    corner_ls[i] = corner_ls[i] + radiusA
                    i += 1

    return collision
コード例 #2
0
    def __init__(self,
                 id,
                 X0,
                 V0,
                 m=1,
                 r=1,
                 q=0,
                 colour=colour.black,
                 name=""):
        """
        Construct the body object.
        :X0: gives the intial position of the object
        :V0: gives the inital velocity of the object
        :m: - inertial and gravitational mass. Recall F=ma
        :r: - radius of the object, assume sphere
        :q: - charge of the object, used to give secondary force, independent of inertial mass.
        :id: - identification number for object.
        """

        if isinstance(X0, vector.Vector):
            self.X = X0
        else:
            self.X = vector.Vector(X0)
        if isinstance(V0, vector.Vector):
            self.V = V0
        else:
            self.V = vector.Vector(V0)

        self.id = id

        #self.X_prev = self.X
        #self.V_prev = self.V

        self.mass = m
        self.radius = r
        self.charge = q
        self.colour = colour

        self.trail_history = TrailHistory()
        self.anchor = False
        self.elasticity = 1
        self.can_collide = False
        self.drag = False

        self.name = name
コード例 #3
0
    def check_wall_collision(self, bod:body.Body, del_x:vector.Vector):
        """
        Given the new point a ball will be, find if it collides with the boundary wall/box.
        Return whether collision occured, the normal vector to the wall, and the new_delta_x value.
        
        new_delta_x is the delta_x such that when updated, the body lies touching the wall.
        """
        collision = False
        vec = None
        new_del_x = None

        if self.wall == None:
            pass
        elif bod.can_collide or self.all_wall_collide:
            
            n = len(self.wall)
            vec_components = [0] * n
            r = bod.radius
            
            new_x = bod.X + del_x
            component_length = 1
            new_component_length = 1

            i = 0
            while i < n:
                xi = new_x.components[i]
                abs_wall = abs(self.wall.components[i])
                
                xi_distance = abs_wall - r - abs(xi)
                
                if xi_distance >= 0:
                    pass # no collision
                else:
                    component_length = abs(del_x.components[i])
                    new_component_length = component_length + xi_distance

                    # collision occured, update normal vector.
                    collision = True
                    if xi >= 0:
                        vec_components[i] = -1
                    else:
                        vec_components[i] = 1
                i += 1
                    
            tmp_vec = vector.Vector(vec_components)
            vec = metrics.unit_vector(tmp_vec, self._nmetric)
            
            if collision:
                if component_length == 0:
                    new_del_x = vector.Vector.zero_vector(n)
                else:
                    new_del_x = (new_component_length / component_length) * del_x

        return collision, vec, new_del_x
コード例 #4
0
    def get_pos_vector(self, pos, n):
        # n is the dimension of the vector
        x, y = pos

        vec = [0] * n
        x_pos = self.get_x_pos(x)
        y_pos = self.get_y_pos(y)

        vec[self.proj[0]] = x_pos
        vec[self.proj[1]] = y_pos

        return v.Vector(vec)
コード例 #5
0
    def get_delta_pos_vector(self, pos1, pos2, n):
        x1, y1 = pos1
        x2, y2 = pos2

        vec = [0] * n
        x_pos1 = self.get_x_pos(x1)
        y_pos1 = self.get_y_pos(y1)
        x_pos2 = self.get_x_pos(x2)
        y_pos2 = self.get_y_pos(y2)

        vec[self.proj[0]] = x_pos2 - x_pos1
        vec[self.proj[1]] = y_pos2 - y_pos1

        return v.Vector(vec)
コード例 #6
0
def parse_vector(strings: list, parent_name: str, variables: dict):
    """
    Given a string representation of a vector parse it.
    """
    if len(strings) != 1:
        param_error(parent_name, strings, 1)
    string = strings[0]

    key_values = parse.parse_key_values(string, parent_name)

    if len(key_values) != 1:
        raise ValueError("\nFile Trace: {0}\nInvalid number of Vector attributes:\n '{1}'"\
                         .format(parent_name, string))
    else:
        name = key_values[0][0]
        value = key_values[0][1]

        string_ls = value.split(",")
        n = len(string_ls)

        vec = [0] * n
        i = 0
        while i < n:
            sub_str = string_ls[i]

            if sub_str == '':
                raise ValueError("\nStack Trace: {0}\nCannot Make vector of zero length."\
                                 .format(parent_name))
            else:
                tmp = parse.parse_maths_string(sub_str, parent_name, variables)
                if tmp == None:
                    raise ValueError("\nStack Trace: {0}\nMissing vector component.\n '{1}'"\
                                    .format(string))
                else:
                    vec[i] = tmp
            i += 1

        if name == "" or name == cart_str:
            return vector.Vector(vec)
        elif name == polar_str:
            radius = vec[0]
            angles = vec[1:len(vec)]
            return vector.Vector.polar_vector(radius, angles)
        else:
            raise NameError("\nStack Trace: {0}\nUnknown keyword '{1}'."\
                            .format(parent_name, name))
コード例 #7
0
        vec[self.proj[0]] = x_pos2 - x_pos1
        vec[self.proj[1]] = y_pos2 - y_pos1

        return v.Vector(vec)


if __name__ == "__main__":
    pygame.init()
    UScreen = UniverseScreen()

    #bod = b.Body()
    zero2 = v.Vector.zero_vector(2)
    uni = u.Universe(zero2)
    uni.add_body(zero2, zero2, r=20, colour=col.green)
    uni.add_body(v.Vector([100, -50]), zero2, r=20, colour=col.blue)

    UScreen.update_projection(uni)

    run = True
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

        UScreen.draw_2dprojection_universe(uni)

        pygame.display.update()

    pygame.quit()
コード例 #8
0


#####  Extra

def sign(x):
    if x < 0:
        return -1
    else:
        return 1



if __name__ == "__main__":
    zero_vec = vector.Vector.zero_vector(2)
    v1 = vector.Vector([1,0])
    v2 = vector.Vector([-1,0])
    
    b1 = body.Body(1, v1, zero_vec)
    b2 = body.Body(2, v2, zero_vec)
    
    u = Universe(zero_vec, b1, b2)
    
    
    print(u.net_force(b1.id, b1.X, b1.V))
    i = 0
    while i < 20:
        u.runge_kutta_method(b1, 1)
        print(u.net_force(b1.id, b1.X, b1.V))
        i += 1