让炮塔转向直到面向目标方向?

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.

首先,您应该采用目标相对于炮塔的角度,而不是相反。这可以通过在减法中交换位置向量来解决。

其次,一旦你有了目标角度,减去炮塔的当前角度就会得到你需要应用的旋转偏移。然后,使用一些模块化算法和一些 ifs 在 -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;
        }