Skip to content

Instantly share code, notes, and snippets.

# amulware/angle-basic-setup.csSecret Last active Aug 29, 2015

Example code snippets for GameDev<T> blog post on binary representations for angles and directions
 public struct Angle { // contained value private readonly float radians; // private constructor to hide implementation private Angle(float radians) { this.radians = radians; } // public static construction methods to enforce semantics public static Angle FromRadians(float radians) { return new Angle(radians); } // radians property used to retrieve value if needed public float Radians { get { return this.radians; } } }
 public struct Direction { // conversion constants const float fromRadians = uint.MaxValue / ((float) Math.Pi * 2); const float toRadians = ((float)Math.Pi * 2) / uint.MaxValue; // the integer storing the actual binary representation private readonly uint data; // private constructor to hide implementation private Direction(uint data) { this.data = data; } // static constructions methods for strong semantics public static Direction FromRadians(float radians) { return new Direction((uint)(radians * Direction.fromRadians)); } // radians property used to retrieve value if needed public float Radians { get { return this.data * Direction.toRadians; } } }
 // substract two directions to get the angle between them // due to integer overflow this will always return an angle in the interval [-180, 180] degrees public static Angle operator -(Direction direction1, Direction direction2) { return Angle.FromRadians((direction1.data - direction2.data) * toRadians); } // adds an angle to the direction // again, due to integer overflow no wrapping checks are needed public static Direction operator +(Direction direction, Angle angle) { return new Direction((uint)(direction.data + angle.Radians * fromRadians)); }
 // create direction from vector public static Direction Of(Vector2 vector) { return Direction.FromRadians((float)Math.Atan2(vector.Y, vector.X)); } // get unit vector in direction public Vector2 Vector { get { var radians = this.Radians; return new Vector2((float)Math.Cos(radians), (float)Math.Sin(radians)); } }
 // returns a new direction, based on the this one and rotated towards a goal direction // never overshoots the goal and turns at most the given amount in radians public Direction TurnedTowards(Direction goal, float maxStepInRadians) { // we don't turn for negative step sizes if (maxStepInRadians <= 0) return this; // we create an Angle representation to use our own operator overloads var step = Angle.FromRadians(maxStepInRadians); // calculate the Angle towards the goal var thisToGoal = goal - this; // if the allowed step is larger than the actual angular distance, we arrive at the goal and return its value if (maxStepInRadians > Math.Abs(thisToGoal.Radians)) return goal; // we have not arrived at the goal yet // make sure we are turning in the right direction by considering the sign of the angle towards the goal // and return a new direction return this + step * Math.Sign(thisToGoal.Radians); }
 pDir = direction of projectile's velocity tDir = direction from projectile to target pDirNew = turn pDir towards tDir, without overshooting it, with maximum step maxAngularVelocity * frameTimeStep set direction of projectile's velocity to point in direction pDirNew
 var pDir = Direction.Of(projectile.Velocity); var tDir = Direction.Of(target.Position - projectile.Position); var pDirNew = pDir.TurnedTowards(tDir, maxAngularVelocity * frameTimeStep); projectile.Velocity = pDirNew.Vector * projectile.Velocity.Length;
to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.