在box2d/matter.js中查找运动的正常和切向分量
问题描述:
我正在尝试重新创建流体拖动模型,如 paragraph 2.2.1 of this paper中所见。在这个this youtube movie(我发现这篇论文的地方)中可以看到一个工作版本。在box2d/matter.js中查找运动的正常和切向分量
在论文中,他们声明他们计算软体边缘速度的法向力和切向力。我试图理解如何从边缘速度到这两个力分量。不过,我只能找到关于基于函数计算组件的资源(例如this),并且我正在努力将其转换为我的物理环境。什么是实现这种流体阻力模型的方法?
这里是一个小提琴显示我的环境: 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环境。
答
只需在约束两侧的对象位置之间进行区分即可。最好在代码中解释:
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);
});
这似乎是正确的答案。我现在唯一的问题是调整价值观以获得切合实际的行为,而不是弄错整个页面。查看 这个小提琴是如何使用它的 - > https://jsfiddle.net/Swendude/1nnckp5p/5/。 (小心,它往往会崩溃)。谢谢! – SwenMulderij
奇怪的是,它似乎在我的手机(iOS 10.3.2,Safari)上正常工作。 – cdo256
尝试更改值。 (在本文中,法向分量大约是切向大小的50倍) – SwenMulderij