

matter.jsのオブジェクトの結合でつまづいています。

下記コードでcarオブジェクトの上に四角形を３つ固定させたいのですが、うまく固定できずに困っています。どうすればうまくできますでしょうか？

[code]

    var Engine = Matter.Engine,
        Gui = Matter.Gui,
        World = Matter.World,
        Bodies = Matter.Bodies,
        Body = Matter.Body,
        Composite = Matter.Composite,
        Composites = Matter.Composites,
        Common = Matter.Common,
        Events = Matter.Events;
        MouseConstraint = Matter.MouseConstraint,
        Constraint = Matter.Constraint;
    
    
    var container = document.getElementById("canvas-container");
    
    var engine = Engine.create(container,{render: {
        options: {
          wireframes:false,
          showIds:true
        }
    }});
    
    
    var offset = 5;
    World.addBody(engine.world, Bodies.rectangle(400, -offset, 800.5 + 2 * offset, 50.5, { isStatic: true }));
    World.addBody(engine.world, Bodies.rectangle(400, 600 + offset, 800.5 + 2 * offset, 50.5, { isStatic: true }));
    World.addBody(engine.world, Bodies.rectangle(800 + offset, 300, 50.5, 600.5 + 2 * offset, { isStatic: true }));
    World.addBody(engine.world, Bodies.rectangle(-offset, 300, 50.5, 600.5 + 2 * offset, { isStatic: true }));
    
    var mouseConstraint = MouseConstraint.create(engine);
    World.add(engine.world, mouseConstraint);
    
    /*    var testComp = Composite.create();
    var car = Composites.car(200, 400, 100, 40 , 30);
    
    //ここのパラメータは要調整
    var testBody = Bodies.rectangle(200,400,10,10);
    
    //carメソッドの内部を参考に追加　ここのパラメータも要調整
    var axelTest = Constraint.create({
            bodyA: car.bodies[0],
            pointA: { x: 200, y:400 },
            bodyB: testBody,
            stiffness: 0
        });
    Composite.addBody(car,testBody);
    Composite.addConstraint(car, axelTest);
    
    //World.add(engine.world,Composite.add(car,testBody));
    
    World.add(engine.world, car);
    //World.add(engine.world, testBody); ここで追加はしません
    Engine.run(engine);
    
    
    World.add(engine.world,Composite.addBody(car,testBody));
    //World.add(engine.world, testBody);
    */
    var xx = 120;
    var yy = 170;
    var width = 200;
    var height = 40;
    var wheelSize = 20;
    var groupId = Body.nextGroupId(),
        wheelBase = 20,
        wheelAOffset = -width * 0.5 + wheelBase,
        wheelBOffset = width * 0.5 - wheelBase,
        wheelYOffset = 40;
    
    
    var car = Composite.create({ label: 'Car' }),
        body = Bodies.rectangle(xx, yy, width, height, { 
            groupId: groupId, 
            friction: 0.01,
        });
    
    var wheelA = Bodies.circle(xx + wheelAOffset, yy + wheelYOffset, wheelSize, { 
        groupId: groupId, 
        restitution: 0.5, 
        friction: 0.9,
        density: 0.01
    });
                
    var wheelB = Bodies.circle(xx + wheelBOffset, yy + wheelYOffset, wheelSize, { 
        groupId: groupId, 
        restitution: 0.5, 
        friction: 0.9,
        density: 0.01
    });
                
    var axelA = Constraint.create({
        bodyA: body,
        pointA: { x: wheelAOffset, y: wheelYOffset },
        bodyB: wheelA,
        stiffness: 0.5
    });
                    
    var axelB = Constraint.create({
        bodyA: body,
        pointA: { x: wheelBOffset, y: wheelYOffset },
        bodyB: wheelB,
        stiffness: 0.5
    });
    
    Composite.addBody(car, body);
    Composite.addBody(car, wheelA);
    Composite.addBody(car, wheelB);
    Composite.addConstraint(car, axelA);
    Composite.addConstraint(car, axelB);
    
    
    var box = Composite.create({ label: 'box' });
    
    var underBox = Bodies.rectangle(150,150,60,25);
    var leftBox = Bodies.rectangle(110,127.5,25,70);
    var rightBox = Bodies.rectangle(190,127.5,25,70);
    
    
    var leftLabel = Constraint.create({
        bodyA: underBox,
        pointA: { x: -20,y: 0 },
        bodyB: leftBox,
        stiffness: 0.5
    });
    var rightLabel = Constraint.create({
        bodyA: underBox,
        pointA: { x: 20,y: 0 },
        bodyB: rightBox,
        stiffness: 0.5
    });
    
    
    
    
    // World.add(engine.world,underBox);
    // World.add(engine.world,leftBox);
    // World.add(engine.world,rightBox);
    
    Composite.addBody(box,underBox);
    Composite.addBody(box,leftBox);
    Composite.addBody(box,rightBox);
    Composite.addConstraint(box,leftLabel);
    Composite.addConstraint(box,rightLabel);
    
    
    var carLabel = Constraint.create({
        bodyA: body,
        pointA: { x: 0,y: 10 },
        bodyB: underBox,
        stiffness: 0.5
    });
    var carLabel2 = Constraint.create({
        bodyA: body,
        pointA: { x: -20,y: -10 },
        bodyB: leftBox,
        stiffness: 0.5
    });
    var carLabel3 = Constraint.create({
        bodyA: body,
        pointA: { x: 20,y: -10 },
        bodyB: rightBox,
        stiffness: 0.5
    });
    
    Composite.addComposite(car,box);
    Composite.addConstraint(car,carLabel);
    
    
    World.add(engine.world,car);
    
    Engine.run(engine);
    
    
    $("#left").click(function(t){
        var carBodies = Composite.allBodies(car);
        carBodies[1].force.x = 2;  
    });
[/code]

[code]

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <script src="https://github.com/liabru/matter-js/releases/download/0.8.0-alpha/matter-0.8.0.js" type="text/javascript"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore.js"></script>
    
    <div id = "canvas-container"></div>
    <input id = "left" type = "button" value = "left">
[/code]


CC BY-SA 3.0
2015-01-12T14:09:58.443
4445
2015-02-15T19:36:03.920
2015-01-16T15:35:05.640
30
7327
question
javascript matter.js
matter.jsという物理エンジンライブラリのオブジェクトの結合について


以下のスニペットでどうでしょうか。四角形の位置が、元のコードの意図した場所からずれているかもしれませんが、固定はできていると思います。

## 変更点

### `Bodies.rectangle` の引数を調整

`Bodies.rectangle(中心点X座標, 中心点Y座標, 幅, 高さ)`
という引数であることに注意して、carオブジェクトの上に四角形がきれいに乗るように位置を調整しました。

### `Constraint.create` の引数を調整

各剛体を特定の位置関係で固定するのが [`Constraint`](http://brm.io/matter-js-
docs/classes/Constraint.html) (制約)です。2つの剛体を対象に、一番単純な書き方で制約をかけるなら、

[code]

    Constraint.create({
        bodyA: underBox,
        bodyB: rightBox
    });
    
[/code]

のようになります。これで、`underBox`の中心点から`rightBox`の中心点までのベクトルについて、常に初期状態の長さを保つこと、という制約をかけられます。この制約では、BはAの周囲を一定距離で動くことができます。

[code]

    _________               _____________
    |      A|               |          B|
    |       |               |           |
    |   ･---|---------------|---->･     |
    |       |             ↑ |           |
    |_______|             | |___________|
                          |
                  一定距離で固定
    
[/code]

これらの引数に加えて、`pointA`、`pointB`を指定することで、制約の端点を任意の場所に移動できます。

[code]

    Constraint.create({
        bodyA: underBox,
        pointA: {x: Ax, y: Ay},
        bodyB: rightBox,
        pointB: {x: Bx, y: By}
    });
    
            Aの中心点からの
     _______  オフセット↓     ____________
    |      A|  (Ax, Ay) -   |          B|
    |       |            `- |           |
    |       |             ↑`-(Bx, By)<--|-- Bの中心点からのオフセット
    |       |             | |           |
    |_______|             | |___________|
                          |
                  一定距離で固定
    
[/code]

これを利用して、たとえば`pointA`を`bodyB`の中心点に持ってくることで、BをAから見て特定の位置に固定することができます。

[code]

    Constraint.create({
        bodyA: underBox,
        pointA: {x: B.center.x, y: B.center.y},
        bodyB: rightBox,
        //pointBはデフォルトでbodyBの中心点
    });
    
     _______                ___________
    |      A|               |         B|
    |       |               |          |
    |       |               | <pointA> | 「pointAとBの中心点が常に距離ゼロであること」
    |       |               |          |  という制約になる。
    |_______|               |__________|  Bに残された自由度は、その場で回転することのみ。
    
[/code]

この仕組みで固定されているのが、carオブジェクトの車輪になります。

下記のスニペットの四角形も、以下の位置で距離ゼロの制約をかけてあります。脇の2つは回転を防ぐために2点での制約になっています。

![制約の位置](https://i.stack.imgur.com/ScXUp.png)

[code]

    var Engine = Matter.Engine,
        Gui = Matter.Gui,
        World = Matter.World,
        Bodies = Matter.Bodies,
        Body = Matter.Body,
        Composite = Matter.Composite,
        Composites = Matter.Composites,
        Common = Matter.Common,
        Events = Matter.Events;
        MouseConstraint = Matter.MouseConstraint,
        Constraint = Matter.Constraint;
    
    var container = document.getElementById("canvas-container");
    var engine = Engine.create(container,{
      render: {
        options: {
          wireframes:false,
          showIds:true
        }
    }});
    
    var offset = 5,
        width = 450,
        height = 260,
        margin = 20.5;
    World.addBody(engine.world, Bodies.rectangle(width * 0.5, -offset, width + 0.5 + 2 * offset, margin, { isStatic: true }));
    World.addBody(engine.world, Bodies.rectangle(width * 0.5, height + offset, width + 0.5 + 2 * offset, margin, { isStatic: true }));
    World.addBody(engine.world, Bodies.rectangle(width + offset, height * 0.5, margin, height + 0.5 + 2 * offset, { isStatic: true }));
    World.addBody(engine.world, Bodies.rectangle(-offset, height * 0.5, margin, height + 0.5 + 2 * offset, { isStatic: true }));
    
    var mouseConstraint = MouseConstraint.create(engine);
    World.add(engine.world, mouseConstraint);
    
    var xx = 120;
    var yy = 170;
    var width = 200;
    var height = 40;
    var wheelSize = 20;
    var groupId = Body.nextGroupId(),
        wheelBase = 20,
        wheelAOffset = -width * 0.5 + wheelBase,
        wheelBOffset = width * 0.5 - wheelBase,
        wheelYOffset = 40;
    
    var car = Composite.create({ label: 'Car' }),
        body = Bodies.rectangle(xx, yy, width, height, { 
            groupId: groupId, 
            friction: 0.01,
        });
    var wheelA = Bodies.circle(xx + wheelAOffset, yy + wheelYOffset, wheelSize, { 
        groupId: groupId, 
        restitution: 0.5, 
        friction: 0.9,
        density: 0.01
    });
    var wheelB = Bodies.circle(xx + wheelBOffset, yy + wheelYOffset, wheelSize, { 
        groupId: groupId, 
        restitution: 0.5, 
        friction: 0.9,
        density: 0.01
    });
    var axelA = Constraint.create({
        bodyA: body,
        pointA: { x: wheelAOffset, y: wheelYOffset },
        bodyB: wheelA,
        stiffness: 0.5
    });
    var axelB = Constraint.create({
        bodyA: body,
        pointA: { x: wheelBOffset, y: wheelYOffset },
        bodyB: wheelB,
        stiffness: 0.5
    });
    
    Composite.addBody(car, body);
    Composite.addBody(car, wheelA);
    Composite.addBody(car, wheelB);
    Composite.addConstraint(car, axelA);
    Composite.addConstraint(car, axelB);
    
    var box = Composite.create({ label: 'box' });
    var boxes = {
      bottom: yy - height * 0.5,
      under: {
        w: 60,
        h: 30
      },
      left: {
        w: 25,
        h: 70
      },
      right: {
        w: 25,
        h: 70
      }
    };
    var underBox = Bodies.rectangle(xx + boxes.under.w * 0.5,
                                    boxes.bottom - boxes.under.h * 0.5,
                                    boxes.under.w,
                                    boxes.under.h);
    var leftBox = Bodies.rectangle(xx - boxes.left.w * 0.5,
                                   boxes.bottom - boxes.left.h * 0.5,
                                   boxes.left.w,
                                   boxes.left.h);
    var rightBox = Bodies.rectangle(xx + boxes.under.w + boxes.right.w * 0.5,
                                    boxes.bottom - boxes.right.h * 0.5,
                                    boxes.right.w,
                                    boxes.right.h);
    var leftLabel = Constraint.create({
        bodyA: underBox,
        pointA: {
          x: -(boxes.under.w * 0.5) - (boxes.left.w * 0.5),
          y: (boxes.under.h * 0.5) - (boxes.left.h * 0.5)
        },
        bodyB: leftBox,
        stiffness: 1
    });
    var rightLabel = Constraint.create({
        bodyA: underBox,
        pointA: {
          x: (boxes.under.w * 0.5) + (boxes.left.w * 0.5),
          y: (boxes.under.h * 0.5) - (boxes.left.h * 0.5)
        },
        bodyB: rightBox,
        stiffness: 1
    });
    
    Composite.addBody(box,underBox);
    Composite.addBody(box,leftBox);
    Composite.addBody(box,rightBox);
    Composite.addConstraint(box,leftLabel);
    Composite.addConstraint(box,rightLabel);
    
    
    var carUnderLabel = Constraint.create({
        bodyA: body,
        pointA: { x: boxes.under.w * 0.5, y: -(height * 0.5) - boxes.under.h * 0.5 },
        bodyB: underBox,
        stiffness: 1
    });
    var carLeftLabel = Constraint.create({
        bodyA: body,
        pointA: { x: -(boxes.left.w * 0.5), y: -(height * 0.5) },
        bodyB: leftBox,
        pointB: { x: 0, y: boxes.left.h * 0.5 },
        stiffness: 1
    });
    var carRightLabel = Constraint.create({
        bodyA: body,
        pointA: { x: boxes.under.w + boxes.right.w * 0.5, y: -(height * 0.5) },
        bodyB: rightBox,
        pointB: { x: 0, y: boxes.right.h * 0.5 },
        stiffness: 1
    });
    
    Composite.addComposite(car,box);
    Composite.addConstraint(car,carUnderLabel);
    Composite.addConstraint(car,carLeftLabel);
    Composite.addConstraint(car,carRightLabel);
    
    World.add(engine.world,car);
    Engine.run(engine);
    
    $("#left").click(function(t){
        var carBodies = Composite.allBodies(car);
        carBodies[1].force.x = 2;  
    });
[/code]

[code]

    #left {
      position: absolute;
      top: 0;
      left: 0;
    }
[/code]

[code]

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <script src="https://github.com/liabru/matter-js/releases/download/0.8.0-alpha/matter-0.8.0.js" type="text/javascript"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore.js"></script>
    
    <div id = "canvas-container"></div>
    <input id = "left" type = "button" value = "left">
[/code]


CC BY-SA 3.0
2015-01-16T18:37:43.003
4709
2015-01-16T18:37:43.003
30
4445
answer