Ejemplo n.º 1
0
        private static Isometry SetupIsometry(Cell clickedCell, Vector3D clickedPoint, Puzzle puzzle)
        {
            int      p            = puzzle.Config.P;
            Geometry g            = puzzle.Config.Geometry;
            Isometry cellIsometry = clickedCell.Isometry.Clone();

            // Take out reflections.
            // ZZZ - Figuring out how to deal with these reflected isometries was a bit painful to figure out.
            //		 I wish I had just taken more care to not have any cell isometries with reflections.
            //		 Maybe I can rework that to be different at some point.
            if (cellIsometry.Reflection != null)
            {
                cellIsometry = Isometry.ReflectX() * cellIsometry;
            }

            // Round to nearest vertex.
            Vector3D centered         = cellIsometry.Apply(clickedPoint);
            double   angle            = Euclidean2D.AngleToCounterClock(centered, new Vector3D(1, 0));
            double   angleFromZeroToP = p * angle / (2 * Math.PI);

            angleFromZeroToP = Math.Round(angleFromZeroToP, 0);
            if (p == (int)angleFromZeroToP)
            {
                angleFromZeroToP = 0;
            }
            angle = 2 * Math.PI * angleFromZeroToP / p;

            // This will take vertex to canonical position.
            Mobius rotation = new Mobius();

            rotation.Isometry(g, angle, new Complex());
            Isometry rotIsometry = new Isometry(rotation, null);

            return(rotIsometry * cellIsometry);
        }
Ejemplo n.º 2
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);
        }