我正在尝试制作一个涉及计算执行一些简单数学运算所需力的游戏。我有一个dx
变量,表示沿X轴的速度和方向。现在我想减去摩擦,但如果dx
的方向为负,则必须添加。有没有办法在返回有符号值时使用绝对值减去dx
的摩擦力?我正在寻找按位运算符,但我不知道可能性是什么......
我能做什么(我认为):
sign = ( dx >> 31 ) << 31;
dx = (dx << 1) >> 1;
dx = ( dx - friction ) & sign;
不确定这是否有用,只是想法......有什么改进吗?
编辑:这就是我所做的:
dxSign = Integer.signum(dx) * -1;
dySign = Integer.signum(dy) * -1;
dy = Math.abs(dy);
dx = Math.abs(dx);
fric = body.friction * mass;
dx = ( dx > fric ) ? dx - fric : 0;
dy = ( dy > fric ) ? dy - fric : 0;
dx = dx * absorption;
dy = dy * absorption;
dx *= dxSign;
dy *= dySign;
答案 0 :(得分:2)
最安全的选择是使用条件。你不希望分数改变方向
dx = dx < -friction ? dx + friction : dx > friction ? dx - friction : 0
答案 1 :(得分:1)
您的代码不正确,原因有两个:
dx = (dx << 1) >> 1;
不会消除这个标志。而且,当位31被设置为1
时,它可能错误地产生“误报”(即,错误的负数)。即使您将>>
替换为>>>
,也不会获得绝对值,因为int
存储在二进制补码中,而不是作为符号+值表示sign
将是二进制表示中的10000...00
或00000..00
,因此( dx - friction ) & sign
不会将该符号与其他计算的结果合并。您可以使用Integer.signum
功能更改减法的加法,如下所示:
dx -= Integer.signum(dx) * friction;
答案 2 :(得分:1)
只是以明显的方式做到这一点:除非出现性能问题,否则不要试图变得聪明。
if(dx >0 ) {
dx -= friction;
} else {
dx += friction;
}
如果这看起来有点冗长,请将其隐藏在方法中:
dx = applyFriction(dx,friction);
int applyFriction(int pos, int friction) {
if(pos > 0) {
return pos - friction;
} else {
return pos + friction;
}
}
abs(pos) < friction
时出现此问题,如果你研究一下你的物理特性,你会发现通过乘法模拟摩擦的可能性更大 - 这可以消除你对符号的担忧。
答案 3 :(得分:1)
如果要忽略该符号,请使用Math.abs
。请注意,优化可能会导致代码变得难以理解且难以维护。因此,对于初学者来说,尝试使您的代码变得干净和可能,当您遇到性能问题时,通过基准测试确定问题的根源,并仅优化代码的瓶颈。
答案 4 :(得分:1)
在物理学中,你的方向标志并不重要。我建议使用这样的事实,即动摩擦力是一个与运动中物体的绝对速度成正比的力。也就是说,对象在μF
范围内具有一些摩擦系数[0, 1]
。速度的变化只是δV = μF∙V∙δt
,其中 V
是对象的初始速度向量,δt
是一段时间。
新的 V'
由
V' = V - δV
= V - μF∙V∙δt
= V(1 - μF∙δt)
通过这种方式,你根本不需要处理这个符号,它很容易扩展到更高维度的情况。
另外,确保δ t 足够小,不会在模型中引入振荡。