Esempio n. 1
0
 public void Transform(Isometry i)
 {
     Hexagon.Transform(i);
     TestCircle.Transform(i);
     CircumCircle.Transform(i);
     Isometry *= i;
 }
Esempio n. 2
0
 public void Transform(Mobius m)
 {
     Hexagon.Transform(m);
     TestCircle.Transform(m);
     CircumCircle.Transform(m);
     Isometry *= new Isometry(m, null);
 }
Esempio n. 3
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);
        }
Esempio n. 4
0
 /// <summary>
 /// Apply an isometry to us.
 /// </summary>
 public void Transform(Isometry isometry)
 {
     foreach (Segment s in this.Segments)
     {
         s.Transform(isometry);
     }
     Center = isometry.Apply(Center);
 }
Esempio n. 5
0
 public Cell(Polygon boundary, CircleNE vertexCircle)
 {
     Boundary      = boundary;
     VertexCircle  = vertexCircle;
     Stickers      = new List <Sticker>();
     Isometry      = new Isometry();
     IndexOfMaster = -1;
     PickInfo      = new PickInfo[] { };
 }
Esempio n. 6
0
 public void Transform(Isometry i)
 {
     Boundary.Transform(i);
     foreach (Sticker s in Stickers)
     {
         s.Poly.Transform(i);
     }
     VertexCircle.Transform(i);
 }
Esempio n. 7
0
        /// <summary>
        /// Helper to do a geodesic pan.
        /// </summary>
        private void GeodesicPan(Vector3D p1, Vector3D p2)
        {
            Mobius   pan     = new Mobius();
            Isometry inverse = m_isometry.Inverse();

            p1 = inverse.Apply(p1);
            p2 = inverse.Apply(p2);
            pan.Geodesic(m_geometry, p1, p2);
            m_isometry.Mobius *= pan;
        }
Esempio n. 8
0
 /// <summary>
 /// Called to reset us (needs to be done when the puzzle changes).
 /// </summary>
 public void Reset(Geometry g)
 {
     m_geometry                 = g;
     m_isometry                 = new Isometry();
     m_rotation                 = 0;
     m_viewScale                = 1.1f;
     m_viewLookFrom3D           = new Vector3D(15, 15, 0);
     m_viewLookFrom4D           = new Vector3D(0, 0, 7);
     m_up3D                     = new Vector3D(0, 0, 1);
     RotHandler4D.Current4dView = null;
     ProjectionDistance4D       = 1.0;
     UpdateImageSpace();
 }
Esempio n. 9
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. 10
0
        public void Recenter()
        {
            if (Closest == null || !Closest.IsSlave)
            {
                return;
            }

            // Isometry which will move center tile to closest.
            Isometry recenter = Closest.Isometry.Inverse();

            // NOTE: This shouldn't be called multiple times before recalculating new center
            //		 so we safeguard against that by setting Closest to null after.
            m_isometry *= recenter;
            Closest     = null;
        }
Esempio n. 11
0
        public static void DrawPolygonSolid(Polygon p, Isometry isometry, Color color)
        {
            GL.Color3(color);
            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
            GL.Begin(BeginMode.TriangleFan);
            {
                Vector3D center = isometry.Apply(p.Center);
                GL.Vertex2(center.X, center.Y);

                Vector3D[] edgePoints = p.EdgePoints;
                for (int i = 0; i < edgePoints.Length; i++)
                {
                    Vector3D draw = isometry.Apply(edgePoints[i]);
                    GL.Vertex2(draw.X, draw.Y);
                }
            }
            GL.End();
        }
Esempio n. 12
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());
        }
Esempio n. 13
0
 public void Transform(Isometry i)
 {
     TransformInternal(i);
 }
Esempio n. 14
0
 /// <summary>
 /// Инициализирует новый экземпляр класса <see cref="PlanarCurve"/> с произвольным преобразованием.
 /// </summary>
 /// <param name="isometry"></param>
 protected PlanarCurve(Isometry isometry)
 {
     Isometry = isometry;
 }
Esempio n. 15
0
 /// <summary>
 /// Инициализирует новый экземпляр класса <see cref="PlanarCurve"/> с тождественным преобразованием.
 /// </summary>
 protected PlanarCurve()
 {
     Isometry = Isometry.Identity;
 }
Esempio n. 16
0
 public Tile()
 {
     Isometry         = new Isometry();
     EdgeIncidences   = new List <Tile>();
     VertexIndicences = new List <Tile>();
 }
Esempio n. 17
0
        /// <summary>
        /// Инициализирует новый экземпляр класса <see cref="EllipticArcCurve"/> указанными параметрами.
        /// </summary>
        /// <param name="a">Полуось параллельная оси X.</param>
        /// <param name="b">Полуось параллельная оси Y.</param>
        /// <param name="angleStart">Угол (в радианах), который измеряется против часовой стрелки, начиная от оси X и заканчивая начальной точкой дуги.</param>
        /// <param name="angleSweep">Угол (в радианах), который измеряется против часовой стрелки, начиная от значения параметра <see cref="AngleStart"/> и заканчивая конечной точкой дуги.</param>
        /// <param name="isometry">Конгруэнтное преобразование трехмерного евклидова пространства.</param>
        public EllipticArcCurve(double a, double b, double angleStart, double angleSweep, Isometry isometry)
            : base(isometry)
        {
            if (a <= 0 || b <= 0)
            {
                throw new ArgumentException("Аргументы a и b, задающие полуоси эллипса должны быть больше нуля.");
            }


            A          = a;
            B          = b;
            AngleStart = angleStart;
            AngleSweep = angleSweep;

            if (a.Equals(b))
            {
                _paramStart = angleStart;
                _paramSweep = angleSweep;
            }
            else
            {
                var sinStart = Sin(AngleStart);
                var cosStart = Cos(AngleStart);

                var angleStop = angleStart + angleSweep;

                var sinStop = Sin(angleStop);
                var cosStop = Cos(angleStop);

                _paramStart = Atan2(A * sinStart, B * cosStart);

                var paramStop = Atan2(A * sinStop, B * cosStop);
                if (AngleSweep * paramStop < 0)
                {
                    paramStop -= Sign(paramStop) * Math.Tau;
                }
                var turns = Truncate(AngleSweep / Math.Tau);
                paramStop += turns * Math.Tau;

                _paramSweep = paramStop - _paramStart;
            }
        }
Esempio n. 18
0
        public static void DrawElements(HyperbolicModel model, Vector3D[] textureCoords, Vector3D[] textureVerts, int[] elements,
                                        Isometry mouseIsometry, double textureScale)
        {
            ////////////////////// ZZZ - Use VBOs
            GL.Begin(BeginMode.Triangles);
            {
                double factor  = textureScale;
                int    skipped = 0;

                for (int i = 0; i < elements.Length; i++)
                {
                    int idx = elements[i];

                    // In Poincare model.
                    GL.TexCoord2((textureCoords[idx].X * factor + 1) / 2, (textureCoords[idx].Y * factor + 1) / 2);
                    Complex transformed = textureVerts[idx].ToComplex();
                    if (mouseIsometry != null)
                    {
                        transformed = mouseIsometry.Apply(transformed);
                    }

                    switch (model)
                    {
                    case HyperbolicModel.Poincare:
                    {
                        Vertex(transformed);
                        break;
                    }

                    case HyperbolicModel.Klein:
                    {
                        Vector3D temp = Vector3D.FromComplex(transformed);
                        Vertex(PoincareToKlein(temp));
                        break;
                    }

                    case HyperbolicModel.Pseudosphere:
                    {
                        Mobius m = new Mobius();
                        m.UpperHalfPlane();
                        Complex u   = m.Apply(transformed);
                        double  x   = u.Real;
                        double  y   = u.Imaginary;
                        double  max = 1 * System.Math.PI;
                        double  min = -1 * System.Math.PI;
                        if (0 == i % 3 && (x < min - 1 || x > max + 1 || y < 0))
                        {
                            skipped = 1;
                            continue;
                        }

                        if (skipped > 0 && skipped < 3)
                        {
                            skipped++;
                            continue;
                        }

                        skipped = 0;

                        GL.TexCoord2((textureCoords[idx].X * factor + 1) / 2, (textureCoords[idx].Y * factor + 1) / 2);

                        // Pseudosphere
                        Func <double, Complex> tractrix = new Func <double, Complex>(
                            (t) =>
                            {
                                return(new Complex(t - Math.Tanh(t), 1.0 / Math.Cosh(t)));
                            });

                        //Vector3D temp1 = Vector3D.FromComplex( u );
                        if (x < min)
                        {
                            x = min;
                        }
                        if (x > max)
                        {
                            x = max;
                        }
                        if (y < 1)
                        {
                            y = 1;
                        }
                        Vector3D temp1 = new Vector3D(x, y);

                        double   logy  = Math.Log(temp1.Y);
                        Complex  tract = tractrix(logy);
                        Vector3D temp2 = new Vector3D(
                            Math.Cos(temp1.X) * tract.Imaginary,
                            Math.Sin(temp1.X) * tract.Imaginary,
                            tract.Real);

                        GL.Vertex3(temp2.X, temp2.Y, temp2.Z);

                        //temp1 = m.Inverse().Apply( temp1 );
                        //GL.Vertex3( temp1.X, temp1.Y, temp1.Z );
                        //Vertex( temp1 );

                        break;
                    }

                    case HyperbolicModel.Hyperboloid:
                    {
                        Vector3D hyper = Sterographic.PlaneToHyperboloid(Vector3D.FromComplex(transformed));                                                    // Hyperboloid
                        GL.Vertex3(hyper.X, hyper.Y, hyper.Z);
                        break;
                    }

                    default:
                    {
                        System.Diagnostics.Debug.Assert(false);
                        break;
                    }
                    }

                    /* // PETALS
                     * int petals = 7;
                     * double newMag = transformed.Magnitude * ( 1 + 0.5 * Math.Sin( transformed.Phase * petals ) );
                     * double newPhase = transformed.Phase + ( -0.2 * newMag * Math.Pow( Math.Sin( newMag * 3 ), 1 ) * Math.Cos( transformed.Phase * petals ) );
                     * transformed = Complex.FromPolarCoordinates( newMag, newPhase );
                     *
                     * Vertex( transformed );
                     * */

                    //double mag = System.Math.Pow( transformed.Magnitude, 3 ) / transformed.Magnitude;				// nice
                    //double mag = System.Math.Pow( transformed.Magnitude - 3, 2 ) + .0;							// looks spherical

                    //double mag = transformed.Magnitude + 0.1* System.Math.Sin( transformed.Magnitude * 15 );		// Fun warping (20 is cool too)
                    //Vertex( transformed * mag );

                    /*double xmag = 1;
                     * double ymag = transformed.Imaginary + 0.1 * System.Math.Sin( transformed.Imaginary * 15 );
                     * xmag = System.Math.Abs( xmag );
                     * ymag = System.Math.Abs( ymag );
                     * Vertex( new Complex( transformed.Real * xmag, transformed.Imaginary * ymag ) );	*/

                    //Vertex( 2 / System.Math.PI * Complex.Log( ( 1 + transformed ) / ( 1 - transformed ) ) );		// Band model
                    //Vertex( Complex.Pow( transformed, 3 ) / transformed.Magnitude );								// Spikey

                    // Spiral
                    //Complex band = 2 / System.Math.PI * Complex.Log( ( 1 + transformed ) / ( 1 - transformed ) );
                    //band = new Complex( band.Real, band.Imaginary + 0.3 * System.Math.Sin( band.Real * 2 ) );
                    //band = new Complex( band.Real * .5, band.Imaginary );
                    //band += new Complex( 0, .5 );
                    //Vertex( band );

                    /*
                     * double x = band.Real;
                     * double y = band.Imaginary;
                     *
                     * double r = System.Math.Exp( x );
                     * double theta = 3*( x + y/1.75 ); */
                    //Vertex( new Complex( r * System.Math.Sin( theta ), r * System.Math.Cos( theta ) ) );			// Spiral
                }
            }
            GL.End();
        }
Esempio n. 19
0
 public override void Transform(Isometry i)
 {
     base.Transform(i);
     CenterNE = i.Apply(CenterNE);
 }
Esempio n. 20
0
 public Pants()
 {
     Hexagon  = new Polygon();
     Isometry = new Isometry();
 }
Esempio n. 21
0
 public void Transform(Isometry i)
 {
     Boundary.Transform(i);
     //Drawn.Transform( i );
     VertexCircle.Transform(i);
 }
Esempio n. 22
0
 /// <summary>
 /// Инициализирует новый экземпляр класса <see cref="EllipticArcCurve"/> указанными параметрами.
 /// </summary>
 /// <param name="radius">Радиус дуги.</param>
 /// <param name="angleSweep">Угол (в радианах), который измеряется против часовой стрелки, начиная от оси X и заканчивая конечной точкой дуги.</param>
 /// <param name="isometry">Конгруэнтное преобразование трехмерного евклидова пространства.</param>
 public EllipticArcCurve(double radius, double angleSweep, Isometry isometry)
     : this(radius, radius, 0, angleSweep, isometry)
 {
 }