Пример #1
0
 def _make_star(
     self,
     star_npoints: int,
     star_out_rad: float,
     star_in_rad: float,
 ) -> Tuple[List[pm.shapes.Poly], List[List[pm.Vec2d]]]:
     # Body.
     star_verts = gtools.compute_star_verts(star_npoints, star_out_rad,
                                            star_in_rad)
     # Create an exact convex decomposition.
     convex_parts = autogeom.convex_decomposition(
         star_verts + star_verts[:1], 0)
     star_hull = autogeom.to_convex_hull(star_verts, 1e-5)
     star_inertia = pm.moment_for_poly(self.mass, star_hull, (0, 0), 0)
     self.shape_body = body = pm.Body(self.mass, star_inertia)
     body.position = self.init_pos
     body.angle = self.init_angle
     self.add_to_space(body)
     # Shape.
     shapes = []
     star_group = self.generate_group_id()
     for convex_part in convex_parts:
         shape = pm.Poly(body, convex_part)
         # Avoid self-intersection with a shape filter.
         shape.filter = pm.ShapeFilter(group=star_group)
         shapes.append(shape)
         del shape
     return shapes, convex_parts
Пример #2
0
 def _setup_body(self):
     star_verts = gtools.compute_star_verts(self.star_npoints,
                                            self.star_out_rad,
                                            self.star_in_rad)
     self.cvx_parts = autogeom.convex_decomposition(
         star_verts + star_verts[:1], 0)
     star_hull = autogeom.to_convex_hull(star_verts, 1e-5)
     inertia = pm.moment_for_poly(self.mass, star_hull, (0, 0), 0)
     self.body = pm.Body(self.mass, inertia)
Пример #3
0
    def create_shapes(self, model, transform=None):
        if not transform:
            transform = model.transform
        #print('transform', transform)
        sprite = model.sprite
        body = model.body
        position = model.position
        shapes = []
        sprite.position = position
        center = Vec2d(position)
        points = sprite.get_hit_box()
        #print(model.__class__)
        #print(points)
        points = to_convex_hull(points, SLOP)
        #print(points)
        shape = pymunk.Poly(body, points, transform)

        shape.friction = 10
        shape.elasticity = 0.2
        shape.collision_type = model.physics.type
        shapes.append(shape)
        return shapes
    def create_collision_shape(cls, img, body, threshold=240):
        poly_points = []
        px_arr = pygame.PixelArray(img)

        min_y = img.get_height()
        min_x = img.get_width()

        for x in range(px_arr.shape[1]):
            for y in range(px_arr.shape[0]):
                px = 0xFF & px_arr[y][x]
                if px < threshold and px != 0:
                    if x < min_x:
                        min_x = x
                    if y < min_y:
                        min_y = y

                    poly_points.append((y, x))

        hull = autogeometry.to_convex_hull(poly_points, 0.1)

        return pymunk.shapes.Poly(body, hull,
                                  transform=pymunk.Transform(d=-1)), (min_y,
                                                                      min_x)
Пример #5
0
 def test_to_convex_hull(self) -> None:
     p1: List[Tuple[float, float]] = [(0, 0), (0, 10), (5, 5), (10, 10),
                                      (10, 0)]
     expected = [(0, 0), (10, 0), (10, 10), (0, 10), (0, 0)]
     actual = a.to_convex_hull(p1, 1)
     self.assertEqual(actual, expected)
Пример #6
0
 def test_to_convex_hull(self):
     p1 = [(0,0), (0,10), (5,5), (10, 10), (10,0)]
     expected = [(0,0), (10,0), (10,10), (0, 10), (0, 0)]
     actual = a.to_convex_hull(p1, 1)
     self.assertEqual(actual, expected) 
 def test_to_convex_hull(self):
     p1 = [(0, 0), (0, 10), (5, 5), (10, 10), (10, 0)]
     expected = [(0, 0), (10, 0), (10, 10), (0, 10), (0, 0)]
     actual = a.to_convex_hull(p1, 1)
     self.assertEqual(actual, expected)
Пример #8
0
    def setup(self, *args, **kwargs):
        super().setup(*args, **kwargs)

        # Physics. This joint setup was taken form tank.py in the pymunk
        # examples.

        if self.shape_type == ShapeType.SQUARE:
            self.shape_body = body = pm.Body()
            body.position = self.init_pos
            body.angle = self.init_angle
            self.add_to_space(body)

            side_len = math.sqrt(math.pi) * self.shape_size
            shape = pm.Poly.create_box(
                body,
                (side_len, side_len),
                # slightly bevelled corners
                0.01 * side_len)
            # FIXME: why is this necessary? Do I need it for the others?
            shape.mass = self.mass
            shapes = [shape]
            del shape
        elif self.shape_type == ShapeType.CIRCLE:
            inertia = pm.moment_for_circle(self.mass, 0, self.shape_size,
                                           (0, 0))
            self.shape_body = body = pm.Body(self.mass, inertia)
            body.position = self.init_pos
            body.angle = self.init_angle
            self.add_to_space(body)
            shape = pm.Circle(body, self.shape_size, (0, 0))
            shapes = [shape]
            del shape
        elif self.shape_type == ShapeType.STAR:
            star_npoints = 5
            star_out_rad = 1.3 * self.shape_size
            star_in_rad = 0.5 * star_out_rad
            star_verts = gtools.compute_star_verts(star_npoints, star_out_rad,
                                                   star_in_rad)
            # create an exact convex decpomosition
            convex_parts = autogeom.convex_decomposition(
                star_verts + star_verts[:1], 0)
            star_hull = autogeom.to_convex_hull(star_verts, 1e-5)
            star_inertia = pm.moment_for_poly(self.mass, star_hull, (0, 0), 0)
            self.shape_body = body = pm.Body(self.mass, star_inertia)
            body.position = self.init_pos
            body.angle = self.init_angle
            self.add_to_space(body)
            shapes = []
            star_group = self.generate_group_id()
            for convex_part in convex_parts:
                shape = pm.Poly(body, convex_part)
                # avoid self-intersection with a shape filter
                shape.filter = pm.ShapeFilter(group=star_group)
                shapes.append(shape)
                del shape
        else:
            # these are free-form shapes b/c no helpers exist in Pymunk
            if self.shape_type == ShapeType.TRIANGLE:
                # shrink to make it look more sensible and easier to grasp
                factor = 0.8
                num_sides = 3
            elif self.shape_type == ShapeType.PENTAGON:
                factor = 1.0
                num_sides = 5
            elif self.shape_type == ShapeType.HEXAGON:
                factor = 1.0
                num_sides = 6
            elif self.shape_type == ShapeType.OCTAGON:
                factor = 1.0
                num_sides = 8
            else:
                raise NotImplementedError("haven't implemented",
                                          self.shape_type)
            side_len = factor * gtools.regular_poly_circ_rad_to_side_length(
                num_sides, self.shape_size)
            poly_verts = gtools.compute_regular_poly_verts(num_sides, side_len)
            inertia = pm.moment_for_poly(self.mass, poly_verts, (0, 0), 0)
            self.shape_body = body = pm.Body(self.mass, inertia)
            body.position = self.init_pos
            body.angle = self.init_angle
            self.add_to_space(body)
            shape = pm.Poly(body, poly_verts)
            shapes = [shape]
            del shape

        for shape in shapes:
            shape.friction = 0.5
            self.add_to_space(shape)

        trans_joint = pm.PivotJoint(self.space.static_body, body, (0, 0),
                                    (0, 0))
        trans_joint.max_bias = 0
        trans_joint.max_force = self.phys_vars.shape_trans_joint_max_force
        self.add_to_space(trans_joint)
        rot_joint = pm.GearJoint(self.space.static_body, body, 0.0, 1.0)
        rot_joint.max_bias = 0
        rot_joint.max_force = self.phys_vars.shape_rot_joint_max_force
        self.add_to_space(rot_joint)

        # Drawing
        if self.shape_type == ShapeType.SQUARE:
            geoms_inner = [r.make_square(side_len - 2 * SHAPE_LINE_THICKNESS)]
            geoms_outer = [r.make_square(side_len)]
        elif self.shape_type == ShapeType.CIRCLE:
            geoms_inner = [
                r.make_circle(radius=self.shape_size - SHAPE_LINE_THICKNESS,
                              res=100),
            ]
            geoms_outer = [r.make_circle(radius=self.shape_size, res=100)]
        elif self.shape_type == ShapeType.STAR:
            star_short_verts = gtools.compute_star_verts(
                star_npoints, star_out_rad - SHAPE_LINE_THICKNESS,
                star_in_rad - SHAPE_LINE_THICKNESS)
            short_convex_parts = autogeom.convex_decomposition(
                star_short_verts + star_short_verts[:1], 0)
            geoms_inner = []
            for part in short_convex_parts:
                geoms_inner.append(r.make_polygon(part))
            geoms_outer = []
            for part in convex_parts:
                geoms_outer.append(r.make_polygon(part))
        elif self.shape_type == ShapeType.OCTAGON \
                or self.shape_type == ShapeType.HEXAGON \
                or self.shape_type == ShapeType.PENTAGON \
                or self.shape_type == ShapeType.TRIANGLE:
            apothem = gtools.regular_poly_side_length_to_apothem(
                num_sides, side_len)
            short_side_len = gtools.regular_poly_apothem_to_side_legnth(
                num_sides, apothem - SHAPE_LINE_THICKNESS)
            short_verts = gtools.compute_regular_poly_verts(
                num_sides, short_side_len)
            geoms_inner = [r.make_polygon(short_verts)]
            geoms_outer = [r.make_polygon(poly_verts)]
        else:
            raise NotImplementedError("haven't implemented", self.shape_type)

        for g in geoms_inner:
            g.set_color(*self.colour)
        for g in geoms_outer:
            g.set_color(*darken_rgb(self.colour))
        self.shape_xform = r.Transform()
        shape_compound = r.Compound(geoms_outer + geoms_inner)
        shape_compound.add_attr(self.shape_xform)
        self.viewer.add_geom(shape_compound)