0
\$\begingroup\$

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:

enter image description here

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)
\$\endgroup\$
5
  • 1
    \$\begingroup\$ 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? \$\endgroup\$
    – Vaillancourt
    Commented Sep 7, 2022 at 20:01
  • \$\begingroup\$ @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. \$\endgroup\$
    – Gilfoyle
    Commented Sep 8, 2022 at 14:35
  • 1
    \$\begingroup\$ Did you try to add two different fixtures to the same body, with each their own density? \$\endgroup\$
    – Vaillancourt
    Commented Sep 8, 2022 at 14:44
  • \$\begingroup\$ @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. \$\endgroup\$
    – Gilfoyle
    Commented Sep 8, 2022 at 16:07
  • \$\begingroup\$ 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. \$\endgroup\$
    – Vaillancourt
    Commented Sep 8, 2022 at 17:14

1 Answer 1

1
\$\begingroup\$

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)
\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .