【问题标题】:Calculating the angle between a velocity (particles motion) and a line计算速度(粒子运动)和直线之间的角度
【发布时间】:2020-11-03 12:25:20
【问题描述】:

所以我正在创建一个弹跳球的模拟,用户可以通过从一个点拖动到另一个点来在画布上放置球可以碰撞的线。基本上可以创建四行:

所以存储一行的对象是这样定义的:

export interface pathSection {
    xfrom: number;
    yfrom: number;
    xto: number;
    yto: number;
    length: number;
}

例如,图像中的第一行和第三行不给出相同的值

Math.atan2(yto - yfrom, xto - from);

因此,鉴于表面的(相对)复杂性,我需要找到移动物体与碰撞点表面之间的角度:

球以 a 角撞击表面,这就是我想要的!

但是我很难找到两个向量之间的角度。这就是我认为可行的方法:

var dx = this.path[index_for_path_section].xfrom - this.path[index_for_path_section].xto;
var dy = this.path[index_for_path_section].yfrom - this.path[index_for_path_section].yto;
var posX = this.particle.pos.x;
var posY = this.particle.pos.y;
var posNextX = posX + this.particle.v.x;
var posNextY = posY + this.particle.v.y;

var angleOfRamp = Math.atan2(dy, dx);
var angleOfvelocity = Math.atan2(posNextY - posY, posNextX - posX);
var angleBetween =  angleOfRamp - angleOfvelocity;

然后用它来计算碰撞后物体的速度:

var spd = Math.sqrt(this.particle.v.x * this.particle.v.x + this.particle.v.y * this.particle.v.y);
var restitution = this.elasticity / 100;

this.particle.v.x = restitution * spd * Math.cos(angleBetween);
this.particle.v.y = restitution * spd * Math.sin(angleBetween);

但是计算出的角度约为 -4.5 Pi,直接向下的物体约为 -90 度,表面看起来约为 45-60 度......

红色箭头表示物体在表面上移动的路径 - 白点表示在表面和物体之间检测到碰撞的位置。

任何关于如何获得两个速度和线之间正确和可用角度的帮助将不胜感激!

请注意,我尝试过 utilizing this solution,但很难将其适应我自己的工作。

【问题讨论】:

  • 确定表面相对于轴的角度。使用它来调整传入矢量,使表面垂直于轴。取反传入向量的垂直轴以创建传出向量。

标签: javascript vector angle


【解决方案1】:

所以我花了一些时间,我仍然不能 100% 确定它为什么有效,因为我认为我发现 JavaScript 角度系统有点棘手,但是:

var dx = this.path[collided].xfrom - this.path[collided].xto;
var dy = this.path[collided].yfrom - this.path[collided].yto;
var spd = Math.sqrt(this.particle.v.x * this.particle.v.x + this.particle.v.y * this.particle.v.y);
                 
var angleOfRamp = Math.atan2(dy, dx);
var angleOfvelocity = Math.atan2(this.particle.v.y, this.particle.v.x);
var angleBetween =  angleOfRamp * 2 - angleOfvelocity; // not sure why :)

if (angleBetween < 0) { angleBetween += 2*Math.PI; } // not sure why :)
                 
const restitution = this.elasticity / 100;

this.particle.v.x = restitution * spd * Math.cos(angleBetween);
this.particle.v.y = restitution * spd * Math.sin(angleBetween);

感谢所有观看的人:)

【讨论】:

    猜你喜欢
    • 2011-02-10
    • 2015-06-17
    • 2019-07-09
    • 2011-11-27
    • 2016-06-19
    • 2017-07-23
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    相关资源
    最近更新 更多