Esempio n. 1
0
        /// <summary>
        /// Adds a twist to our history.
        /// </summary>
        public void Update(SingleTwist twist)
        {
            if (m_undoMode)
            {
                // Remove from twist list.
                m_twists.RemoveAt(m_twists.Count - 1);

                // Save in our redo list.
                SingleTwist temp = twist.Clone();
                temp.ReverseTwist();
                m_redoTwists.Add(temp);
                m_undoMode = false;
                return;
            }

            if (m_redoMode)
            {
                m_redoTwists.RemoveAt(m_redoTwists.Count - 1);
                m_redoMode = false;
            }
            else
            {
                m_redoTwists.Clear();
            }

            // This block should apply to normal twists and redo twists.
            m_twists.Add(twist);
        }
Esempio n. 2
0
        /// <summary>
        /// Checks if we are an undo of another twist.
        /// </summary>
        public bool IsUndo(SingleTwist other)
        {
            if (other == null)
            {
                return(false);
            }

            SingleTwist clone = this.Clone();

            clone.ReverseTwist();
            return(clone.Compare(other));
        }
Esempio n. 3
0
        /// <summary>
        /// Transforms us into a new macro based on a different click location.
        /// </summary>
        public Macro Transform(Cell clickedCell, Vector3D clickedPoint, Puzzle puzzle, bool mouseMotionReflected)
        {
            Macro m = this.CloneAllButTwists();

            m.SetupMobius(clickedCell, clickedPoint, puzzle, mouseMotionReflected);

            // Did we have an odd number of view reflections?
            bool viewReflected = this.ViewReflected ^ m.ViewReflected;

            Isometry iso1 = new Isometry(m.Mobius, null);
            Isometry iso2 = new Isometry(this.Mobius, null);

            if (viewReflected)
            {
                iso1 = Isometry.ReflectX() * iso1;
            }
            Isometry combined = iso1.Inverse() * iso2;

            foreach (SingleTwist t in this.m_twists)
            {
                // Find the transformed twist data.
                // NOTE: We choose the one which will be closest to the origin after transformation,
                //		 which hopefully won't lead to performance problems.
                //		 I initially just used the first TwistDataForStateCalcs list item,
                //		 but that led to issues because sometimes it would get transformed
                //		 to very near the disk boundary. We'd have run out of cells to
                //		 find the correct closest, and the transformed macros got all messed up.
                TwistData tdOriginal = t.IdentifiedTwistData.TwistDataForStateCalcs
                                       .OrderBy(td => combined.Apply(td.Center).MagSquared())
                                       .First();
                Vector3D  newCenter = combined.Apply(tdOriginal.Center);
                TwistData tdNew     = puzzle.ClosestTwistingCircles(newCenter);

                SingleTwist tClone = t.Clone();
                tClone.IdentifiedTwistData = tdNew.IdentifiedTwistData;

                // If the reverse state of our transformed twist
                // has changed, we may need to reverse the new twist.
                bool reverse = tdOriginal.Reverse ^ tdNew.Reverse;
                if (reverse ^ viewReflected)                    // NOTE: Very similar to code in Renderer.
                {
                    tClone.ReverseTwist();
                }

                m.m_twists.Add(tClone);
            }

            return(m);
        }
Esempio n. 4
0
        /// <summary>
        /// Get undo rotation parameters.
        /// Calling this will set us in the "undo" state for the next rotation.
        /// Returns false if there are no more twists to undo.
        /// </summary>
        public bool GetUndoTwist(out SingleTwist twist)
        {
            twist = null;

            if (0 == m_twists.Count)
            {
                return(false);
            }

            twist = m_twists[m_twists.Count - 1].Clone();
            twist.ReverseTwist();

            m_undoMode = true;
            return(true);
        }