Exemple #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
Exemple #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)
Exemple #3
0
    def test_convex_decomposition(self):
        # TODO: Use a more complicated polygon as test case
        p1 = [(0,0), (5,0), (10,10), (20,20), (5,5), (0,10), (0,0)]
        expected = [
            [(5.0,5.0), (6.25, 2.5), (20.0,20.0), (5.0,5.0)],
            [(0.0,0.0), (5.0,0.0), (6.25, 2.5), (5.0,5.0),(0.0,10.0), (0.0,0.0)], 
            ]

        actual = a.convex_decomposition(p1, .1)
        actual.sort(key=len)
    def test_convex_decomposition(self):
        # TODO: Use a more complicated polygon as test case
        p1 = [(0, 0), (5, 0), (10, 10), (20, 20), (5, 5), (0, 10), (0, 0)]
        expected = [
            [(5.0, 5.0), (6.25, 2.5), (20.0, 20.0), (5.0, 5.0)],
            [(0.0, 0.0), (5.0, 0.0), (6.25, 2.5), (5.0, 5.0), (0.0, 10.0),
             (0.0, 0.0)],
        ]

        actual = a.convex_decomposition(p1, .1)
        actual.sort(key=len)
Exemple #5
0
    def test_convex_decomposition(self) -> None:
        # TODO: Use a more complicated polygon as test case
        p1: List[Tuple[float, float]] = [
            (0, 0),
            (5, 0),
            (10, 10),
            (20, 20),
            (5, 5),
            (0, 10),
            (0, 0),
        ]
        expected = [
            [(5.0, 5.0), (6.25, 2.5), (20.0, 20.0), (5.0, 5.0)],
            [(0.0, 0.0), (5.0, 0.0), (6.25, 2.5), (5.0, 5.0), (0.0, 10.0),
             (0.0, 0.0)],
        ]

        actual = a.convex_decomposition(p1, 0.1)
        actual.sort(key=len)
Exemple #6
0
 def _setup_graphic(self):
     star_short_verts = gtools.compute_star_verts(
         self.star_npoints,
         self.star_out_rad - SHAPE_LINE_THICKNESS,
         self.star_in_rad - SHAPE_LINE_THICKNESS,
     )
     short_convex_parts = autogeom.convex_decomposition(
         star_short_verts + star_short_verts[:1], 0)
     geoms = []
     for part in short_convex_parts:
         geoms.append(r.Poly(part, outline=False))
     geoms_outer = []
     for part in self.cvx_parts:
         geoms_outer.append(r.Poly(part, outline=False))
     dark_robot_color = darken_rgb(self.robot_color)
     for g in geoms_outer:
         g.color = dark_robot_color
     for g in geoms:
         g.color = self.robot_color
     self.graphic_bodies.extend([*geoms_outer, *geoms])
Exemple #7
0
    def create_shapes(self, model, transform=None):
        if not transform:
            transform = model.transform

        sprite = model.sprite
        body = model.body
        position = model.position

        shapes = []
        sprite.position = position
        center = Vec2d(position)
        points = sprite.get_hit_box()
        #print(points)
        polys = convex_decomposition(points, SLOP)
        #print(polys)
        for poly in polys:
            shape = pymunk.Poly(body, poly, transform)
            shape.friction = 10
            shape.elasticity = 0.2
            shape.collision_type = model.physics.type
            shapes.append(shape)
        return shapes
 def test_convex_decomposition(self):
     # TODO: Use a more complicated polygon as test case
     p1 = [(0,0), (0,10), (5,5), (20, 20), (10,10), (5,0)]
     expected = [[(0,0), (20,20), (0, 10), (0, 0)]]
     actual = a.convex_decomposition(p1, .1)
     self.assertEqual(actual, expected)
Exemple #9
0
 def test_convex_decomposition(self):
     # TODO: Use a more complicated polygon as test case
     p1 = [(0, 0), (0, 10), (5, 5), (20, 20), (10, 10), (5, 0)]
     expected = [[(0, 0), (20, 20), (0, 10), (0, 0)]]
     actual = a.convex_decomposition(p1, .1)
     self.assertEqual(actual, expected)
Exemple #10
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)
Exemple #11
0
    def setup(self, *args, **kwargs) -> None:
        super().setup(*args, **kwargs)

        # Physics. This joint setup was taken form tank.py in the pymunk
        # examples.
        if self.shape_type == ShapeType.SQUARE:
            side_len = math.sqrt(math.pi) * self.shape_size
            shapes = self._make_square(side_len)
        elif self.shape_type == ShapeType.CIRCLE:
            shapes = self._make_circle()
        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
            shapes, convex_parts = self._make_star(star_npoints, star_out_rad,
                                                   star_in_rad)
        else:
            # These are free-form shapes b/c no helpers exist in Pymunk.
            try:
                factor, num_sides = POLY_TO_FACTOR_SIDE_PARAMS[self.shape_type]
            except KeyError:
                raise NotImplementedError("haven't implemented",
                                          self.shape_type)
            side_len = factor * gtools.regular_poly_circ_rad_to_side_length(
                num_sides, self.shape_size)
            shapes, poly_verts = self._make_regular_polygon(
                num_sides, side_len)

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

        trans_joint = pm.PivotJoint(self.space.static_body, self.shape_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, self.shape_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)

        # Graphics.
        geoms_outer = []
        if self.shape_type == ShapeType.SQUARE:
            geoms = [r.make_square(side_len, outline=True)]
        elif self.shape_type == ShapeType.CIRCLE:
            geoms = [r.make_circle(self.shape_size, 100, True)]
        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 = []
            for part in short_convex_parts:
                geoms.append(r.Poly(part, outline=False))
            geoms_outer = []
            for part in convex_parts:
                geoms_outer.append(r.Poly(part, outline=False))
        elif (self.shape_type == ShapeType.OCTAGON
              or self.shape_type == ShapeType.HEXAGON
              or self.shape_type == ShapeType.PENTAGON
              or self.shape_type == ShapeType.TRIANGLE):
            geoms = [r.Poly(poly_verts, outline=True)]
        else:
            raise NotImplementedError("haven't implemented", self.shape_type)

        if self.shape_type == ShapeType.STAR:
            for g in geoms_outer:
                g.color = darken_rgb(self.color)
            for g in geoms:
                g.color = self.color
        else:
            for g in geoms:
                g.color = self.color
                g.outline_color = darken_rgb(self.color)

        self.shape_xform = r.Transform()
        shape_compound = r.Compound(geoms_outer + geoms)
        shape_compound.add_transform(self.shape_xform)
        self.viewer.add_geom(shape_compound)