# Perpendicular inelastic joint of two bodies in PyBox2d

I would like to create two objects of different density and (inelastically) weld them perpendicular together, so that the final object forms an L. Afterwards, I want to be able to assign a position and velocity to the newly welded object.

I tried to use CreateWeldJoint in the example below. However, I am not sure how to use it correctly and so far I didn't find any useful information. What I have so far looks as follows:

The image shows, that the joint of both bodies is not completely inelastic.

How can I use CreateWeldJoint or some other method, to weld two objects together at a 90 angle? How can I make the weld / joint completely inelastic?

from Box2D.examples.framework import Framework, main
from Box2D import b2EdgeShape, b2FixtureDef, b2PolygonShape

class TestObject(Framework):

def __init__(self):
super(TestObject, self).__init__()

# World
self.world.gravity = (0.0, 0.0)

self.world.CreateStaticBody(
shapes=[
b2EdgeShape(vertices=[(-10, 0), (10, 0)]),
b2EdgeShape(vertices=[(-10, 0), (-20, 20)]),
b2EdgeShape(vertices=[(10, 0), (20, 20)]),
]
)

obj_vertices = [(1.0, 1.0), (-1.0, 1.0), (-1.0, -1.0), (1.0, -1.0)]
velocity = (0.0, -10.0)

# First object
height = 4
width = 1

obj1 = self.world.CreateDynamicBody(position=(15, 20), linearVelocity=velocity)
obj1_vertices = [(width * item[0], height * item[1]) for item in obj_vertices]
obj1_shape = b2PolygonShape(vertices=obj1_vertices)
obj1_fixture_def = b2FixtureDef(shape=obj1_shape, density=1)
_ = obj1.CreateFixture(obj1_fixture_def)

# Second object
height = 2
width = 1

obj2 = self.world.CreateDynamicBody(position=(15, 16), linearVelocity=velocity)
obj2_vertices = [(width * item[0], height * item[1]) for item in obj_vertices]
obj2_shape = b2PolygonShape(vertices=obj2_vertices)
obj2_fixture_def = b2FixtureDef(shape=obj2_shape, density=10000)
_ = obj2.CreateFixture(obj2_fixture_def)

# Weld both objects
obj_welded = self.world.CreateWeldJoint(
bodyA=obj1,
bodyB=obj2,
localAnchorA=(0, -7),
# localAnchorB=(0, -4),
# referenceAngle=90,   # does not work
# frequencyHz=0.0,
# dampingRatio=0.0,
)
# obj_welded.CreateFixture(b2FixtureDef(position=(0, 40), linearVelocity=(0, 0)))   # does not work

def Step(self, settings):
super(TestObject, self).Step(settings)

if __name__ == "__main__":
main(TestObject)

• I'm not familiar with this physics engine in particular, but more with another one. Typically, a "tip" is to not use a joint when you could attach two geometries to the same body instead. So the question is: why do you want to use this kind of joint, could you get away by having two collision geometries to the same L body? Commented Sep 7, 2022 at 20:01
• @Vaillancourt I don't have to use a joint. I just thought that is the way to connect two objects of different density. If there is a more straight forward way to do that, I would be happy to see how I can do it. Commented Sep 8, 2022 at 14:35
• Did you try to add two different fixtures to the same body, with each their own density? Commented Sep 8, 2022 at 14:44
• @Vaillancourt Yes. I passed two different fixtures to CreateFixture and got an error. I'm probably just not familiar enough with box2d. Can you point me to an example how to do it? I checked all the examples in the Github repository but did not find anything helpful there. Commented Sep 8, 2022 at 16:07
• Yes. I passed two different fixtures to CreateFixture and got an error. You should also mention this in your question: what have you tried (what was the code) and what was the error. Commented Sep 8, 2022 at 17:14

It is actually pretty straight forward to connect two objects of different masses.

The following modified code shows how to create a single physics body to which two collider fixtures are attached:

from Box2D.examples.framework import Framework, main
from Box2D import b2EdgeShape, b2FixtureDef, b2PolygonShape

class TestObject(Framework):

def __init__(self):
super(TestObject, self).__init__()

# World
self.world.gravity = (0.0, 0.0)

self.world.CreateStaticBody(
shapes=[
b2EdgeShape(vertices=[(-10, 0), (10, 0)]),
b2EdgeShape(vertices=[(-10, 0), (-20, 20)]),
b2EdgeShape(vertices=[(10, 0), (20, 20)]),
]
)

obj_vertices = [(1.0, 1.0), (-1.0, 1.0), (-1.0, -1.0), (1.0, -1.0)]
velocity = (0.0, -10.0)

# First object
height = 4
width = 1

obj1 = self.world.CreateDynamicBody(position=(15, 20), linearVelocity=velocity)
obj1_vertices = [(width * item[0], height * item[1]) for item in obj_vertices]
obj1_shape = b2PolygonShape(vertices=obj1_vertices)
obj1_fixture_def = b2FixtureDef(shape=obj1_shape, density=1)
_ = obj1.CreateFixture(obj1_fixture_def)

# Second object
height = 2
width = 1

obj2_vertices = [(width * item[0], height * item[1]) for item in obj_vertices]
obj2_shape = b2PolygonShape(vertices=obj2_vertices)
obj2_fixture_def = b2FixtureDef(shape=obj2_shape, density=10000)
_ = obj1.CreateFixture(obj2_fixture_def)

def Step(self, settings):
super(TestObject, self).Step(settings)

if __name__ == "__main__":
main(TestObject)