Esempio n. 1
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. 2
0
        /// <summary>
        /// Get a distribution of points on a sphere.
        /// The points are the vertices of a geodesic dome.
        /// </summary>
        private static Vector3D[] SpherePoints()
        {
            List <Vector3D> spherePoints = new List <Vector3D>();
            TilingConfig    config       = new TilingConfig(3, 5);
            Tiling          tiling       = new Tiling();

            tiling.GenerateInternal(config);

            Tile baseTile = tiling.Tiles.First();

            Vector3D[] templateTextureCoords = TextureHelper.TextureCoords(baseTile.Boundary, Geometry.Spherical, doGeodesicDome: true);
            foreach (Tile tile in tiling.Tiles)
            {
                Isometry isom = new Isometry();
                isom.CalculateFromTwoPolygons(baseTile, tile, Geometry.Spherical);
                Vector3D[] textureCoords = Isometry.TransformVertices(templateTextureCoords, isom.Inverse());
                spherePoints.AddRange(textureCoords);
            }

            return(spherePoints.Select(p => H3Models.UHSToBall(p)).Distinct().ToArray());
        }