示例#1
0
        /// <summary>
        /// Allow a hyperbolic transformation using an absolute offset.
        /// offset is specified in the respective geometry.
        /// </summary>
        public void Hyperbolic2(Geometry g, Complex fixedPlus, Complex point, double offset)
        {
            // To the origin.
            Mobius m = new Mobius();

            m.Isometry(g, 0, fixedPlus * -1);
            double eRadius = m.Apply(point).Magnitude;

            double scale = 1;

            switch (g)
            {
            case Geometry.Spherical:
                double sRadius = Spherical2D.e2sNorm(eRadius);
                sRadius += offset;
                scale    = Spherical2D.s2eNorm(sRadius) / eRadius;
                break;

            case Geometry.Euclidean:
                scale = (eRadius + offset) / eRadius;
                break;

            case Geometry.Hyperbolic:
                double hRadius = DonHatch.e2hNorm(eRadius);
                hRadius += offset;
                scale    = DonHatch.h2eNorm(hRadius) / eRadius;
                break;
            }

            Hyperbolic(g, fixedPlus, scale);
        }
示例#2
0
        public void AnimationSections(Settings config)
        {
            HoneycombDef imageData = new HoneycombDef(config.P, config.Q, config.R);
            int          p = imageData.P, q = imageData.Q, r = imageData.R;

            string filename = imageData.FormatFilename();

            Sphere[] mirrors = SimplexCalcs.Mirrors(p, q, r);
            double   bounds  = 1.0;          //config.UhsBoundary.Bounds;

            bounds = 9.0;

            // Calculate the color scale.
            int size = 200;

            CoxeterImages.Settings settings = new CoxeterImages.Settings()
            {
                Honeycomb = imageData,
                Width     = size,
                Height    = size,
                Bounds    = bounds,
                Mirrors   = mirrors,
                FileName  = imageData.FormatFilename(),
            };

            CoxeterImages imageCalculator = new CoxeterImages();

            //imageCalculator.AutoCalcScale( settings );
            if (settings.ColorScaling < 1)
            {
                settings.ColorScaling = 15;
            }
            settings.ColorScaling = 11;

            Program.Log("\nGenerating sections...");
            size              = 500;
            settings.Width    = size;
            settings.Height   = size;
            settings.FileName = filename;

            double max = Spherical2D.e2sNorm(15);
            double min = Spherical2D.e2sNorm(1.0 / 15);

            DonHatch.e2hNorm(max);
            int    numSteps = 1800;          // 1 minute
            double step     = (max - min) / numSteps;

            for (int i = 0; i < 1; i++)
            {
                Program.Log("\nSection " + i);
                imageCalculator.m_z = 1.0 / 0.5;
                Spherical2D.s2eNorm(min + step * i);
                DonHatch.h2eNorm(step * i);
                settings.FileName = string.Format("533_{0:D4}.png", i);
                imageCalculator.GenImage(settings);
            }
        }
示例#3
0
        /// <summary>
        /// Equally subdivides a segment with a startpoint at the origin, in the respective geometry.
        /// </summary>
        private static Vector3D[] SubdivideRadialInGeometry(Segment radial, int divisions, Geometry g)
        {
            List <Vector3D> result = new List <Vector3D>();

            if (radial.Type != SegmentType.Line)
            {
                Debug.Assert(false);
                return(result.ToArray());
            }

            switch (g)
            {
            case Geometry.Spherical:
            {
                double eLength   = radial.Length;
                double sLength   = Spherical2D.e2sNorm(eLength);
                double divLength = sLength / divisions;

                for (int i = 0; i <= divisions; i++)
                {
                    double temp = Spherical2D.s2eNorm(divLength * i);
                    result.Add(radial.P2 * temp / eLength);
                }

                break;
            }

            case Geometry.Euclidean:
                return(radial.Subdivide(divisions));

            case Geometry.Hyperbolic:
            {
                double eLength   = radial.Length;
                double hLength   = DonHatch.e2hNorm(eLength);
                double divLength = hLength / divisions;

                for (int i = 0; i <= divisions; i++)
                {
                    double temp = DonHatch.h2eNorm(divLength * i);
                    result.Add(radial.P2 * temp / eLength);
                }

                break;
            }
            }

            return(result.ToArray());
        }
示例#4
0
        public static Sphere GeodesicOffset(Sphere s, double offset, bool ball = true)
        {
            Sphere offsetSphere;

            if (ball)
            {
                // Geodesic offset (ball).

                {                       // Hyperbolic honeycomb
                    double mag = s.Center.Abs() - s.Radius;
                    mag = s.IsPlane ? DonHatch.h2eNorm(offset) :
                          DonHatch.h2eNorm(DonHatch.e2hNorm(mag) - offset);

                    Vector3D closestPointToOrigin = s.IsPlane ? s.Normal : s.Center;
                    closestPointToOrigin.Normalize();
                    closestPointToOrigin *= mag;
                    offsetSphere          = H3Models.Ball.OrthogonalSphereInterior(closestPointToOrigin);

                    // There are multiple ultraparallel spheres.
                    // This experiments with picking others.
                    Mobius m = new Mobius();
                    m.Isometry(Geometry.Hyperbolic, 0, new Vector3D(0, -0.2));
                    //H3Models.TransformInBall2( offsetSphere, m );
                }

                {                       // Spherical honeycomb
                                        //offset *= -1;
                    double mag = -s.Center.Abs() + s.Radius;
                    Spherical2D.s2eNorm(Spherical2D.e2sNorm(mag) + offset);

                    offsetSphere         = s.Clone();
                    offsetSphere.Radius += offset * 10;
                }
            }
            else
            {
                // Geodesic offset (UHS).
                // XXX - not scaled right.
                offsetSphere         = s.Clone();
                offsetSphere.Radius += offset;
            }

            return(offsetSphere);
        }