def add_slide_joint( self, pos: Union[tuple[float, float], Vector], shape: pymunk.Shape, limit: Union[float, tuple[float, float]]) -> pymunk.SlideJoint: """ new static slide joint Parameters ---------- pos : Union[tuple[float, float], Vector] position of the slide joint shape : pymunk.Shape the shape to attach to\\ can be Circle, Segment and Poly limit : Union[float, tuple[float, float]] max distance limit, optional lower limit """ pos = pos[0], pos[1] rotation_limit_body = pymunk.Body(body_type=pymunk.Body.STATIC) rotation_limit_body.position = pos body = shape.body up = limit if isinstance(limit, (float, int)) else max(limit) low = 0 if isinstance(limit, (float, int)) else min(limit) rotation_limit_joint = pymunk.SlideJoint(body, rotation_limit_body, pos, (0, 0), low, up) self._space.add(rotation_limit_joint) return rotation_limit_joint
def add_L(space): #Create the rotation center body to act as a static point in the joint #so that the line can rotate around it. NO SHAPE/Collision hull added to it rotation_center_body = pymunk.Body(body_type=pymunk.Body.STATIC) rotation_center_body.position = (250, 250) #Create a static body to limit the motion rotation_limit_body = pymunk.Body(body_type=pymunk.Body.STATIC) rotation_limit_body.position = (100, 250) #The L shape to be added to the screen is not static anymore #mass 10 and random moment wrt the rotation center body = pymunk.Body(10, 10000) body.position = (250, 250) #Create the lines l1 = pymunk.Segment(body, (-150, 0), (100, 0), 5) l2 = pymunk.Segment(body, (-150, 0), (-150, 50), 5) #Joint functions take in #1st body, 2nd body, 1st body joint location, 2nd_body joint location #Create a pinjoint between body and rotation_center_body rotation_center_joint = pymunk.PinJoint(body, rotation_center_body, (0, 0), (0, 0)) #Create a slidejoint between body and rotation_center_body #joint_limit defines the min and max the body will slide wrt to each other joint_limit = 50 rotation_limit_joint = pymunk.SlideJoint(body, rotation_limit_body, (-150, 0), (0, 0), 0, joint_limit) space.add(l1, l2, body, rotation_center_joint, rotation_limit_joint) return l1, l2
def add_L(space): """Add a inverted L shape with two joints""" rotation_center_body = pymunk.Body(body_type=pymunk.Body.STATIC) rotation_center_body.position = (300, 300) rotation_limit_body = pymunk.Body(body_type=pymunk.Body.STATIC) rotation_limit_body.position = (200, 300) body = pymunk.Body(10, 10000) body.position = (300, 300) l1 = pymunk.Segment(body, (-150, 0), (255.0, 0.0), 5.0) l2 = pymunk.Segment(body, (-150.0, 0), (-150.0, -50.0), 5.0) l1.friction = 1 l2.friction = 1 l1.mass = 1 l2.mass = 1 rotation_center_joint = pymunk.PinJoint(body, rotation_center_body, (0, 0), (0, 0)) joint_limit = 25 rotation_limit_joint = pymunk.SlideJoint(body, rotation_limit_body, (-100, 0), (0, 0), 0, joint_limit) space.add(l1, l2, body, rotation_center_joint) #, rotation_limit_joint) return l1, l2
def __init__(self, a, b, c1=None, c2=None, segments=10, density=0.01, colour=(0, 0, 0, 1), thickness=4): """Tether between points a and b. if c1 and c2 are given, these are bodies that will be jointed to each end of the tether. """ self.density = density self.colour = colour self.thickness = thickness self.shapes = [] self.bodies = [] self.joints = [] a = v(a) b = v(b) segment_length = (b - a).length / segments for i in xrange(segments + 1): frac = float(i) / segments pos = frac * b + (1 - frac) * a body = self.create_node(pos) if self.bodies: last = self.bodies[-1] self.joints.append(pymunk.SlideJoint(last, body, (0, 0), (0, 0), 0, segment_length)) self.bodies.append(body) if c1: self.joints.append( pymunk.PivotJoint(c1, self.bodies[0], self.bodies[0].position), ) if c2: self.joints.append( pymunk.PivotJoint(c2, self.bodies[-1], self.bodies[-1].position), ) for j in self.joints: j.error_bias = 0.9 ** 30.0 self.vertices = pyglet.graphics.vertex_list(len(self.bodies), 'v2f')
def __init__(self, pos, max_angle=math.pi / 6, on_left=False, length=24.0, friction=1.0, color=hinge_color, weighted=False): if weighted: init_angle = -max_angle if on_left else max_angle else: init_angle = 0 super().__init__(pos, length, friction, color, init_angle=init_angle) self.on_left = on_left self.length = length # Joint Body offset = 1.0 joint_body = pymunk.Body(body_type=pymunk.Body.STATIC) joint_body.position = [self.pos[0] - offset, self.pos[1]] # Joint joint_limit = 2 * offset * math.sin(max_angle / 2) self.joint = pymunk.SlideJoint( self.body, joint_body, (-offset * math.cos(init_angle), -offset * math.sin(init_angle)), (0, 0), 0, joint_limit)
def __init__(self, space: pymunk.Space, x, y, tethered_object: pymunk.Body, screen=None, tether_offset=(0, 0), distance_cutoff=1000): super().__init__( values.torque, values.max_rpm, values.tether_length, values.shaft_diameter / 2 + values.inner_radius_padding, values.tether_diameter, values.packing_factor) self.space = space self.pos = (x, y) self.object = tethered_object self.distance_cutoff = distance_cutoff self.create_body(self.space, *self.pos, screen=screen, tether_offset=tether_offset) self.update_distance(self.object) self.engaged = self.curr_used_length > self.distance_cutoff self.constraint = pymunk.SlideJoint(self.spool, self.object, (0, 0), (0, 0), 0, self.tether_length)
def __init__(self, cml_bond, atomA, atomB, space, batch): self.joints = list() self.vertex = None self.cml_bond = cml_bond self.batch = batch self.space = space self.atomA = atomA self.atomB = atomB bond_length = self.get_bond_lenght(cml_bond) slide_joint = pymunk.SlideJoint(atomA.body, atomB.body, (0, 0), (0, 0), 10, bond_length) slide_joint.max_force = 15000000 self.joints.append(slide_joint) self.space.add(slide_joint) if self.cml_bond.bonds > 0: self.vertex = self.create_vertex() groove_joint_a = self.create_groove_joint(atomA, atomB) groove_joint_b = self.create_groove_joint(atomB, atomA) self.joints.append(groove_joint_a) self.joints.append(groove_joint_b) self.space.add(groove_joint_a) self.space.add(groove_joint_b)
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 testAnchor(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.SlideJoint(a, b, (1, 2), (3, 4), 0, 10) 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 grab(self): if framework.grabbables: for item in filter(self.in_reach, framework.grabbables): if len(self.grab_joints) < 3: self.grab_joints.append( pymunk.SlideJoint(self.body, item.body, (0, 0), (0, 0), min=5, max=14)) framework.space.add(self.grab_joints[-1])
def __init__(self, b, b2, a=(0, 0), a2=(0, 0), min=50, max=100, collide=True): joint = pymunk.SlideJoint(b, b2, a, a2, min, max) joint.collide_bodies = collide space.add(joint)
def tether(self, object1, object2, position1, position2, length): body1 = self._find_body(object1) body2 = self._find_body(object2) joint = pymunk.SlideJoint(body1, body2, position1.array(), position2.array(), 0, length) self.space.add(joint) tether = _Tether(object1, object2, joint) self._tethers[object1.key] = tether self._tethers[object2.key] = tether
def CollisionAbsorber(arbiter, space, data): absorber = arbiter.shapes[0] absorbable = arbiter.shapes[1] joint = pymunk.SlideJoint(absorber.body, absorbable.body, (0, 0), (0, 0), 0, 40) space.add(joint) # absorbable.body.velocity = pymunk.Vec2d() absorbable.sensor = True return True
def testPickle(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.SlideJoint(a, b, (1, 2), (3, 4), 5, 6) 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.min, j2.min) self.assertEqual(j.max, j2.max) self.assertEqual(j.a.mass, j2.a.mass) self.assertEqual(j.b.mass, j2.b.mass)
def __init__(self, pos): center = pymunk.Body(0, 0, pymunk.Body.STATIC) center.position = pos limit = pymunk.Body(0, 0, pymunk.Body.STATIC) limit.position = pos[0] - 100, pos[1] body = pymunk.Body(100, 100000) body.position = pos seg1 = pymunk.Segment(body, (-100, 0), (100, 0), 10) seg2 = pymunk.Segment(body, (-100, 0), (-100, 50), 10) joint = pymunk.PinJoint(body, center, (0, 0), (0, 0)) joint2 = pymunk.SlideJoint(body, limit, (-100, 0), (0, 0), 0, 30) App.current.space.add(seg1, seg2, body, joint, joint2)
def add_l(space): rotation_center_body = pymunk.Body(body_type=pymunk.Body.STATIC) rotation_center_body.position = (300, 300) rotation_limit_body = pymunk.Body(body_type=pymunk.Body.STATIC) rotation_limit_body.position = (200, 300) body = pymunk.Body(10, 10000) body.position = (300, 300) i1 = pymunk.Segment(body, (-150, 0), (255.0, 0.0), 5.0) i2 = pymunk.Segment(body, (-150.0, 0), (-150.0, 50.0), 5.0) rotation_center_joint = pymunk.PinJoint(body, rotation_center_body, (0, 0), (0, 0)) joint_limit = 25 rotation_limit_joint = pymunk.SlideJoint(body, rotation_limit_body, (-100, 0), (0, 0), 0, joint_limit) space.add(i1, i2, body, rotation_center_joint, rotation_limit_joint)
def add_L(space): rotation_center_body = pymunk.Body() rotation_center_body.position = (300, 300) rotation_limit_body = pymunk.Body() rotation_limit_body.position = (200, 300) body = pymunk.Body(10, 10000) body.position = (300, 300) l1 = pymunk.Segment(body, (-150, 0), (255.0, 0.0), 5.0) l2 = pymunk.Segment(body, (-150.0, 0), (-150.0, 50.0), 5.0) rotation_center_joint = pymunk.PinJoint(body, rotation_center_body, (0, 0), (0, 0)) joint_limit = 25 rotation_limit_joint = pymunk.SlideJoint(body, rotation_limit_body, (-100, 0), (0, 0), 0, joint_limit) space.add(l1, l2, body, rotation_center_joint, rotation_limit_joint) return l1, l2
def add_L_pulley(self, space): rotation_center_body = pm.Body(body_type=pm.Body.STATIC) rotation_center_body.position = (300, 300) rotation_limit_body = pm.Body(body_type=pm.Body.STATIC) rotation_limit_body.position = (200, 300) body1 = pm.Body(10, 10000) body1.position = (300, 300) l1 = pm.Segment(body1, (-100, 125), (100.0, 125.0), 1) l2 = pm.Segment(body1, (100.0, 125), (100.0, 150.0), 1) rotation_center_joint = pm.PinJoint(body1, rotation_center_body, (0, 25), (0, 25)) joint_limit = 200 rotation_limit_joint = pm.SlideJoint(body1, rotation_limit_body, (-150, 125), (0, 125), 0, joint_limit) self.space.add(l1, l2, body1, rotation_center_joint, rotation_limit_joint) return l1, l2
def add_L(space): rotation_center_body = pymunk.Body() rotation_center_body.position = (300, 300) rotation_limit_body = pymunk.Body() rotation_limit_body.position = (200, 300) body = pymunk.Body(5, 1000) body.position = (300, 300) l1 = add_line(space, body, start=(-150, 0), end=(255, 0), radius=5) l2 = add_line(space, body, start=(-150, 0), end=(-150, 50), radius=5) # l3 = add_line(space, body, start=(0, 100), end=(0, 400), radius=8) # l4 = add_line_from_body(space, body, 150, 5) rotation_center_joint = pymunk.PinJoint(body, rotation_center_body, (0, 0), (0, 0)) joint_limit = 25 rotation_limit_joint = pymunk.SlideJoint(body, rotation_limit_body, (-100, 0), (0, 0), 0, joint_limit) # space.add(l1, l2, body, rotation_center_joint, rotation_limit_joint) space.add(body, rotation_center_joint) return l1, l2
def add_L(self, space): """Add a inverted L shape with two joints""" rotation_center_body = pm.Body(body_type=pm.Body.STATIC) rotation_center_body.position = (300, 300) rotation_limit_body = pm.Body(body_type=pm.Body.STATIC) rotation_limit_body.position = (300, 300) body = pm.Body(650, 650) body.position = (300, 600) l1 = pm.Segment(rotation_limit_body, (25, -20), (25, 200.0), 1.0) l2 = pm.Segment(rotation_limit_body, (-25, -20), (-25, 200.0), 1.0) l3 = pm.Segment(rotation_limit_body, (25, -20), (85.0, -90.0), 1.3) l4 = pm.Segment(rotation_limit_body, (-25, -20), (-85.0, -90.0), 1.3) l8 = pm.Segment(body, (-250, -200), (200.0, -200.0), 5.0) rotation_center_joint = pm.PinJoint(body, rotation_center_body, (0, -200), (0, -200)) joint_limit = .03 rotation_limit_joint = pm.SlideJoint(body, rotation_limit_body, (-20, -200), (0, -200), 0, joint_limit) space.add(l1, l2, l3, l4, l8, rotation_limit_body, rotation_center_body, body, rotation_center_joint, rotation_limit_joint) return l8
def add_actor(self, position=(0, 0)): self.actor_c_b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) self.actor_c_b.position = position self.space.add(self.actor_c_b) self.actor_b = self.add_box(20, 1, 'ACT') self.actor_b.position = position for s in self.actor_b.shapes: s.color = (0, 100, 100, 255) pivot = pymunk.PivotJoint(self.actor_c_b, self.actor_b, (0, 0), (0, 0)) self.space.add(pivot) pivot.max_bias = 0 pivot.max_force = 10000 gear = pymunk.GearJoint(self.actor_c_b, self.actor_b, 0.0, 0.1) self.space.add(gear) gear.error_bias = 0 gear.max_bias = 1.2 gear.max_force = 50000 pin = pymunk.SlideJoint(self.actor_c_b, self.actor_b, (0,0), (0,0), 0.5, 1) self.space.add(pin)
def __init__(self, x, y, width, height, image, data): self.mass = 10 self.moment = 100000 self.fence = 20 self.width = width self.height = height self.limit = 25 self.distance = 100 self.centerBody = pymunk.Body() self.centerBody.position = (x, y) self.limitBody = pymunk.Body() self.limitBody.position = (x - self.distance, y) self.mainBody = pymunk.Body(self.mass, self.moment) self.mainBody.position = (x, y) self.seesaw = pymunk.Segment(self.mainBody, (-self.width // 2, 0), (self.width // 2, 0), self.height) self.centerBody = pymunk.PinJoint(self.mainBody, self.centerBody, (0, 0), (0, 0)) self.limitBody = pymunk.SlideJoint(self.mainBody, self.limitBody, (-self.distance, 0), (0, 0), 0, self.limit) data.space.add(self.seesaw, self.mainBody, self.centerBody, self.limitBody) self.image = image
return body txts = {} box_offset = 0, 0 b1 = add_ball(space, (50, 60), box_offset) b2 = add_ball(space, (150, 60), box_offset) c = pymunk.PinJoint(b1, b2, (20, 0), (-20, 0)) txts[box_offset] = inspect.getdoc(c) space.add(c) box_offset = box_size, 0 b1 = add_ball(space, (50, 60), box_offset) b2 = add_ball(space, (150, 60), box_offset) c = pymunk.SlideJoint(b1, b2, (20, 0), (-20, 0), 40, 80) txts[box_offset] = inspect.getdoc(c) space.add(c) box_offset = box_size * 2, 0 b1 = add_ball(space, (50, 60), box_offset) b2 = add_ball(space, (150, 60), box_offset) c = pymunk.PivotJoint(b1, b2, Vec2d(box_offset) + (100, 60)) txts[box_offset] = inspect.getdoc(c) space.add(c) box_offset = box_size * 3, 0 b1 = add_ball(space, (50, 60), box_offset) b2 = add_ball(space, (150, 60), box_offset) c = pymunk.GrooveJoint(b1, b2, (50, 50), (50, -50), (-50, 0)) txts[box_offset] = inspect.getdoc(c)
def fill_space(space, custom_color=(255, 255, 0, 255)): captions = [] ### Static captions.append(((50, 680), "Static Shapes")) #Static Segments segments = [ pymunk.Segment(space.static_body, (10, 400), (10, 600), 0), pymunk.Segment(space.static_body, (20, 400), (20, 600), 1), pymunk.Segment(space.static_body, (30, 400), (30, 600), 3), pymunk.Segment(space.static_body, (50, 400), (50, 600), 5) ] space.add(segments) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (40, 630) b.angle = 3.14 / 7 s = pymunk.Segment(b, (-30, 0), (30, 0), 2) space.add(s) # Static Circles b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (120, 630) s = pymunk.Circle(b, 10) space.add(s) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (120, 630) s = pymunk.Circle(b, 10, (-30, 0)) space.add(s) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (120, 560) b.angle = 3.14 / 4 s = pymunk.Circle(b, 40) space.add(s) # Static Polys b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (120, 460) b.angle = 3.14 / 4 s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)]) space.add(s) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (120, 500) t = pymunk.Transform(ty=-100) s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)], t, radius=3) space.add(s) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (50, 430) t = pymunk.Transform(ty=-100) s = pymunk.Poly(b, [(0, -50), (50, 0), (30, 50), (-30, 50), (-50, 0)], t) space.add(s) ### Kinematic captions.append(((220, 680), "Kinematic Shapes")) # Kinematic Segments b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) segments = [ pymunk.Segment(b, (180, 400), (180, 600), 0), pymunk.Segment(b, (190, 400), (190, 600), 1), pymunk.Segment(b, (200, 400), (200, 600), 3), pymunk.Segment(b, (220, 400), (220, 600), 5) ] space.add(segments) b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (210, 630) b.angle = 3.14 / 7 s = pymunk.Segment(b, (-30, 0), (30, 0), 2) space.add(s) # Kinematic Circles b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (290, 630) s = pymunk.Circle(b, 10) space.add(s) b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (290, 630) s = pymunk.Circle(b, 10, (-30, 0)) space.add(s) b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (290, 560) b.angle = 3.14 / 4 s = pymunk.Circle(b, 40) space.add(s) # Kinematic Polys b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (290, 460) b.angle = 3.14 / 4 s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)]) space.add(s) b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (290, 500) t = pymunk.Transform(ty=-100) s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)], t, radius=3) space.add(s) b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (230, 430) t = pymunk.Transform(ty=-100) s = pymunk.Poly(b, [(0, -50), (50, 0), (30, 50), (-30, 50), (-50, 0)], t) space.add(s) ### Dynamic captions.append(((390, 680), "Dynamic Shapes")) #Dynamic Segments b = pymunk.Body(1, 1) segments = [ pymunk.Segment(b, (350, 400), (350, 600), 0), pymunk.Segment(b, (360, 400), (360, 600), 1), pymunk.Segment(b, (370, 400), (370, 600), 3), pymunk.Segment(b, (390, 400), (390, 600), 5), ] space.add(segments) b = pymunk.Body(1, 1) b.position = (380, 630) b.angle = 3.14 / 7 s = pymunk.Segment(b, (-30, 0), (30, 0), 2) space.add(s) # Dynamic Circles b = pymunk.Body(1, 1) b.position = (460, 630) s = pymunk.Circle(b, 10) space.add(s) b = pymunk.Body(1, 1) b.position = (460, 630) s = pymunk.Circle(b, 10, (-30, 0)) space.add(s) b = pymunk.Body(1, 1) b.position = (460, 560) b.angle = 3.14 / 4 s = pymunk.Circle(b, 40) space.add(s) # Dynamic Polys b = pymunk.Body(1, 1) b.position = (460, 460) b.angle = 3.14 / 4 s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)]) space.add(s) b = pymunk.Body(1, 1) b.position = (460, 500) s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)], pymunk.Transform(ty=-100), radius=3) space.add(s) b = pymunk.Body(1, 1) b.position = (400, 430) s = pymunk.Poly(b, [(0, -50), (50, 0), (30, 50), (-30, 50), (-50, 0)], pymunk.Transform(ty=-100)) space.add(s) ###Constraints # PinJoints captions.append(((560, 660), "Pin Joints")) a = pymunk.Body(1, 1) a.position = (550, 600) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (650, 620) sb = pymunk.Circle(b, 20) j = pymunk.PinJoint(a, b) space.add(sa, sb, a, b, j) a = pymunk.Body(1, 1) a.position = (550, 550) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (650, 570) sb = pymunk.Circle(b, 20) j = pymunk.PinJoint(a, b, anchor_a=(0, 20), anchor_b=(0, -20)) space.add(sa, sb, a, b, j) # SlideJoints captions.append(((560, 490), "Slide Joint")) a = pymunk.Body(1, 1) a.position = (550, 430) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (650, 450) sb = pymunk.Circle(b, 20) j = pymunk.SlideJoint(a, b, anchor_a=(0, 20), anchor_b=(0, -20), min=10, max=30) space.add(sa, sb, a, b, j) # PivotJoints captions.append(((560, 390), "Pivot Joint")) a = pymunk.Body(1, 1) a.position = (550, 330) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (650, 350) sb = pymunk.Circle(b, 20) j = pymunk.PivotJoint(a, b, (600, 320)) space.add(sa, sb, a, b, j) # GrooveJoints captions.append(((760, 660), "Groove Joint")) a = pymunk.Body(1, 1) a.position = (750, 600) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (850, 620) sb = pymunk.Circle(b, 20) j = pymunk.GrooveJoint(a, b, (790, 610), (790, 620), (840, 620)) space.add(sa, sb, a, b, j) # DampedSpring captions.append(((760, 550), "Damped Spring")) a = pymunk.Body(1, 1) a.position = (750, 480) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (850, 500) sb = pymunk.Circle(b, 20) j = pymunk.DampedSpring(a, b, (0, 0), (0, 10), 100, 1, 1) space.add(sa, sb, a, b, j) # DampedRotarySpring captions.append(((740, 430), "Damped Rotary Spring")) a = pymunk.Body(1, 1) a.position = (750, 350) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (850, 380) sb = pymunk.Circle(b, 20) j = pymunk.DampedRotarySpring(a, b, 10, 1, 1) space.add(sa, sb, a, b, j) # RotaryLimitJoint captions.append(((740, 300), "Rotary Limit Joint")) a = pymunk.Body(1, 1) a.position = (750, 220) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (850, 250) sb = pymunk.Circle(b, 20) j = pymunk.RotaryLimitJoint(a, b, 1, 2) b.angle = 3 space.add(sa, sb, a, b, j) # RatchetJoint captions.append(((740, 170), "Ratchet Joint")) a = pymunk.Body(1, 1) a.position = (750, 100) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (850, 120) sb = pymunk.Circle(b, 20) j = pymunk.RatchetJoint(a, b, 1, 0.1) b.angle = 3 space.add(sa, sb, a, b, j) # GearJoint and SimpleMotor omitted since they are similar to the already # added joints # TODO: more stuff here :) ### Other # Objects in custom color captions.append(((150, 150), "Custom Color (static & dynamic)")) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (200, 200) s = pymunk.Circle(b, 40) s.color = custom_color space.add(s) b = pymunk.Body(1, 1) b.position = (300, 200) s = pymunk.Circle(b, 40) s.color = custom_color space.add(s) # Collision captions.append(((450, 150), "Collisions")) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (470, 200) s = pymunk.Circle(b, 40) space.add(s) b = pymunk.Body(1, 1) b.position = (500, 250) s = pymunk.Circle(b, 40) space.add(s) # Sleeping captions.append(((50, 150), "Sleeping")) b = pymunk.Body(1, 1) b.position = (75, 200) space.sleep_time_threshold = 0.01 s = pymunk.Circle(b, 40) space.add(s, b) b.sleep() space.step(0.000001) return captions
def testSlideJoint(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.SlideJoint(a, b, (1, 0), (10, 0), 7, 12) self.assertEqual(j.max, 12) self.assertEqual(j.anchr1, (1, 0))
def main(): pygame.init() screen = pygame.display.set_mode((600, 600)) pygame.display.set_caption("Joints. Just wait and the L will tip over") clock = pygame.time.Clock() running = True ### Physics stuff space = pm.Space() space.gravity = 0.0, -900.0 ## Balls balls = [] ### static stuff rot_center_body = pm.Body() rot_center_body.position = (300, 300) ### To hold back the L rot_limit_body = pm.Body() rot_limit_body.position = (200, 300) ### The moving L shape l1 = [(-150, 0), (255.0, 0.0)] l2 = [(-150.0, 0), (-150.0, 50.0)] body = pm.Body(10, 10000) body.position = (300, 300) lines = [ pm.Segment(body, l1[0], l1[1], 5.0), pm.Segment(body, l2[0], l2[1], 5.0) ] space.add(body) space.add(lines) ### The L rotates around this rot_center = pm.PinJoint(body, rot_center_body, (0, 0), (0, 0)) ### And is constrained by this joint_limit = 25 rot_limit = pm.SlideJoint(body, rot_limit_body, (-100, 0), (0, 0), 0, joint_limit) space.add(rot_center, rot_limit) ticks_to_next_ball = 10 while running: for event in pygame.event.get(): if event.type == QUIT: running = False elif event.type == KEYDOWN and event.key == K_ESCAPE: running = False elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(screen, "slide_and_pinjoint.png") ticks_to_next_ball -= 1 if ticks_to_next_ball <= 0: ticks_to_next_ball = 25 mass = 1 radius = 14 inertia = pm.moment_for_circle(mass, 0, radius, (0, 0)) body = pm.Body(mass, inertia) x = random.randint(120, 380) body.position = x, 550 shape = pm.Circle(body, radius, (0, 0)) space.add(body, shape) balls.append(shape) ### Clear screen screen.fill(THECOLORS["white"]) ### Draw stuff balls_to_remove = [] for ball in balls: if ball.body.position.y < 150: balls_to_remove.append(ball) p = to_pygame(ball.body.position) pygame.draw.circle(screen, THECOLORS["blue"], p, int(ball.radius), 2) for ball in balls_to_remove: space.remove(ball, ball.body) balls.remove(ball) for line in lines: body = line.body pv1 = body.position + line.a.rotated(body.angle) pv2 = body.position + line.b.rotated(body.angle) p1 = to_pygame(pv1) p2 = to_pygame(pv2) pygame.draw.lines(screen, THECOLORS["lightgray"], False, [p1, p2], 4) ### The rotation center of the L shape pygame.draw.circle(screen, THECOLORS["red"], to_pygame(rot_center_body.position), 5) ### The limits where it can move. pygame.draw.circle(screen, THECOLORS["green"], to_pygame(rot_limit_body.position), joint_limit, 2) ### Update physics dt = 1.0 / 50.0 / 10.0 for x in range(10): space.step(dt) ### Flip screen pygame.display.flip() clock.tick(50)
def main(): if viz: pygame.init() screen = pygame.display.set_mode((1000, 1000)) pygame.display.set_caption("double_ball") clock = pygame.time.Clock() print(clock) draw_options = pymunk.pygame_util.DrawOptions(screen) space = pymunk.Space() space.gravity = (0.0, 0.0) item_details = [] items = [] def add_ball(pos, vel): shape = create_ball(space, 1, 10, pos, vel, 0) item_details.append(['obj', len(items), None]) items.append(shape) return shape # ticks_to_next_ball = 10 if simtype == 'none': pos = [(random.randint(300, 700), random.randint(300, 700)) for i in range(2)] vel = [(random.randint(-200, 200), random.randint(-200, 200)) for i in range(2)] shapes = [add_ball(pos[i], vel[i]) for i in range(2)] elif simtype == 'pin': pos = [(random.randint(300, 700), random.randint(300, 700)) for i in range(2)] vel = [(random.randint(-400, 400), random.randint(-400, 400)) for i in range(2)] shapes = [add_ball(pos[i], vel[i]) for i in range(2)] pin_joint = pymunk.PinJoint(shapes[0].body, shapes[1].body, (0, 0), (0, 0)) item_details.append([ 'con', len(items), ['pin', items.index(shapes[0]), items.index(shapes[1])] ]) items.append(pin_joint) space.add(pin_joint) elif simtype == 'slide': pos = [(random.randint(300, 700), random.randint(300, 700)) for i in range(2)] vel = [(random.randint(-400, 400), random.randint(-400, 400)) for i in range(2)] shapes = [add_ball(pos[i], vel[i]) for i in range(2)] cur_dist = ((pos[1][0] - pos[0][0])**2 + (pos[1][1] - pos[0][1])**2)**(1 / 2) mn = random.random() * cur_dist mx = (1 + random.random()) * cur_dist slide_joint = pymunk.SlideJoint(shapes[0].body, shapes[1].body, (0, 0), (0, 0), mn, mx) item_details.append([ 'con', len(items), ['slide', items.index(shapes[0]), items.index(shapes[1]), mn, mx] ]) items.append(slide_joint) space.add(slide_joint) elif simtype == 'spring-undamped': pos = [(random.randint(300, 700), random.randint(300, 700)) for i in range(2)] vel = [(random.randint(-200, 200), random.randint(-200, 200)) for i in range(2)] shapes = [add_ball(pos[i], vel[i]) for i in range(2)] rest_length = random.randint(0, 200) stiffness = random.randint(4, 80) spring_joint = pymunk.DampedSpring(shapes[0].body, shapes[1].body, (0, 0), (0, 0), rest_length, stiffness, 0) item_details.append([ 'con', len(items), [ 'spring', items.index(shapes[0]), items.index(shapes[1]), rest_length, stiffness, 0 ] ]) items.append(spring_joint) space.add(spring_joint) elif simtype == 'spring-damped': pos = [(random.randint(300, 700), random.randint(300, 700)) for i in range(2)] vel = [(random.randint(-200, 200), random.randint(-200, 200)) for i in range(2)] shapes = [add_ball(pos[i], vel[i]) for i in range(2)] rest_length = random.randint(0, 200) stiffness = random.randint(10, 120) damping = 0.1 / random.random() spring_joint = pymunk.DampedSpring(shapes[0].body, shapes[1].body, (0, 0), (0, 0), rest_length, stiffness, damping) item_details.append([ 'con', len(items), [ 'spring', items.index(shapes[0]), items.index(shapes[1]), rest_length, stiffness, damping ] ]) items.append(spring_joint) space.add(spring_joint) else: sys.exit("ERROR: non-valid simulation type") locations = [] timestep = 0 while True: if not viz and timestep >= 200: break timestep += 1 if viz: screen.fill((255, 255, 255)) 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) if viz: space.debug_draw(draw_options) pygame.display.flip() clock.tick(50) else: step_obj = [] for item in item_details: if item[0] == 'obj': pos = tuple(items[item[1]].body.position) vel = tuple(items[item[1]].body.velocity) step_obj.append([item[1], pos, vel]) locations.append(step_obj) if not viz: with open(os.path.join(data_folder, simtype + '_' + str(now) + '.pkl'), 'wb') as f: constraints = [] for item in item_details: if item[0] == 'con': constraints.append([item[1]] + item[2]) save_data = {'obj': locations, 'con': constraints} pickle.dump(save_data, f)
def testMax(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.SlideJoint(a, b, (0, 0), (0, 0), 0, 1) self.assertEqual(j.max, 1) j.max = 2 self.assertEqual(j.max, 2)
def testMin(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.SlideJoint(a, b, (0, 0), (0, 0), 1, 0) self.assertEqual(j.min, 1) j.min = 2 self.assertEqual(j.min, 2)
def main(): driver_type = 5 full_screen = False stencil_buffer = False vsync = False run_app = True from video_choice_dialog import has_pywingui if has_pywingui: from video_choice_dialog import ChoiceDialog, IDOK, IDCANCEL dialog = ChoiceDialog() dialog.driver_type = driver_type dialog.full_screen = full_screen dialog.stencil_buffer = stencil_buffer dialog.vsync = vsync dialogResult = dialog.DoModal() if dialogResult == IDOK: driver_type = dialog.driver_type full_screen = dialog.full_screen stencil_buffer = dialog.stencil_buffer vsync = dialog.vsync elif dialogResult == IDCANCEL: run_app = False if run_app: import pymunk as pm import os, math, random X, Y, Z = 0, 1, 2 # Easy indexing info_text = '\nJoints. Just wait and the L will tip over' ### Physics stuff space = pm.Space() space.gravity = 0.0, -900.0 ## Balls balls = [] ### static stuff rot_center_body = pm.Body() rot_center_body.position = (300, 300) ### To hold back the L rot_limit_body = pm.Body() rot_limit_body.position = (200, 300) ### The moving L shape l1 = [(-150, 0), (255.0, 0.0)] l2 = [(-150.0, 0), (-150.0, 50.0)] body = pm.Body(10, 10000) body.position = (300, 300) lines = [ pm.Segment(body, l1[0], l1[1], 5.0), pm.Segment(body, l2[0], l2[1], 5.0) ] space.add(body) space.add(lines) ### The L rotates around this rot_center = pm.PinJoint(body, rot_center_body, (0, 0), (0, 0)) ### And is constrained by this joint_limit = 25 rot_limit = pm.SlideJoint(body, rot_limit_body, (-100, 0), (0, 0), 0, joint_limit) space.add(rot_center, rot_limit) ticks_to_next_ball = 10 screen_x, screen_y = 640, 480 def reverse_coords(p): """Small hack to convert pymunk to pygame coordinates""" return p.x, -p.y + screen_y ### pyIrrlicht block import pyirrlicht as irr if not driver_type: driver_type = irr.EDT_SOFTWARE class UserIEventReceiver(irr.IEventReceiver): KeyIsDown = {} for key in range(irr.KEY_KEY_CODES_COUNT): KeyIsDown[key] = False def OnEvent(self, evt): event = irr.SEvent(evt) if event.EventType is irr.EET_KEY_INPUT_EVENT: self.KeyIsDown[ event.KeyInput.Key] = event.KeyInput.PressedDown return False def IsKeyDown(self, keyCode): return self.KeyIsDown[keyCode] window_size = irr.dimension2du(screen_x, screen_y) device = irr.createDevice(driver_type, window_size, 16, full_screen, stencil_buffer, vsync) if device: window_caption = __doc__ device.setWindowCaption(window_caption) device.setResizable(True) video_driver = device.getVideoDriver() scene_manager = device.getSceneManager() gui_environment = device.getGUIEnvironment() font = irr.CGUITTFont( gui_environment, os.environ['SYSTEMROOT'] + '/Fonts/arial.ttf', 16) if not font: font = gui_environment.getBuiltInFont() gui_environment.getSkin().setFont(font) static_text = gui_environment.addStaticText( window_caption + info_text, irr.recti(10, 10, screen_x - 20, 50), True) color_red = irr.SColor(255, 255, 0, 0) color_green = irr.SColor(255, 0, 255, 0) color_blue = irr.SColor(255, 0, 0, 255) color_black = irr.SColor(255, 0, 0, 0) color_lightgray = irr.SColor(255, 200, 200, 200) color_text = irr.SColor(255, 0, 0, 0) color_screen = irr.SColor(255, 100, 100, 100) lastFPS = -1 i_event_receiver = UserIEventReceiver() device.setEventReceiver(i_event_receiver) update_physics = False while device.run(): if device.isWindowActive(): if i_event_receiver.IsKeyDown(irr.KEY_ESCAPE): break if device.getTimer().getTime() > 30: ticks_to_next_ball -= 1 if ticks_to_next_ball <= 0: ticks_to_next_ball = 25 mass = 1 radius = 14 inertia = pm.moment_for_circle( mass, 0, radius, (0, 0)) body = pm.Body(mass, inertia) x = random.randint(120, 380) body.position = x, 550 shape = pm.Circle(body, radius, (0, 0)) space.add(body, shape) balls.append(shape) device.getTimer().setTime(0) update_physics = True ### Draw stuff if video_driver.beginScene(True, True, color_screen): balls_to_remove = [] for ball in balls: if ball.body.position.y < 150: balls_to_remove.append(ball) x1, y1 = reverse_coords(ball.body.position) video_driver.draw2DPolygon_f( x1, y1, ball.radius, color_blue) for ball in balls_to_remove: space.remove(ball, ball.body) balls.remove(ball) for line in lines: body = line.body pv1 = body.position + line.a.rotated(body.angle) pv2 = body.position + line.b.rotated(body.angle) x1, y1 = reverse_coords(pv1) x2, y2 = reverse_coords(pv2) video_driver.draw2DLine_f(x1, y1, x2, y2, color_lightgray) ### The rotation center of the L shape x, y = reverse_coords(rot_center_body.position) video_driver.draw2DPolygon_f(x, y, 5, color_red) ### The limits where it can move. x, y = reverse_coords(rot_limit_body.position) video_driver.draw2DPolygon_f(x, y, joint_limit, color_green, 100) gui_environment.drawAll() video_driver.endScene() ### Update physics if update_physics: dt = 1.0 / 50.0 / 10.0 for x in range(10): space.step(dt) update_physics = False device.sleep(1) fps = video_driver.getFPS() if lastFPS != fps: caption = '%s [%s] FPS:%d' % ( window_caption, video_driver.getName(), fps) device.setWindowCaption(caption) static_text.setText(caption + info_text) lastFPS = fps else: device._yield() device.closeDevice() else: print('ERROR createDevice')