撞墙后计算角度变化 [英] Calculate angle change after hitting a tilted wall

查看:55
本文介绍了撞墙后计算角度变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用javascript做游戏,其中的一个物体应该从墙壁反弹.我真的想让它自己工作,但是永远无法正常工作.

I'm making a game in javascript, where an object is supposed to bounce from walls. I really tried to get it to work myself, but it never works correctly.

比方说,这个笼子里有一个弹跳的球(蓝色= 30°,棕色= 60°);

Let's say theres a ball bouncing inside this cage (blue = 30°, brown = 60°);

球的坐标是已知的.运动角度是已知的.碰撞点(P)坐标是已知的.墙壁的角度是已知的.球的位置正在使用以下函数在setInterval函数内更新其坐标:

The ball's coordinates are known. The angle of movement is known. The point of collision (P) coordinates are known. The angle of the wall is known. The ball's position is updating it's coordinates inside a setInterval function using this function:

function findNewPoint(x, y, angle, distance) {
var result = {};

result.x =(Math.cos(angle * Math.PI / 180) * distance + x);
result.y = (Math.sin(angle * Math.PI / 180) * distance + y);

return result;

因此,在发生碰撞时,应该有一个可以正确改变球角度的功能.看来这是一个非常复杂的问题,因为即使我知道墙是30°,也很重要的一点是要知道球从哪一侧碰撞到其中.我尝试使用在平面上的直线上的反射"公式以及一些矢量,但是它对我而言从来没有奏效.我不希望代码有完整的答案,如果有人可以建议应该以哪种方式进行编程,那么它也会有所帮助.

So, upon colliding, there should be a function that properly changes the ball's angle. It's a very complicated problem it seems, because even if I know that the wall is 30°, its important to know from what side the ball is colliding into it. I tried using the "Reflection across a line in the plane" formula and also some vectors, but it never worked out for me. I'm not expecting a complete answer with code, if someone could suggest in what way this should be programmed, it would help aswell.

谢谢你们给我的提示,我意识到是造成最大混乱的原因.如果用鼠标在画布上选择一个角度,则起始坐标(0,0)在左下角.但是由于画布的起始坐标在左上角,所以必须考虑这一点.

Thanks for your tips guys, I realized what was causing the most confustion; if I select an angle on the canvas with my mouse, the starting coordinate(0,0) is in the bottom left corner. But since the canvas' starting coordinate is in the top left corner, this has to be considered.

基本上使用此公式来计算角度:

Basically using this formula for calculating the angle:

function angle(cx, cy, ex, ey) {
var dy = ey - cy;
var dx = ex - cx;
var theta = Math.atan2(dy, dx);
theta *= 180 / Math.PI; 
return theta;

}

如果球从(50,50)移至(100,100),则角度将为-45.

if the ball moved from (50,50) to (100,100), the angle would be -45.

现在,撞墙时此角度将以以下方式变化:

Now, this angle changes in the following way when hitting walls:

如果说实话,我是经过反复试验得出的,不是很了解为什么精确地为60和120.

If im honest, I got these out of trial and error, am not really understanding why exactly 60 and 120.

推荐答案

使用角度移动球并一次又一次地计算Cos/Sin是不明智的.而是使用像这样的分量 vx,vy 的单位速度方向矢量:

It is not wise to use angle for moving ball and calculate Cos/Sin again and again. Instead use unit velocity direction vector with components vx, vy like this:

new_x = old_x + vx * Velocity_Magnitude * Time_Interval

请注意, vx = Cos(角度),vy = Sin(角度),但是通过方向方法,您几乎不需要使用三角函数.

Note that vx = Cos(angle), vy = Sin(angle), but with direction approach you seldom need to use trigonometric functions.

倾斜角度为Fi的倾斜墙

Tilted wall with angle Fi has normal

nx = -Sin(Fi)
ny = Cos(Fi)

要找到反射,您需要计算速度与法线的点积

To find reflection , you need to calculate dot product of velocity and normal

dot = vx * nx + vy * ny

反射后的速度转换:

vnewx = v.x - 2 * dot * n.x 
vnewy = v.y - 2 * dot * n.y 

使用这些值进行进一步移动

Use these values for further moving

(请注意,您可以同时使用内部和外部法线方向,因为方向翻转会同时改变两个分量,并且 2 * dot * nx 的符号保持不变)

(note that you can use both internal and external normal direction, because direction flip changes both components, and sign of 2 * dot * n.x remains the same)

示例:

horizontal moving right
vx=1, vy=0   
30 degrees wall has normal 
nx=-1/2, ny=Sqrt(3)/2  
dot = -1/2
vnewx = 1 - 2 * (-1/2) * (-1/2) = 1/2
vnewy = 0 - 2 * (-1/2) * Sqrt(3)/2 = Sqrt(3)/2
(velocity direction angle becomes 60 degrees)

horizontal moving left
vx=-1, vy=0   
330 degrees wall (left bottom corner) has normal 
nx=1/2, ny=Sqrt(3)/2  
dot = -1/2
vnewx = -1 - 2 * (-1/2) * (1/2) = -1/2
vnewy = 0 - 2 * (-1/2) * (Sqrt(3)/2) = Sqrt(3)/2
(velocity direction angle becomes 120 degrees)

这篇关于撞墙后计算角度变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆