/// <summary>
        /// Starts the defined movement if it has not already been started.
        /// </summary>
        public void StartMovement()
        {
            if (currentTime > 0)
            {
                return;
            }
            //construct the real pivot.
            movedObject.transform.position = initial;
            Vector3 middle    = QVectorCalculations.GetVector3Middle(initial, final);
            Vector3 nearest   = QVectorCalculations.GetNearestPointOnLine(middle, (final - initial), pivot);
            Vector3 dir       = (pivot - nearest).normalized;
            Vector3 realPivot = middle;

            //construct circle.
            v1    = (initial - realPivot).normalized * (initial - realPivot).magnitude;
            v2    = dir * (initial - realPivot).magnitude;
            pivot = realPivot;

            currentTime = movementTime;

            //do the movement
            if (isRigidBodyMovement)
            {
                //rigidbody movement
                QGradualMovementManager.AddGradualMovement(rigidbody, this, movementStacked, attemptMerge);
            }
            else
            {
                //regular movement.
                QGradualMovementManager.AddGradualMovement(movedObject, this, movementStacked, attemptMerge);
            }
        }
 /// <summary>
 /// Initializes the circular movement.
 /// </summary>
 /// <param name="rigidbody">The rigidbody to be moved.</param>
 /// <param name="args">the arguments that define the movement.</param>
 public QGradualCircularMovement(Rigidbody rigidbody, CircularMovementArgs args)
 {
     this.rigidbody      = rigidbody;
     isRigidBodyMovement = true;
     initial             = args.startingPosition;
     final                 = args.finalPosition;
     pivot                 = args.referencePivot;
     movementTime          = args.time;
     this.degree           = args.degree;
     movementStacked       = args.stacked;
     this.attemptMerge     = args.attemptMerge;
     this.onMovementFinish = args.onMovementFinish;
     if (degree < 10 || degree > 180)
     {
         throw new Exception("The degree input into a gradual circular movement must be between 10 and 180.");
     }
     else if (args.degree == 180)
     {
         degree = 179.99f;
     }
     if (QVectorCalculations.Vector3MathfApproximately(initial, final))
     {
         throw new Exception("The input starting and ending vectors cannot be the same!");
     }
     if (QVectorCalculations.Vector3Colinear(initial, initial, pivot))
     {
         throw new Exception("The reference pivot, starting position, and the final position cannot be colinear!");
     }
     this.degree       = degree * Mathf.Deg2Rad;
     this.isWorldSpace = args.isWorldSpace;
     movedObject       = rigidbody.gameObject;
     this.onFramePass  = args.onFramePass;
 }
 /// <summary>
 /// Initializes the circular movement
 /// </summary>
 /// <param name="rigidbody"> The rigidbody to be moved. </param>
 /// <param name="startingPosition"> The starting position. If set to any other position than that of the gameobject, the gameobject will be moved to that position when the movement starts. </param>
 /// <param name="finalPosition"> The position the gameobject will be moving towards. This may not be the same as the starting point. </param>
 /// <param name="time"> The time it shall take for the movement to finish. </param>
 /// <param name="stacked"> Defines whether the gradual movement should be stacked along with a series of movements; or only start when a series of movements has finished and define its own series of movements upon which other movements may stack. </param>
 /// <param name="referencePivot"> The reference point. The center of the circle will be between the line formed by the start and end points and a plane defined by this point. THIS POINT MAY NOT BE COLINEAR WITH THE START AND END POINTS </param>
 /// <param name="degree"> how many degrees of the constructed circle the movement will comprise. This value must be between 10 and 180 </param>
 /// <param name="attemptMerge"> whether this movement should be tried to be merged with other movements. </param>
 /// <param name="isWorldSpace">  Defines whether the transformations influenced by this movement is to be done in world space or local space. Very different movements may thus be achieved. </param>
 /// <param name="onMovementFinish"> A function that is called when the movement finished, with the boolean indicating whether the movement finished or not. This function will not be called in scene changes. </param>
 /// <param name="onFramePass"> A function that is called each frame a movement takes place. The rigidbody passed in will be null if the object is not a rigidbody.</param>
 public QGradualCircularMovement(Rigidbody rigidbody, Vector3 startingPosition, Vector3 finalPosition, Vector3 referencePivot, float degree, float time, bool isWorldSpace = true, bool stacked = false, bool attemptMerge = false,
                                 Action <bool> onMovementFinish = null, Action <GameObject, Rigidbody, Vector3> onFramePass = null)
 {
     if (degree < 10 || degree > 180)
     {
         throw new Exception("The degree input into a gradual circular movement must be between 10 and 180.");
     }
     else if (degree == 180)
     {
         degree = 179.99f;
     }
     if (QVectorCalculations.Vector3MathfApproximately(startingPosition, finalPosition))
     {
         throw new Exception("The input starting and ending vectors cannot be the same!");
     }
     if (QVectorCalculations.Vector3Colinear(startingPosition, finalPosition, referencePivot))
     {
         throw new Exception("The reference pivot, starting position, and the final position cannot be colinear!");
     }
     isRigidBodyMovement = true;
     this.rigidbody      = rigidbody;
     initial             = startingPosition;
     final                 = finalPosition;
     pivot                 = referencePivot;
     movementTime          = time;
     this.degree           = degree * Mathf.Deg2Rad;
     movementStacked       = stacked;
     this.attemptMerge     = attemptMerge;
     this.onMovementFinish = onMovementFinish;
     this.isWorldSpace     = isWorldSpace;
     movedObject           = rigidbody.gameObject;
     this.onFramePass      = onFramePass;
 }
 /// <summary>
 /// Initializes the circular movement.
 /// </summary>
 /// <param name="gameObject">The gameobject to be moved.</param>
 /// <param name="args">the arguments that define the movement.</param>
 public QGradualFullCircularMovement(GameObject gameObject, CircularMovementArgs args)
 {
     movedObject           = gameObject;
     initial               = args.startingPosition;
     final                 = args.finalPosition;
     pivot                 = args.referencePivot;
     movementTime          = args.time;
     movementStacked       = args.stacked;
     this.attemptMerge     = args.attemptMerge;
     this.onMovementFinish = args.onMovementFinish;
     if (QVectorCalculations.Vector3MathfApproximately(initial, final))
     {
         throw new Exception("The input starting and ending vectors cannot be the same!");
     }
     if (QVectorCalculations.Vector3Colinear(initial, initial, pivot))
     {
         throw new Exception("The reference pivot, starting position, and the final position cannot be colinear!");
     }
     this.isWorldSpace = args.isWorldSpace;
     this.onFramePass  = args.onFramePass;
 }
        //TODO Ability to transform already created ellipsis for reuse?

        #region Construction

        /// <summary>
        /// Initializes the circular movement
        /// </summary>
        /// <param name="gameObject"> The gameobject to be moved. </param>
        /// <param name="startingPosition"> The starting position. If set to any other position than that of the gameobject, the gameobject will be moved to that position when the movement starts. </param>
        /// <param name="finalPosition"> The position the gameobject will be moving towards. This may not be the same as the starting point. </param>
        /// <param name="time"> The time it shall take for the movement to finish. </param>
        /// <param name="stacked"> Defines whether the gradual movement should be stacked along with a series of movements; or only start when a series of movements has finished and define its own series of movements upon which other movements may stack. </param>
        /// <param name="referencePivot"> The reference point. The center of the circle will be between the line formed by the start and end points and a plane defined by this point. THIS POINT MAY NOT BE COLINEAR WITH THE START AND END POINTS </param>
        /// <param name="attemptMerge"> whether this movement should be tried to be merged with other movements. </param>
        /// <param name="isWorldSpace"> Defines whether the transformations influenced by this movement is to be done in world space or local space. Very different movements may thus be achieved. </param>
        /// <param name="onMovementFinish">  A function that is called when the movement finished, with the boolean indicating whether the movement finished PREMATURELY or not. This function will not be called in scene changes. </param>
        /// <param name="onFramePass">A function that is called each frame a movement takes place. The rigidbody passed in will be null if the object is not a rigidbody. The gameobject passed is the gameobject being moved, whereas the Vector3 that is passed is the displacement that took place in this particular frame.</param>
        public QGradualFullCircularMovement(GameObject gameObject, Vector3 startingPosition, Vector3 finalPosition, Vector3 referencePivot, float time, bool isWorldSpace = true, bool stacked = false, bool attemptMerge = false,
                                            Action <bool> onMovementFinish = null, Action <GameObject, Rigidbody, Vector3> onFramePass = null)
        {
            if (QVectorCalculations.Vector3MathfApproximately(startingPosition, finalPosition))
            {
                throw new Exception("The input starting and ending vectors cannot be the same!");
            }
            if (QVectorCalculations.Vector3Colinear(startingPosition, finalPosition, referencePivot))
            {
                throw new Exception("The reference pivot, starting position, and the final position cannot be colinear!");
            }
            movedObject           = gameObject;
            initial               = startingPosition;
            final                 = finalPosition;
            pivot                 = referencePivot;
            movementTime          = time;
            movementStacked       = stacked;
            this.attemptMerge     = attemptMerge;
            this.onMovementFinish = onMovementFinish;
            this.isWorldSpace     = isWorldSpace;
            this.onFramePass      = onFramePass;
        }