如何“舍入”最接近 15 度的 2D 矢量

发布于 2024-12-29 07:01:00 字数 398 浏览 2 评论 0原文

我正在开发一个简单的游戏,我正在尝试简化游戏中部分 2D 碰撞反应。当某些物体撞到墙壁时,我会计算碰撞法线(collisionPoint - objectCenter)并根据该法线进行反射。我有兴趣将该法线向量舍入到最接近的 15°,但我不确定有什么好方法。

我目前的想法是做这样的事情

float angle = atan2(normal.Y, normal.X) * Rad2Deg;
float newAngle = ((int)(angle + 7.5f) / 15) * 15.0f * Deg2Rad;
vector2 newNormal = vector2(cos(newAngle), sin(newAngle));

这是一个合理的方法吗?有更好的办法吗?

I'm working on a simple game and I'm trying to simplify part of the 2D collision reaction in the game. When certain objects hit walls, I'm calculating a collision normal (collisionPoint - objectCenter) and reflecting based on that normal. I'm interested in rounding that normal vector to its nearest 15° but I'm not sure of a good way to go about that.

My current thought is doing something like this

float angle = atan2(normal.Y, normal.X) * Rad2Deg;
float newAngle = ((int)(angle + 7.5f) / 15) * 15.0f * Deg2Rad;
vector2 newNormal = vector2(cos(newAngle), sin(newAngle));

Is this a reasonable way to do it? Is there a better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

放飞的风筝 2025-01-05 07:01:00

试试这个:

float roundAngle = 15 * Deg2Rad;
float angle = (float)Math.Atan2(normal.Y, normal.X);
Vector2 newNormal;

if (angle % roundAngle != 0)
{
    float newAngle = (float)Math.Round(angle / roundAngle) * roundAngle;
    newNormal = new Vector2((float)Math.Cos(newAngle), (float)Math.Sin(newAngle));
}
else
{
    newNormal = Vector2.Normalize(normal);
}

你不需要添加 7.5,看这个例子:

// 4 degrees should round to 0
    (4 + 7.5) / 15 == 11.5 / 15 == 0.77
// When this gets rounded up to 1 and multiplied by 15 again, it becomes 15 degrees.

// Don't add 7.5, and you get this:
    4 / 15 == 0.27
// When rounded, it becomes 0 and, as such the correct answer

// Now how about a negative number; -12
    -12 / 15 == -0.8
// Again, when rounded we get the correct number

Try this:

float roundAngle = 15 * Deg2Rad;
float angle = (float)Math.Atan2(normal.Y, normal.X);
Vector2 newNormal;

if (angle % roundAngle != 0)
{
    float newAngle = (float)Math.Round(angle / roundAngle) * roundAngle;
    newNormal = new Vector2((float)Math.Cos(newAngle), (float)Math.Sin(newAngle));
}
else
{
    newNormal = Vector2.Normalize(normal);
}

You don't need to add 7.5, take this example:

// 4 degrees should round to 0
    (4 + 7.5) / 15 == 11.5 / 15 == 0.77
// When this gets rounded up to 1 and multiplied by 15 again, it becomes 15 degrees.

// Don't add 7.5, and you get this:
    4 / 15 == 0.27
// When rounded, it becomes 0 and, as such the correct answer

// Now how about a negative number; -12
    -12 / 15 == -0.8
// Again, when rounded we get the correct number
娇柔作态 2025-01-05 07:01:00

实际上,如果您想要最近的 15 度角,则这是更正确的:
这样做:

newangle% = INT(((angle%+7.5)/15)*15) 

默认情况下,INT总是向下舍入,这应该正确地为您提供最近的角度,无论是正数还是负数,玩得开心!
并在括号内添加使用角度到拉德和拉德到角度的部分(如果需要的话,就在角度%旁边,如果该角度没有以度为单位给出,则在其中使用某种 rad2deg 乘数)
这更像是你在基本中执行此操作的方式,经过一些修改它将在 C 代码或类似代码中工作,祝你好运!

actually this is more correct if you want the nearest 15 degree angle :
do this:

newangle% = INT(((angle%+7.5)/15)*15) 

INT ALWAYS rounds DOWN by default this should properly give you the nearest angle in any case that is positive or negative have fun!!
and add the part where you use degree to rad and rad to degree if needed INSIDE the parens (like right next to angle% if that angle is not given in degrees then use some sort of rad2deg multiplier inside there
this is more like how you would do this in basic, with some modification It will work in c code or such, well good luck!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文