让炮塔转向直到面向目标方向?
Getting a turret to turn until facing a target direction?
我正在尝试让炮塔面对敌人,我已经设置了所有逻辑我的问题是三角函数。
这是我画的插图:
这是我目前得到的代码:
//Get the target degree (Is returned with a box2d world facing right, so make it face up)
float targetDegree = (((currentLockedEnemy.getBody().getPosition().sub(getBody().getPosition()).angle() + 270f) % 360f));
//Get the turret current facing degree.
float currentTurretFacingDirection = (getBody().getAngle() * MathUtils.radiansToDegrees) % 360f;
//Because box2d can go negative angles.
if(currentTurretFacingDirection < 0f){
currentTurretFacingDirection += 360f;
}
//Because it will go over 360 to 0. Make it within the 180 to -180 range. Fixes the skip
if(currentTurretFacingDirection > 180f){
currentTurretFacingDirection -= 360f;
}
if(targetDegree > 180f){
targetDegree -= 360f;
}
//Subtract the current turret facing angle from the target.
float rotationalOffset = targetDegree - currentTurretFacingDirection;
//If it's greater than the accuracy turn towards the object.
if(Math.abs(rotationalOffset) > getAccuracy())
{
if(rotationalOffset > 0f)
{
this.revoluteJoint.setMotorSpeed(TURN_SPEED);
}
else
{
this.revoluteJoint.setMotorSpeed(-TURN_SPEED);
}
}
else{
this.revoluteJoint.setMotorSpeed(0f);
}
我的问题是,到底如何让炮塔以正确的角度转动?
仅供参考
我将 Box2d 与 Libgdx 一起使用,语言是 JAVA.
首先,您应该采用目标相对于炮塔的角度,而不是相反。这可以通过在减法中交换位置向量来解决。
其次,一旦你有了目标角度,减去炮塔的当前角度就会得到你需要应用的旋转偏移。然后,使用一些模块化算法和一些 if
s 在 -180
和 +180
之间移动该偏移量。如果结果是肯定的,你需要旋转一个方向。如果它是负数,则需要以另一种方式旋转。如果结果是 "close enough" 到零,那么炮塔正在瞄准 "close enough" 目标("close enough" 取决于您需要的精度)。
我建议采用完全不同的方法。
导出一条穿过炮塔的直线,指向炮塔所面对的方向,作为直线方程 ax + by + c = 0 中的系数 [a,b,c]。
使用以下公式计算直线到目标的距离:
D = (a.tx + b.ty + c) / Sqrt( a^2 + b^2 )
如果 D 为负,则将炮塔左转,如果为正,则将炮塔右转(如果是这种情况,则相反)。如果D为0,则炮塔要么正对着目标,要么正对着目标的相反方向。
这里有一些伪代码来说明我的意思。我假设有一些方法可以获得炮塔的 "forward vector",即指向炮塔所面对方向的二维向量。
public static float calculate(float turretPositionX, float turretPositionY,
float turretForwardX, float turretForwardY,
float targetPositionX, float targetPositionY)
{
float a, b, c;
a = turretForwardY;
b = -turretForwardX;
c = -(a * turretPositionX + b * turretPositionY);
float d = (a * targetPositionX + b * targetPositionY + c) / (float)Math.Sqrt(a * a + b * b);
// if d is negative, turn one way, if it's positive, turn the other.
// if it's zero, you're either facing directly toward the target, or directly
// away from it.
return d;
}
我正在尝试让炮塔面对敌人,我已经设置了所有逻辑我的问题是三角函数。
这是我画的插图:
//Get the target degree (Is returned with a box2d world facing right, so make it face up)
float targetDegree = (((currentLockedEnemy.getBody().getPosition().sub(getBody().getPosition()).angle() + 270f) % 360f));
//Get the turret current facing degree.
float currentTurretFacingDirection = (getBody().getAngle() * MathUtils.radiansToDegrees) % 360f;
//Because box2d can go negative angles.
if(currentTurretFacingDirection < 0f){
currentTurretFacingDirection += 360f;
}
//Because it will go over 360 to 0. Make it within the 180 to -180 range. Fixes the skip
if(currentTurretFacingDirection > 180f){
currentTurretFacingDirection -= 360f;
}
if(targetDegree > 180f){
targetDegree -= 360f;
}
//Subtract the current turret facing angle from the target.
float rotationalOffset = targetDegree - currentTurretFacingDirection;
//If it's greater than the accuracy turn towards the object.
if(Math.abs(rotationalOffset) > getAccuracy())
{
if(rotationalOffset > 0f)
{
this.revoluteJoint.setMotorSpeed(TURN_SPEED);
}
else
{
this.revoluteJoint.setMotorSpeed(-TURN_SPEED);
}
}
else{
this.revoluteJoint.setMotorSpeed(0f);
}
我的问题是,到底如何让炮塔以正确的角度转动?
仅供参考 我将 Box2d 与 Libgdx 一起使用,语言是 JAVA.
首先,您应该采用目标相对于炮塔的角度,而不是相反。这可以通过在减法中交换位置向量来解决。
其次,一旦你有了目标角度,减去炮塔的当前角度就会得到你需要应用的旋转偏移。然后,使用一些模块化算法和一些 if
s 在 -180
和 +180
之间移动该偏移量。如果结果是肯定的,你需要旋转一个方向。如果它是负数,则需要以另一种方式旋转。如果结果是 "close enough" 到零,那么炮塔正在瞄准 "close enough" 目标("close enough" 取决于您需要的精度)。
我建议采用完全不同的方法。
导出一条穿过炮塔的直线,指向炮塔所面对的方向,作为直线方程 ax + by + c = 0 中的系数 [a,b,c]。
使用以下公式计算直线到目标的距离: D = (a.tx + b.ty + c) / Sqrt( a^2 + b^2 )
如果 D 为负,则将炮塔左转,如果为正,则将炮塔右转(如果是这种情况,则相反)。如果D为0,则炮塔要么正对着目标,要么正对着目标的相反方向。
这里有一些伪代码来说明我的意思。我假设有一些方法可以获得炮塔的 "forward vector",即指向炮塔所面对方向的二维向量。
public static float calculate(float turretPositionX, float turretPositionY,
float turretForwardX, float turretForwardY,
float targetPositionX, float targetPositionY)
{
float a, b, c;
a = turretForwardY;
b = -turretForwardX;
c = -(a * turretPositionX + b * turretPositionY);
float d = (a * targetPositionX + b * targetPositionY + c) / (float)Math.Sqrt(a * a + b * b);
// if d is negative, turn one way, if it's positive, turn the other.
// if it's zero, you're either facing directly toward the target, or directly
// away from it.
return d;
}