1
\$\begingroup\$

First the issue im having: Basically its the fact that the angles of a circle aren't continuous, they rise from 0 to 2pi then immediately fall back to 0.

I want to make a game where the player controls a tank and ive got a tank drive working but i want to implement a "Directional Drive" where the player can push a joy stick(XBOX360) in a certain direction and the tank will move forward and turn towards this direction. heres the code i have to do that:

if (Math.Abs(controllerCOORD.Y) > Deadzone || Math.Abs(controllerCOORD.X) > Deadzone)
        {
            decimal intended_angle = (decimal)Math.Atan2(controllerCOORD.X, controllerCOORD.Y);

            double correction = (double)Decimal.Round((intended_angle - (decimal)this.BaseAngle_Rad), 1, MidpointRounding.AwayFromZero);

            this.BaseAngle_Rad += (correction / demultiplier_rot);

            this._x_pos += ((float)Math.Sin(this.BaseAngle_Rad) * multiplier_pos); //x component vector of movement
            this._y_pos -= ((float)Math.Cos(this.BaseAngle_Rad) * multiplier_pos); //y component vector of movement
        }

Unfortunately with this code, when the player pushed the joystick downwards(0,1), the angle it calculates approches pi from the right side and negative pi from the left side causing it to make a full turn in the wrong direction instead of like a few degrees in the correct direction.

How do i make the rotation continuous all the way around? Ive already found these two questions on here but neither is helping me:

360+ degree rotation skips back to 0 degrees when using Math.Atan2(y, x)

Turning a sprite such that it rotates in the direction that's most efficient

Thanks

\$\endgroup\$
1
\$\begingroup\$

I misread one of the links i posted and it turned out to be more helpfulthan i thought. the working code sample:

if (Math.Abs(controllerCOORD.Y) > Deadzone || Math.Abs(controllerCOORD.X) > Deadzone)
{
    double intended_angle = Math.Atan2(controllerCOORD.X, controllerCOORD.Y);
    double current_angle = this.BaseAngle_Rad % MathHelper.TwoPi;
    double difference = ((intended_angle - current_angle + MathHelper.Pi) % MathHelper.TwoPi) - MathHelper.Pi;
    if (intended_angle > current_angle + MathHelper.Pi)
    {
        intended_angle -= 2 * MathHelper.Pi;
    }
    else if (intended_angle < current_angle - MathHelper.Pi)
    {
        intended_angle += 2 * MathHelper.Pi;
    }
    this.BaseAngle_Rad = MathHelper.Lerp((float)current_angle, 
                                         (float)intended_angle, 
                                         2.5f * (float)gametime.ElapsedGameTime.TotalSeconds);
    this._x_pos += ((float)Math.Sin(this.BaseAngle_Rad) * multiplier_pos); //x component vector of movement
    this._y_pos -= ((float)Math.Cos(this.BaseAngle_Rad) * multiplier_pos); //y component vector of movement
}

Sorry for the pointless post, hope someone else may find this useful

\$\endgroup\$
  • \$\begingroup\$ You may want to reformat that code snippet, it is nearly unreadable when formatted like this. \$\endgroup\$ – Felsir Nov 16 '15 at 7:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.