计算速度粒子运动与直线之间的角度

问题描述

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

Four line options,with their respective save points in an object.

因此存储行的对象是这样定义的:

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

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

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

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

ballstrike

球以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度……

demo picture

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

在如何获得两个速度和直线之间的正确和可用角度方面的任何帮助,将不胜感激!

请注意,我已经尝试过utilizing this solution,但一直在努力使其适应我的工作。

解决方法

所以花了我一些时间,但我仍然不能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);

感谢所有看过:)