def __init__(self, a, b): self.LHS=a self.RHS=b d1 = pymunk.DampedSpring(a.body, b.body, (R,R),(-R,R), 0, S, D) d2 = pymunk.DampedSpring(a.body, b.body, (R,R/2),(-R,R/2), 0, S, D) d3 = pymunk.DampedSpring(a.body, b.body, (R,-R/2),(-R,-R/2), 0, S, D) d4 = pymunk.DampedSpring(a.body, b.body, (R,-R),(-R,-R), 0 , S, D) #d1.collide_bodies=False self.joints=[d1,d2,d3,d4] self.LHS.right_bond=self self.RHS.left_bond=self a.world.space.add(d1,d2,d3,d4)
def add_spring_constraint(self, b1, b2, loc1=(0, 0), loc2=(0, 0), params=None): if params == None: rest_length = np.random.randint(SPRING_LIMITS[0][0], SPRING_LIMITS[0][1]) stiffness = np.random.randint(SPRING_LIMITS[1][0], SPRING_LIMITS[1][1]) # damping = np.random.gamma(1, 0.5) damping = 0 params = [rest_length, stiffness, damping] # if self.verbose: # print('Adding spring to {}-{}; {}, {}'.format(self.bodies.index(b1), self.bodies.index(b2), params[0], params[1])) spring_joint = pymunk.DampedSpring(b1, b2, loc1, loc2, params[0], params[1], params[2]) self.space.add(spring_joint) if type(self) == SimulationScene: indices = (self.bodies.index(b1), self.bodies.index(b2)) self.constraints[(min(indices), max(indices))] = spring_joint return spring_joint
def add_player(space, pos): body = pymunk.Body(100, pymunk.inf) ####Body body.position = pos bodyShape = pymunk.Circle(body, 20, (0, 0)) bodyShape.friction = 0.1 bodyShape.elasticity = 0.0 bodyShape.filter = pymunk.ShapeFilter(mask=pymunk.ShapeFilter.ALL_MASKS ^ 1) bodyShape.collision_type = 1 space.add(body, bodyShape) contact = pymunk.Body(10, 1000) ####Sole contact.position = (pos[0], pos[1] - 100) contactRadius = 2 contactShape = pymunk.Segment(contact, (0, 0), (0, 100), 4) contactShape.filter = pymunk.ShapeFilter(categories=1) contactShape.friction = 3.5 contactShape.elasticity = 0.0 contactShape.collision_type = 2 space.add(contact, contactShape) ##################Adding constraints to a system################ slider = pymunk.GrooveJoint(contact, body, (0, -100), (0, 200), (0, 0)) space.add(slider) spring = pymunk.DampedSpring(contact, body, (0, 0), (0, 0), 100, 20000, 200) space.add(spring) return [body, contact, spring]
def testDebugDrawZeroLengthSpring(self): if sys.version_info < (3, 0): return s = p.Space() b1 = p.Body(1, 3) c = p.DampedSpring(b1, s.static_body, (0, 0), (0, 0), 0, 10, 1) s.add(b1, c) s.step(1) o = p.SpaceDebugDrawOptions() new_out = io.StringIO() sys.stdout = new_out try: s.debug_draw(o) finally: sys.stdout = sys.__stdout__ expected = ( "draw_dot (5.0, Vec2d(0.0, 0.0), SpaceDebugColor(r=142.0, g=68.0, b=173.0, a=255.0))\n" "draw_dot (5.0, Vec2d(0.0, 0.0), SpaceDebugColor(r=142.0, g=68.0, b=173.0, a=255.0)) \n" "draw_segment (Vec2d(0.0, 0.0), Vec2d(0.0, 0.0), SpaceDebugColor(r=142.0, g=68.0, b=173.0, a=255.0))\n" "draw_segment (Vec2d(0.0, 0.0), Vec2d(0.0, 0.0), SpaceDebugColor(r=142.0, g=68.0, b=173.0, a=255.0))\n" ) actual = new_out.getvalue() try: self.assertEqual(expected, actual) except: print("\nExpected", expected) print("\nActual", actual) raise
def add_joint(a, b): rl = a.position.get_distance(b.position) * 0.9 stiffness = 5000. damping = 100 j = pymunk.DampedSpring(a, b, (0, 0), (0, 0), rl, stiffness, damping) j.max_bias = 1000 space.add(j)
def update(self, time: float, dt: float): if self.move_normal is not None: for i, foot in enumerate(self.feet): #want_contact = .0 < math.sin(self.feet_rotation_movement * 10. + i / len(self.feet) * math.pi * 2) want_contact = .0 < foot.normal().dot(self.move_normal) if want_contact and not foot.world_joint: #foot_world_pos = self.object.position + foot.relative_pos.rotated(self.object.rotation) foot_world_pos = foot.object.position info = self.space.point_query_nearest( point=foot_world_pos + .1 * self.move_normal, max_distance=foot.radius*1.3, shape_filter=ShapeFilter(mask=ShapeFilter.ALL_MASKS() ^ 0b1), ) if info: # print("connect", foot.object, info.point, info.shape) foot.world_joint = pymunk.DampedSpring( a=foot.object.body, b=info.shape.body, anchor_a=(0, 0), anchor_b=info.shape.body.world_to_local(info.point), rest_length=0,#foot.radius, stiffness=10000, damping=10, ) self.space.add(foot.world_joint) foot.object.color = (1, 2, 1, 1) if not want_contact and foot.world_joint: # print("disconnect", foot.object) self.space.remove(foot.world_joint) foot.world_joint = None foot.object.color = (1, 1, 1, 1)
def main(): pygame.init() screen = pygame.display.set_mode((1000, 1000)) pygame.display.set_caption("Ball moving") clock = pygame.time.Clock() space = pymunk.Space() space.gravity = (0.0, 0.0) objects = [] draw_options = pymunk.pygame_util.DrawOptions(screen) harmonic_center_body = pymunk.Body(body_type=pymunk.Body.STATIC) joint_x = random.randint(300, 700) joint_y = random.randint(300, 700) harmonic_center_body.position = (joint_x, joint_y) x_pos = random.randint(300, 700) y_pos = random.randint(300, 700) vel = random.randint(2, 20) string = (joint_x - x_pos, joint_y - y_pos) mag = math.sqrt(string[0]**2 + string[1]**2) velocity = (string[1] / mag * vel, string[0] / mag * vel) shape = add_ball(space, 1, 20, (x_pos, y_pos), velocity, 0) stiffness = random.randint(10, 120) harmonic_center_joint = pymunk.DampedSpring(shape.body, harmonic_center_body, (0, 0), (0, 0), 0, stiffness, 0) space.add(harmonic_center_joint) objects.append(shape) while True: for event in pygame.event.get(): if event.type == QUIT: sys.exit(0) elif event.type == KEYDOWN and event.key == K_ESCAPE: sys.exit(0) space.step(1 / 50.0) screen.fill((255, 255, 255)) # objects_to_remove = [] # for obj in objects: # print (obj) # if obj.body.position.y > 150: # objects_to_remove.append(obj) # for obj in objects_to_remove: # space.remove(obj, obj.body) # objects.remove(obj) space.debug_draw(draw_options) pygame.display.flip() clock.tick(50)
def add_rels(self, param_load=None): param = np.zeros((self.n_ball * (self.n_ball - 1) // 2, 2)) self.param_dim = param.shape[0] if param_load is not None: print("Load param for init env") cnt = 0 rels_idx = [] for i in range(self.n_ball): for j in range(i): rel_type = rand_int( 0, self.n_rel_type) if param_load is None else param_load[cnt, 0] param[cnt, 0] = rel_type rels_idx.append([i, j]) pos_i = self.balls[i].position pos_j = self.balls[j].position if rel_type == 0: # no relation pass elif rel_type == 1: # spring rest_length = rand_float( 20, 120) if param_load is None else param_load[cnt, 1] param[cnt, 1] = rest_length c = pymunk.DampedSpring(self.balls[i], self.balls[j], (0, 0), (0, 0), rest_length=rest_length, stiffness=20, damping=0.) self.space.add(c) elif rel_type == 2: # string rest_length = calc_dis( pos_i, pos_j) if param_load is None else param_load[cnt, 1] param[cnt, 1] = rest_length c = pymunk.SlideJoint(self.balls[i], self.balls[j], (0, 0), (0, 0), rest_length - 5, rest_length + 5) self.space.add(c) else: raise AssertionError("Unknown relation type") cnt += 1 if param_load is not None: assert ((param == param_load).all()) self.rels_idx = rels_idx self.param = param
def input(self): events = pygame.event.get() for event in events: if event.type == pygame.QUIT: self.stop() if event.type == pygame.VIDEORESIZE: self.width = event.dict['size'][0] self.height = event.dict['size'][1] self.screen = pygame.display.set_mode( (self.width, self.height), pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.RESIZABLE) self.widthPixelsPerVirtualPixel = self.width / self.virtualWidth self.heightPixelsPerVirtualPixel = self.height / self.virtualHeight if event.type == pygame.MOUSEBUTTONDOWN: self.clickPosition = list(pygame.mouse.get_pos()) self.clickPosition[0] = self.clickPosition[ 0] / self.widthPixelsPerVirtualPixel self.clickPosition[1] = self.clickPosition[ 1] / self.heightPixelsPerVirtualPixel self.holdingState = True elif event.type == pygame.MOUSEBUTTONUP: self.releasePosition = list(pygame.mouse.get_pos()) self.releasePosition[0] = self.releasePosition[ 0] / self.widthPixelsPerVirtualPixel self.releasePosition[1] = self.releasePosition[ 1] / self.heightPixelsPerVirtualPixel self.holdingState = False self.shapes.sliceShapes( [self.clickPosition, self.releasePosition]) if event.type == pygame.MOUSEMOTION: self.previousPosition = self.currentPosition self.currentPosition = list(pygame.mouse.get_pos()) self.currentPosition[0] = self.currentPosition[ 0] / self.widthPixelsPerVirtualPixel self.currentPosition[1] = self.currentPosition[ 1] / self.heightPixelsPerVirtualPixel self.a.position = self.currentPosition if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: self.shapes.createShape(self.virtualWidth / 2, self.virtualHeight / 2) if event.key == pygame.K_z: b = self.space.point_query_nearest(self.currentPosition, 20, pymunk.ShapeFilter()) if b != None: if self.c != None: self.space.remove(self.c) self.c = pymunk.DampedSpring( self.a, b[0].body, (0, 0), b[0].body.center_of_gravity, 10, 30, 0) self.space.add(self.c) if event.key == pygame.K_x: if self.c != None: self.space.remove(self.c) self.c = None
def mk_static_body(b, x, y): static_body = pymunk.Body(body_type=pymunk.Body.STATIC) static_body.position = vec2d.Vec2d(x, y) l = static_body.position.get_distance(b.position) * 0.9 damping = 15 stiffness = 20 j = pymunk.DampedSpring(static_body, b, (0, 0), (0, 0), l, stiffness, damping) space.add(j)
def create_wheel(self, wheel_side): if wheel_side not in ['rear', 'front']: raise Exception('Wheel position must be front or rear') wheel_objects = [] wheel_mass = getattr(self, wheel_side + '_wheel_mass') wheel_radius = getattr(self, wheel_side + '_wheel_radius') wheel_position = getattr(self, wheel_side + '_wheel_position') wheel_friction = getattr(self, wheel_side + '_wheel_friction') wheel_elasticity = getattr(self, wheel_side + '_wheel_elasticity') wheel_damp_position = getattr(self, wheel_side + '_wheel_damp_position') wheel_damp_length = getattr(self, wheel_side + '_wheel_damp_length') wheel_damp_stiffness = getattr(self, wheel_side + '_wheel_damp_stiffness') wheel_damp_damping = getattr(self, wheel_side + '_wheel_damp_damping') wheel_body = pymunk.Body( wheel_mass, pymunk.moment_for_box(wheel_mass, (wheel_radius * 2, wheel_radius * 2))) wheel_body.position = (wheel_position[0] * self.x_modification, wheel_position[1]) wheel_shape = pymunk.Poly.create_box( wheel_body, (wheel_radius * 2, wheel_radius * 2)) wheel_shape.filter = pymunk.ShapeFilter(group=self.car_group) wheel_shape.color = 255, 34, 150 wheel_shape.friction = wheel_friction wheel_shape.elasticity = wheel_elasticity wheel_objects.append(wheel_shape) wheel_grove = pymunk.GrooveJoint( self.car_body, wheel_body, (wheel_damp_position[0] * self.x_modification, wheel_damp_position[1]), (wheel_damp_position[0] * self.x_modification, wheel_damp_position[1] - wheel_damp_length * 1.5), (0, 0)) wheel_objects.append(wheel_grove) wheel_damp = pymunk.DampedSpring( wheel_body, self.car_body, anchor_a=(0, 0), anchor_b=(wheel_damp_position[0] * self.x_modification, wheel_damp_position[1]), rest_length=wheel_damp_length, stiffness=wheel_damp_stiffness, damping=wheel_damp_damping) wheel_objects.append(wheel_damp) wheel_motor = None if (wheel_side == 'rear' and self.drive in [self.AWD, self.FR]) or ( wheel_side == 'front' and self.drive in [self.AWD, self.FF]): wheel_motor = pymunk.SimpleMotor(wheel_body, self.car_body, 0) return wheel_body, wheel_motor, wheel_objects
def createSpring(self, bodyA, bodyB, anchorA, anchorB, restLength): joint = pymunk.DampedSpring(bodyA, bodyB, anchorA, anchorB, restLength, stiffness=0.5, damping=0.5) self.space.add(joint)
def testAnchor(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.DampedSpring(a, b, (1, 2), (3, 4), 0, 0, 0) self.assertEqual(j.anchor_a, (1, 2)) self.assertEqual(j.anchor_b, (3, 4)) j.anchor_a = (5, 6) j.anchor_b = (7, 8) self.assertEqual(j.anchor_a, (5, 6)) self.assertEqual(j.anchor_b, (7, 8))
def build(space, group): # type: (pymunk.Space, pygame.sprite.AbstractGroup) -> CatModel """ Builds our unicycle cat. :param space: The pymunk space to put the cat in. :param group: The pygame sprite group to put the cat in. """ scale = 2 normal_rect = pygame.Rect(0, 0, 32 * scale, 40 * scale) cat_model = CatModel() sprites = [] pymunk_objects = [] filter1 = pymunk.ShapeFilter(group=0b000001) # Main body body_body = pymunk.Body(0.00001, pymunk.inf) body_body.position = normal_rect.topleft cat_model.main_body = body_body pymunk_objects.append(body_body) # seat seat_body = build_seat(filter1, normal_rect, pymunk_objects, sprites) # build feet cat_model.feet, feet_sprite = build_feet(filter1, normal_rect, pymunk_objects, body_body, seat_body) sprites.append(feet_sprite) # Add motor cat_model.motor = pymunk.SimpleMotor(body_body, cat_model.feet, 0.0) pymunk_objects.append(cat_model.motor) # cat cat_body, cat_rect = build_cat(normal_rect, pymunk_objects, sprites) # hold cat the the seat spring = pymunk.DampedSpring(seat_body, cat_body, normal_rect.midtop, cat_rect.midbottom, 0, 1, 0) pymunk_objects.append(spring) # tilt corrector spring = pymunk.DampedRotarySpring(body_body, seat_body, radians(0), 60000, 20000) spring.collide_bodies = False pymunk_objects.append(spring) cat_model.sprites = sprites cat_model.pymunk_objects = pymunk_objects space.add(pymunk_objects) group.add(*sprites) return cat_model
def __init__(self, space, p1, shape1, p2, shape2, length, stiffness, damping): # Associate the joint with the location of one of the bodies so # it is removed when that body is out of the simulation self.body = shape1.body self.shape = pymunk.DampedSpring(shape1.body, shape2.body, p1, p2, length, stiffness, damping) super().__init__() space.add(self.shape)
def on_mouse_press(x, y, button, modifiers): mouse_body.position = x,y hit = space.point_query_nearest((x,y), 10, pymunk.ShapeFilter()) if hit != None: global selected body = hit.shape.body rest_length = mouse_body.position.get_distance(body.position) stiffness = 1000 damping = 10 selected = pymunk.DampedSpring(mouse_body, body, (0,0), (0,0), rest_length, stiffness, damping) space.add(selected)
def add_joint(a, b): global spring_stiffness global spring_damping_factor global spring_max_force rl = a.position.get_distance(b.position) * 1.0 # @parameter stiffness = spring_stiffness / (9 / num_levels) damping = spring_damping_factor j = pymunk.DampedSpring(a, b, (0, 0), (0, 0), rl, stiffness, damping) # j.max_bias = 1000 # @parameter j.max_force = spring_max_force space.add(j)
def create_physics(self): constraint = pymunk.DampedSpring( self.a.body, self.b.body, anchor_a=self.anchor_a, anchor_b=self.anchor_b, rest_length=self.rest_length, stiffness=self.stiffness, damping=self.damping, ) self._constraint = constraint self.engine.space.add(constraint)
def handle_moving_platform(self, shape): logger.info('loading moving platform %s', shape) assert (not shape.body.is_static) shape.layers = 3 shape.collision_type = 0 shape.body.velocity_func = ignore_gravity shape.body.moment = pymunk.inf shape.cache_bb() bb = shape.bb rect = pygame.Rect( (bb.left, bb.top, bb.right - bb.left, bb.top - bb.bottom)) rect.normalize() height = 100 anchor1 = shape.body.position anchor2 = shape.body.position - (0, height) joint = pymunk.GrooveJoint(self.space.static_body, shape.body, anchor1, anchor2, (0, 0)) spring = pymunk.DampedSpring(self.space.static_body, shape.body, anchor2, (0, 0), height, 10000, 50) self.space.add(joint, spring) gids = [self.tmx_data.map_gid(i)[0][0] for i in (1, 2, 3)] colorkey = (255, 0, 255) tile_width = self.tmx_data.tilewidth s = pygame.Surface((rect.width, rect.height)) s.set_colorkey(colorkey) s.fill(colorkey) tile = self.tmx_data.getTileImageByGid(gids[0]) s.blit(tile, (0, 0)) tile = self.tmx_data.getTileImageByGid(gids[1]) for x in range(0, rect.width - tile_width, tile_width): s.blit(tile, (x, 0)) tile = self.tmx_data.getTileImageByGid(gids[2]) s.blit(tile, (rect.width - tile_width, 0)) spr = sprite.BoxSprite(shape) spr.original_surface = s m = models.Basic() m.sprite = spr self.add_model(m)
def testPickle(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.DampedSpring(a, b, (1, 2), (3, 4), 5, 6, 7) s = pickle.dumps(j) j2 = pickle.loads(s) self.assertEqual(j.anchor_a, j2.anchor_a) self.assertEqual(j.anchor_b, j2.anchor_b) self.assertEqual(j.rest_length, j2.rest_length) self.assertEqual(j.stiffness, j2.stiffness) self.assertEqual(j.damping, j2.damping) self.assertEqual(j.a.mass, j2.a.mass) self.assertEqual(j.b.mass, j2.b.mass)
def create_wheel(self, wheel_side): if wheel_side not in ['rear', 'front']: raise Exception('Wheel position must be front or rear') wheel_objects = [] wheel_mass = getattr(self, wheel_side + '_wheel_mass') wheel_radius = getattr(self, wheel_side + '_wheel_radius') wheel_position = getattr(self, wheel_side + '_wheel_position') wheel_friction = getattr(self, wheel_side + '_wheel_friction') wheel_elasticity = getattr(self, wheel_side + '_wheel_elasticity') wheel_joint = getattr(self, wheel_side + '_wheel_joint') wheel_damp_position = getattr(self, wheel_side + '_wheel_damp_position') wheel_damp_length = getattr(self, wheel_side + '_wheel_damp_length') wheel_damp_stiffness = getattr(self, wheel_side + '_wheel_damp_stiffness') wheel_damp_damping = getattr(self, wheel_side + '_wheel_damp_damping') wheel_body = pymunk.Body(wheel_mass, pymunk.moment_for_circle(wheel_mass, 0, wheel_radius)) wheel_body.position = (wheel_position[0] * self.x_modification, wheel_position[1]) wheel_shape = pymunk.Circle(wheel_body, wheel_radius) wheel_shape.filter = pymunk.ShapeFilter(group=self.car_group) wheel_shape.color = 255, 34, 150 wheel_shape.friction = wheel_friction wheel_shape.elasticity = wheel_elasticity wheel_objects.append(wheel_shape) wheel_joint = pymunk.PinJoint(wheel_body, self.car_body, anchor_b=(wheel_joint[0] * self.x_modification, wheel_joint[1])) wheel_objects.append(wheel_joint) wheel_damp = pymunk.DampedSpring(wheel_body, self.car_body, anchor_a=(0, 0), anchor_b=(wheel_damp_position[0] * self.x_modification, wheel_damp_position[1]), rest_length=wheel_damp_length, stiffness=wheel_damp_stiffness, damping=wheel_damp_damping) wheel_objects.append(wheel_damp) wheel_stop = pymunk.Poly(self.car_body, [(0, 0), (0, 1), (wheel_radius * 2 * self.x_modification, 1), (wheel_radius * 2 * self.x_modification, 0)], transform=pymunk.Transform(tx=wheel_damp_position[0] * self.x_modification - wheel_radius * self.x_modification, ty=wheel_damp_position[1])) wheel_objects.append(wheel_stop) wheel_stop.color = 0, 255, 0 wheel_motor = None if (wheel_side == 'rear' and self.drive in [self.AWD, self.FR]) or (wheel_side == 'front' and self.drive in [self.AWD, self.FF]): wheel_motor = pymunk.SimpleMotor(wheel_body, self.car_body, 0) # wheel_objects.append(motor) return wheel_body, wheel_motor, wheel_objects
def on_mouse_press(self, x, y, button, modifiers): self.mouse_body.position = x, y hit = self.env.point_query_nearest((x, y), 10, pymunk.ShapeFilter()) if hit != None: body = hit.shape.body if body.body_type == pymunk.Body.DYNAMIC: rest_length = self.mouse_body.position.get_distance(\ body.position) stiffness = 500 damping = 10 self.spring_body = pymunk.DampedSpring(self.mouse_body, body, \ (0,0), (0,0), rest_length, stiffness, damping) self.env.add(self.spring_body) elif body.body_type == pymunk.Body.STATIC: # e.g. landmarks self.selected_static_body = body self.env.remove(body) self.env.remove(body.shapes)
def make_damped_spring(self, x, y): shape_selected = self.get_shape(x, y) if shape_selected is None: return if self.shape_1 is None: print("Shape 1 Selected") self.shape_1 = shape_selected elif self.shape_2 is None: print("Shape 2 Selected") self.shape_2 = shape_selected joint = pymunk.DampedSpring(self.shape_1.shape.body, self.shape_2.shape.body, (0, 0), (0, 0), 45, 300, 30) self.space.add(joint) self.joints.append(joint) self.shape_1 = None self.shape_2 = None print("Joint Made")
def __init__(self, neuron_1, neuron_2): joints_count = 3 self.connected_neurons = (neuron_1, neuron_2) self._is_connected = False self.connection_progress = 0.0 self.connect_speed = 4 self.neurons = (neuron_1, neuron_2) self.joints = [ pymunk.DampedSpring( neuron_1.body, neuron_2.body, (n * 50 / joints_count, n * 50 / joints_count), (n * 50 / joints_count, n * 50 / joints_count), rest_length=0, stiffness=5, damping=5) for n in range(joints_count) ]
def add_spring(space): spring_anchor_body = pymunk.Body(body_type=pymunk.Body.STATIC) spring_anchor_body.position = (590, 108) spring_ground = pymunk.Segment(spring_anchor_body, (-40, 0), (40, 0), 3) body = pymunk.Body(10, 1000000000000000000000000000000000000) body.position = (580, 158) spring_top = pymunk.Poly.create_box(body, (40, 30)) spring_top.color = spring_color rest_length = 100 stiffness = 3000 damping = 150 dampened_spring = pymunk.DampedSpring(body, spring_anchor_body, (0, 0), (0, 0), rest_length, stiffness, damping) space.add(spring_top, body, spring_anchor_body, spring_ground, dampened_spring) return dampened_spring
def create_spring(self, b1, b2): """ Метод для создания пружины. (0, 0) и (0, 0) означают, что концы пружин будут находиться там же где и body указанных Ду. Добавляем созданную пружину в пространство симуляции. Аргументы: ---------- b1 : DooFixed Первый фиксированный Ду. b2 : DooFixed Второй фиксированный Ду. lenght : float или int Длина пружины в расслабленном состоянии (без воздействия внешних сил). """ d = self.world.distance_between_bodies(b1, b2) ds = pm.DampedSpring(b1, b2, (0, 0), (0, 0), d, self.spring_strength, self.damping) self.space.add(ds)
def draw(self, delta): ''' Draws stuff on the screen ''' if self.spring: if self.spring in self.space.constraints: self.space.remove(self.spring) self.spring = None if self.thing: self.spring = pymunk.DampedSpring(self.thing.body, self.floor.body, \ self.thing_clickpos_rel, \ self.floor.body.world_to_local(self.thing_movepos), \ 0.0, 3000.0, 0.1) self.space.add(self.spring) self.screen.fill(THECOLORS['white']) # Background self.screen.blit(self.img_background, \ pygame.Rect(0, 0, self.screen_width, self.screen_height)) # Screw self.screen.blit(self.img_screw, \ pygame.Rect(- 600 + self.cart.body.position[0] \ , 409, 1200, 60)) # Base self.screen.blit(self.img_base, \ pygame.Rect(0, 0, self.screen_width, self.screen_height)) # Cart self.screen.blit(self.img_cart, \ pygame.Rect(- 50 + self.cart.body.position[0] \ , 387, 78, 70)) # Pole self.draw_pole((self.cart.body.position[0], 400), \ self.pole.body.angle) #pymunk.pygame_util.draw_space(self.screen, \ # self.space) # Spring if self.thing: pygame.draw.line(self.screen, THECOLORS['black'], \ self._invy(self.thing.body.local_to_world(self.thing_clickpos_rel)), \ self._invy(self.thing_movepos)) pygame.display.flip() self.clock.tick(1.0 / delta)
def add_rels(self): param = np.zeros((self.n_ball * (self.n_ball - 1) // 2, 2)) self.param_dim = param.shape[0] cnt = 0 for i in range(self.n_ball): for j in range(i): # rel_type = rand_int(0, self.n_rel_type) rel_type = cnt % self.n_rel_type param[cnt, 0] = rel_type cnt += 1 pos_i = self.balls[i].position pos_j = self.balls[j].position if rel_type == 0: # no relation pass elif rel_type == 1: # spring c = pymunk.DampedSpring(self.balls[i], self.balls[j], (0, 0), (0, 0), rest_length=60, stiffness=20, damping=0.) self.space.add(c) elif rel_type == 2: # rod c = pymunk.PinJoint(self.balls[i], self.balls[j], (0, 0), (0, 0)) self.space.add(c) else: raise AssertionError("Unknown relation type") self.param = param
for i in range(len(bs) - 1): add_joint(bs[i], bs[i + 1]) i2 = i + 20 if len(bs) > i2: add_joint(bs[i], bs[i2]) ### WEB ATTACH POINTS static_bs = [] for b in bs[-17::4]: static_body = pymunk.Body(body_type=pymunk.Body.STATIC) static_body.position = b.position static_bs.append(static_body) # j = pymunk.PivotJoint(static_body, b, static_body.position) j = pymunk.DampedSpring(static_body, b, (0, 0), (0, 0), 0, 0, 0) j.damping = 100 j.stiffness = 20000 space.add(j) ### ALL SETUP DONE def update(dt): # Note that we dont use dt as input into step. That is because the # simulation will behave much better if the step size doesnt change # between frames. r = 10 for x in range(r): space.step(1.0 / 30.0 / r)
def main(): pygame.init() screen = pygame.display.set_mode(display_size, display_flags) width, height = screen.get_size() def to_pygame(p): """Small hack to convert pymunk to pygame coordinates""" return int(p.x), int(-p.y + height) def from_pygame(p): return to_pygame(p) clock = pygame.time.Clock() running = True font = pygame.font.Font(None, 16) ### Physics stuff space = pm.Space() space.gravity = (0.0, -1900.0) space.damping = 0.999 # to prevent it from blowing up. mouse_body = pm.Body(body_type=pm.Body.KINEMATIC) bodies = [] for x in range(-100, 150, 50): x += width / 2 offset_y = height / 2 mass = 10 radius = 25 moment = pm.moment_for_circle(mass, 0, radius, (0, 0)) body = pm.Body(mass, moment) body.position = (x, -125 + offset_y) body.start_position = Vec2d(body.position) shape = pm.Circle(body, radius) shape.elasticity = 0.9999999 space.add(body, shape) bodies.append(body) pj = pm.PinJoint(space.static_body, body, (x, 125 + offset_y), (0, 0)) space.add(pj) reset_bodies(space) selected = None if not is_interactive: pygame.time.set_timer(USEREVENT + 1, 70000) # apply force pygame.time.set_timer(USEREVENT + 2, 120000) # reset pygame.event.post(pygame.event.Event(USEREVENT + 1)) pygame.mouse.set_visible(False) while running: for event in pygame.event.get(): if event.type == QUIT: running = False elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(screen, "newtons_cradle.png") if event.type == pygame.USEREVENT + 1: r = random.randint(1, 4) for body in bodies[0:r]: body.apply_impulse_at_local_point((-6000, 0)) if event.type == pygame.USEREVENT + 2: reset_bodies(space) elif event.type == KEYDOWN and event.key == K_r and is_interactive: reset_bodies(space) elif event.type == KEYDOWN and event.key == K_f and is_interactive: r = random.randint(1, 4) for body in bodies[0:r]: body.apply_impulse_at_local_point((-6000, 0)) elif event.type == MOUSEBUTTONDOWN and is_interactive: if selected != None: space.remove(selected) p = from_pygame(Vec2d(event.pos)) hit = space.point_query_nearest(p, 0, pm.ShapeFilter()) if hit != None: shape = hit.shape rest_length = mouse_body.position.get_distance( shape.body.position) ds = pm.DampedSpring(mouse_body, shape.body, (0, 0), (0, 0), rest_length, 1000, 10) space.add(ds) selected = ds elif event.type == MOUSEBUTTONUP and is_interactive: if selected != None: space.remove(selected) selected = None elif event.type == KEYDOWN: running = False elif event.type == MOUSEBUTTONDOWN: running = False mpos = pygame.mouse.get_pos() p = from_pygame(Vec2d(mpos)) mouse_body.position = p ### Clear screen screen.fill(THECOLORS["black"]) ### Draw stuff for c in space.constraints: pv1 = c.a.position + c.anchor_a pv2 = c.b.position + c.anchor_b p1 = to_pygame(pv1) p2 = to_pygame(pv2) pygame.draw.aalines(screen, THECOLORS["lightgray"], False, [p1, p2]) for ball in space.shapes: p = to_pygame(ball.body.position) drawcircle(screen, ball.color, p, int(ball.radius), 0) #pygame.draw.circle(screen, ball.color, p, int(ball.radius), 0) ### Update physics fps = 50 iterations = 25 dt = 1.0 / float(fps) / float(iterations) for x in range( iterations): # 10 iterations to get a more stable simulation space.step(dt) ### Flip screen if is_interactive: screen.blit( font.render("fps: " + str(clock.get_fps()), 1, THECOLORS["white"]), (0, 0)) screen.blit( font.render("Press left mouse button and drag to interact", 1, THECOLORS["darkgrey"]), (5, height - 35)) screen.blit( font.render("Press R to reset, any other key to quit", 1, THECOLORS["darkgrey"]), (5, height - 20)) pygame.display.flip() clock.tick(fps)