/// <summary> /// Moves a train around a 90 degree arc, in either direction /// </summary> /// <param name="position">The trains position</param> /// <param name="quadrantPositionX">The distance between the center of the circle, and the left hand side of the cell</param> /// <param name="quadrantPositionY">The distance between the center of the circle, and the top of the cell</param> /// <param name="midpointAngle">The angle at the middle of the arc you want to move</param> public static void MoveAroundCorner(TrainPosition position, int quadrantPositionX, int quadrantPositionY, int minTrainAngleCCW, int maxTrainAngleCCW, int minimumAngle, int maximumAngle) { // Find the angle within the tracks circle using the current position // This *should* be perpendicular to angle double currentAngle = TrainMovement.PointsToAngle(position.RelativeLeft - Math.Abs(quadrantPositionX), position.RelativeTop - Math.Abs(quadrantPositionY)); // To travel 2PIr, we need to move 360 // To travel x we need to move x/2PIr * 360 // To travel x rad we need to move x/2PIr * 2PI // To travel x rad we need to move x/r double angleToMove = position.Distance / 0.5; float distance; // In order to figure out if we are moving clockwise or counter-clockwise, look at the angle of the train if (BetweenAngles(position.Angle, minTrainAngleCCW, maxTrainAngleCCW)) { // We are facing left/up, so we move counter clockwise, with a minimum angle of 90 (currentAngle, distance) = MoveCounterClockwise(currentAngle, angleToMove, position.Distance, DegreeToRad(minimumAngle)); position.Angle = (float)TrainMovement.RadToDegree(currentAngle) - 90.0f; } else { // We are NOT facing left/up, so we move clockwise, with a maximum angle of 180, Math.PI (currentAngle, distance) = MoveClockwise(currentAngle, angleToMove, position.Distance, DegreeToRad(maximumAngle)); position.Angle = (float)TrainMovement.RadToDegree(currentAngle) + 90.0f; } position.Distance = distance; // Double check to keep our angle in range, this makes our angle checks easier!: position.Angle = TrainMovement.KeepWithin0and360(position.Angle); // Find our new position on the track (position.RelativeLeft, position.RelativeTop) = TrainMovement.AngleToPoints(currentAngle, 0.5f); position.RelativeLeft += Math.Abs(quadrantPositionX); position.RelativeTop += Math.Abs(quadrantPositionY); }