Найдите нормальные и тангенциальные компоненты движения в box2d/matter.js

Я пытаюсь воссоздать модель сопротивления жидкости, как показано в параграф 2.2.1 этой статьи< /а>. Рабочую версию можно увидеть в этом этом ролике на YouTube (где я нашел статью) .

В статье утверждается, что они рассчитывают нормальную и касательную силы скорости ребра мягкого тела. Я пытался понять, как перейти от краевой скорости к этим двум составляющим силы. Однако я могу найти ресурсы только для расчета компонентов на основе функции (например, это), и я изо всех сил пытаюсь перевести это в свою физическую среду. Как можно было бы реализовать эту модель сопротивления жидкости?

Вот скрипт, показывающий мою среду: https://jsfiddle.net/Swendude/1nnckp5p/

// module aliases
var Engine = Matter.Engine,
    Render = Matter.Render,
    World = Matter.World,
    Bodies = Matter.Bodies,
    Body = Matter.Body,
    Vector = Matter.Vector,
    Composite = Matter.Composite,
    Composites = Matter.Composites,
    Constraint = Matter.Constraint,
    Events = Matter.Events;

// create an engine
var engine = Engine.create();

// create a canvas
var canvas = document.getElementById("maincanvas");

var render = Render.create({
    element: document.body,
    canvas: canvas,
    engine: engine,
    options: {
        background: "#fff",
        height: 400,
        width: 400,
        wireframes: false,
    }
});

engine.world.gravity = {x:0, y:0};

// Create a soft body composite, see 
// http://brm.io/matter-js/docs/classes/Composites.html#method_softBody
var softbox = Composites.softBody(100,100,2,2,40,40,true,1);

World.add(engine.world, softbox);


// This functions makes some constraints move.

function pulse(composite) {
  var allcons = Composite.allConstraints(composite);
  allcons[0].length += 5;
  allcons[4].length += 5;

  // Set a timeout to make the constraints short again
  setTimeout(function (cons) { cons.length -= 5;}, 1000, allcons[0]);
  setTimeout(function (cons) { cons.length -= 5;}, 1000, allcons[4]);
}

setInterval(pulse, 2000, softbox);

function applyForcesOnEdge() {
    var allcons = Composite.allConstraints(engine.world);

    allcons.forEach( function(cons, index) {
        // Edge speed defined as the average of both connected body's speed. 
        var constraintspeed = Vector.div(Vector.add(cons.bodyA.velocity, cons.bodyA.velocity),2);
        if (constraintspeed.x != 0 && constraintspeed.y != 0) {
          console.log(constraintspeed); // How to get the tangential and normal components from this?
        }
    });
}

Events.on(engine, 'beforeUpdate', function () {
  applyForcesOnEdge();
})


Engine.run(engine);

Render.run(render);

По большей части это шаблоны из Matter.js, интересные части — это функции: pulse() и applyForcesOnEdge().

Я использую matter.js, но могу предположить, что тот же вопрос может быть применен к среде box2d. .


person SwenMulderij    schedule 17.06.2017    source источник


Ответы (1)


Просто возьмите разницу между позициями объектов по обе стороны от ограничения. Это лучше объяснить в коде:

allcons.forEach( function(cons, index) {
    // Edge speed defined as the average of both connected body's speed. 
    var constraintspeed = Vector.div(
        Vector.add(
            cons.bodyA.velocity,
            cons.bodyB.velocity),
        2);
    var constraintpos = Vector.div(
        Vector.add(
            cons.bodyA.position,
            cons.bodyB.position),
        2);
    var tangent = Vector.normalise(
        cons.bodyB.position -
        cons.bodyA.position);
    var normal = Vector.perp(tangent);
    var v_T = Vector.dot(constraintspeed, tangent);
    var v_N = Vector.dot(constraintspeed, normal);
    var F_T = - lambda_T * Math.sign(v_T) * v_T * v_T;
    var F_N = - lambda_N * Math.sign(v_N) * v_N * v_N;
    var F = Vector.add(
        Vector.mult(tangent, F_T),
        Vector.mult(normal, F_N));
    Body.applyForce(cons.bodyA, constraintpos, F);
    Body.applyForce(cons.bodyB, constraintpos, F);
});
person cdo256    schedule 08.07.2017
comment
Кажется, это правильный ответ. Единственная проблема, с которой я столкнулся сейчас, это настройка значений, чтобы получить реалистичное поведение, а не глючить всю страницу. Посмотрите эту скрипту, чтобы узнать, как я ее использовал -› jsfiddle.net/Swendude/1nnckp5p/5 . (Будьте осторожны, он имеет тенденцию к сбою). Спасибо! - person SwenMulderij; 18.07.2017
comment
Странно, на моем телефоне вроде работает нормально (iOS 10.3.2, Safari). - person cdo256; 18.07.2017
comment
Попробуйте изменить значение. (В статье нормальный компонент примерно в 50 раз больше тангенциального) - person SwenMulderij; 18.07.2017