def convexPoly( self, vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5): """ Add a complex polygon with vertices in absolute positions (meters or pixels, according to INPUT_PIXELS or INPUT_METERS). This function does the reduction and convec hulling of the poly, and calls add_poly(...) Parameters: vertices .. absolute vertices positions other ..... see [physics parameters] Return: box2d.b2Body """ # NOTE: Box2D has a maximum poly vertex count, defined in Common/box2d.b2Settings.h (box2d.b2_maxPolygonVertices) # We need to make sure, that we reach that by reducing the poly with increased tolerance # Reduce Polygon tolerance = 10 # 5 v_new = vertices while len(v_new) > box2d.b2_maxPolygonVertices: tolerance += 1 v_new = tools_poly.reduce_poly(vertices, tolerance) print "convexPoly: Polygon reduced from %i to %i vertices | tolerance: %i" % (len(vertices), len(v_new), tolerance) vertices = v_new # So poly should be alright now # Continue reducing the vertecs vertices_orig_reduced = vertices vertices = tools_poly.poly_center_vertices(vertices) vertices = tools_poly.convex_hull(vertices) if len(vertices) < 3: return # Define the body x, y = tools_poly.calc_center(vertices_orig_reduced) return self.poly((x, y), vertices, dynamic, density, restitution, friction)
def convexPoly(self, vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5): """ Add a complex polygon with vertices in absolute positions (meters or pixels, according to INPUT_PIXELS or INPUT_METERS). This function does the reduction and convec hulling of the poly, and calls add_poly(...) Parameters: vertices .. absolute vertices positions other ..... see [physics parameters] Return: box2d.b2Body """ # NOTE: Box2D has a maximum poly vertex count, defined in Common/box2d.b2Settings.h (box2d.b2_maxPolygonVertices) # We need to make sure, that we reach that by reducing the poly with increased tolerance # Reduce Polygon tolerance = 10 # 5 v_new = vertices while len(v_new) > box2d.b2_maxPolygonVertices: tolerance += 1 v_new = tools_poly.reduce_poly(vertices, tolerance) print "convexPoly: Polygon reduced from %i to %i vertices | tolerance: %i" % ( len(vertices), len(v_new), tolerance) vertices = v_new # So poly should be alright now # Continue reducing the vertecs vertices_orig_reduced = vertices vertices = tools_poly.poly_center_vertices(vertices) vertices = tools_poly.convex_hull(vertices) if len(vertices) < 3: return # Define the body x, y = tools_poly.calc_center(vertices_orig_reduced) return self.poly((x, y), vertices, dynamic, density, restitution, friction)
def concavePoly( self, vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5, screenCoord=True): # 1. Step: Reduce # Detect if the polygon is closed or open if vertices[0] != vertices[-1]: is_closed = False else: is_closed = True # Continue reducing the vertecs x, y = c = tools_poly.calc_center(vertices) vertices = tools_poly.poly_center_vertices(vertices) # Bring coordinates into the world coordinate system (flip, camera # offset, ...) if screenCoord: x, y = self.parent.to_world(c) else: x, y = c # If required, translate pixel -> meters if self.parent.input == INPUT_PIXELS: # translate pixel -> meters x /= self.parent.ppm y /= self.parent.ppm # Let's add the body bodyDef = box2d.b2BodyDef() bodyDef.position = (x, y) userData = {'color': self.parent.get_color()} bodyDef.userData = userData # Create the Body if not dynamic: density = 0 else: bodyDef.type = box2d.b2_dynamicBody body = self.parent.world.CreateBody(bodyDef) self.parent.element_count += 1 # Create the reusable Box2D polygon and circle definitions polyDef = box2d.b2PolygonShape() polyDef.vertexCount = 4 # rectangle polyDef.density = density polyDef.restitution = restitution polyDef.friction = friction circleShape = box2d.b2CircleShape() circleShape.radius = radius circleDef = box2d.b2FixtureDef() circleDef.shape = circleShape circleDef.density = density circleDef.restitution = restitution circleDef.friction = friction # Set the scale factor factor = 8.0 v2 = box2d.b2Vec2(*vertices[0]) for v in vertices[1:]: v1 = v2.copy() v2 = box2d.b2Vec2(*v) vdir = v2 - v1 # (v2x-v1x, v2y-v1y) vdir.Normalize() # we need a little size for the end part vn = box2d.b2Vec2(-vdir.y * factor, vdir.x * factor) v = [v1 + vn, v1 - vn, v2 - vn, v2 + vn] # Create a line (rect) for each part of the polygon, # and attach it to the body polyDef.setVertices([vi / self.parent.ppm for vi in v]) try: polyDef.checkValues() except ValueError: print "concavePoly: Created an invalid polygon!" return None body.CreateFixture(polyDef) # Now add a circle to the points between the rects # to avoid sharp edges and gaps if not is_closed and v2.tuple() == vertices[-1]: # Don't add a circle at the end break circleDef.localPosition = v2 / self.parent.ppm body.CreateFixture(circleDef) # Return hard and soft reduced vertices return body
def concavePoly(self, vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5, screenCoord=True): # 1. Step: Reduce # Detect if the polygon is closed or open if vertices[0] != vertices[-1]: is_closed = False else: is_closed = True # Continue reducing the vertecs x, y = c = tools_poly.calc_center(vertices) vertices = tools_poly.poly_center_vertices(vertices) # Bring coordinates into the world coordinate system (flip, camera # offset, ...) if screenCoord: x, y = self.parent.to_world(c) else: x, y = c # If required, translate pixel -> meters if self.parent.input == INPUT_PIXELS: # translate pixel -> meters x /= self.parent.ppm y /= self.parent.ppm # Let's add the body bodyDef = box2d.b2BodyDef() bodyDef.position = (x, y) userData = {'color': self.parent.get_color()} bodyDef.userData = userData # Create the Body if not dynamic: density = 0 else: bodyDef.type = box2d.b2_dynamicBody body = self.parent.world.CreateBody(bodyDef) self.parent.element_count += 1 # Create the reusable Box2D polygon and circle definitions polyDef = box2d.b2PolygonShape() polyDef.vertexCount = 4 # rectangle polyDef.density = density polyDef.restitution = restitution polyDef.friction = friction circleShape = box2d.b2CircleShape() circleShape.radius = radius circleDef = box2d.b2FixtureDef() circleDef.shape = circleShape circleDef.density = density circleDef.restitution = restitution circleDef.friction = friction # Set the scale factor factor = 8.0 v2 = box2d.b2Vec2(*vertices[0]) for v in vertices[1:]: v1 = v2.copy() v2 = box2d.b2Vec2(*v) vdir = v2 - v1 # (v2x-v1x, v2y-v1y) vdir.Normalize() # we need a little size for the end part vn = box2d.b2Vec2(-vdir.y * factor, vdir.x * factor) v = [v1 + vn, v1 - vn, v2 - vn, v2 + vn] # Create a line (rect) for each part of the polygon, # and attach it to the body polyDef.setVertices([vi / self.parent.ppm for vi in v]) try: polyDef.checkValues() except ValueError: print "concavePoly: Created an invalid polygon!" return None body.CreateFixture(polyDef) # Now add a circle to the points between the rects # to avoid sharp edges and gaps if not is_closed and v2.tuple() == vertices[-1]: # Don't add a circle at the end break circleDef.localPosition = v2 / self.parent.ppm body.CreateFixture(circleDef) # Return hard and soft reduced vertices return body