Example #1
0
        public void MultiplicativeOperations()
        {
            var result = CalcSimpleExpression("2 * 2");

            Assert.AreEqual(result, 4M);             // as decimal

            result = CalcSimpleExpression("2 * '2'");
            Assert.AreEqual(result, 4M);             // as decimal

            result = CalcSimpleExpression("'3'* 2");
            Assert.AreEqual(result, 6M);             // as decimal

            result = CalcSimpleExpression("2 * true");
            Assert.AreEqual(result, 2M);             // as decimal

            result = CalcSimpleExpression("4 / 2");
            Assert.AreEqual(result, 2M);             // as decimal

            result = CalcSimpleExpression("4 / 0");
            Assert.IsTrue(Infinity.IsInfinity(result));

            result = CalcSimpleExpression("4 / false");
            Assert.IsTrue(Infinity.IsInfinity(result));

            result = CalcSimpleExpression("2 / true");
            Assert.AreEqual(2M, result);             // as decimal
        }
Example #2
0
            private H3.Cell.Edge[] GenEdgesInternal(Vector3D v1, Vector3D v2, Vector3D v3, Vector3D v4)
            {
                int div = 5;
                List <H3.Cell.Edge> result = new List <H3.Cell.Edge>();

                for (int i = 0; i <= div; i++)
                {
                    Vector3D start = v1 + (v2 - v1) * i / div;
                    Vector3D end   = v3 + (v4 - v3) * i / div;
                    start.Normalize();
                    end.Normalize();

                    start = Sterographic.S3toR3(start);
                    end   = Sterographic.S3toR3(end);

                    if (Infinity.IsInfinite(start))
                    {
                        start = end * 10;
                    }
                    if (Infinity.IsInfinite(end))
                    {
                        end = start * 10;
                    }

                    result.Add(new H3.Cell.Edge(start, end));
                }
                return(result.ToArray());
            }
Example #3
0
        private static void ReflectGeodesicsRecursive(Sphere[] simplex, Circle3D[] geodesics, HashSet <Circle3D> completed)
        {
            if (0 == geodesics.Length)
            {
                return;
            }

            HashSet <Circle3D> newGeodesics = new HashSet <Circle3D>(new GyrationPlaneEqualityComparer());

            foreach (Circle3D geodesic in geodesics)
            {
                for (int m = 0; m < simplex.Length; m++)
                {
                    Sphere mirror = simplex[m];

                    Vector3D[] points = Infinity.IsInfinite(geodesic.Radius) ?
                                        new Vector3D[] { -geodesic.Normal, new Vector3D(), geodesic.Normal } :
                    geodesic.RepresentativePoints;

                    Vector3D[] reflected = points.Select(p => mirror.ReflectPoint(p)).ToArray();
                    Circle3D   newCirc   = new Circle3D(reflected[0], reflected[1], reflected[2]);

                    if (completed.Add(newCirc))
                    {
                        newGeodesics.Add(newCirc);
                    }
                }
            }

            ReflectGeodesicsRecursive(simplex, newGeodesics.ToArray(), completed);
        }
Example #4
0
        /// <summary>
        /// This transform will map z1 to Zero, z2 to One, and z3 to Infinity.
        /// http://en.wikipedia.org/wiki/Mobius_transformation#Mapping_first_to_0.2C_1.2C_.E2.88.9E
        /// If one of the zi is ∞, then the proper formula is obtained by first
        /// dividing all entries by zi and then taking the limit zi → ∞
        /// </summary>
        public void MapPoints(Complex z1, Complex z2, Complex z3)
        {
            if (Infinity.IsInfinite(z1))
            {
                A = 0;
                B = -1 * (z2 - z3);
                C = -1;
                D = z3;
            }
            else if (Infinity.IsInfinite(z2))
            {
                A = 1;
                B = -z1;
                C = 1;
                D = -z3;
            }
            else if (Infinity.IsInfinite(z3))
            {
                A = -1;
                B = z1;
                C = 0;
                D = -1 * (z2 - z1);
            }
            else
            {
                A = z2 - z3;
                B = -z1 * (z2 - z3);
                C = z2 - z1;
                D = -z3 * (z2 - z1);
            }

            Normalize();
        }
Example #5
0
        // Rotates a dodec about a vertex or edge to get a dual dodec.
        private static Dodec GetDual(Dodec dodec, Vector3D rotationPoint)
        {
            //double rot = System.Math.PI / 2;	// Edge-centered
            double rot = 4 * (-Math.Atan((2 + Math.Sqrt(5) - 2 * Math.Sqrt(3 + Math.Sqrt(5))) / Math.Sqrt(3)));                                 // Vertex-centered

            Mobius m = new Mobius();

            if (Infinity.IsInfinite(rotationPoint))
            {
                m.Elliptic(Geometry.Spherical, new Vector3D(), -rot);
            }
            else
            {
                m.Elliptic(Geometry.Spherical, rotationPoint, rot);
            }

            Dodec dual = new Dodec();

            foreach (Vector3D v in dodec.Verts)
            {
                Vector3D rotated = m.ApplyInfiniteSafe(v);
                dual.Verts.Add(rotated);
            }

            foreach (Vector3D v in dodec.Midpoints)
            {
                Vector3D rotated = m.ApplyInfiniteSafe(v);
                dual.Midpoints.Add(rotated);
            }

            return(dual);
        }
Example #6
0
        /// <summary>
        /// Generate a catenoid, then move it to a point on the hemisphere in S^3.
        /// </summary>
        private static Mesh Catenoid(double scale, Vector3D loc, double rld_height, double waist)
        {
            double h = waist * 3.5;
            //Mesh mesh = StandardCatenoid( waist, h );
            Mesh mesh = CatenoidSquared(waist, h);

            mesh.Scale(scale * rld_height * 2 / h);                     // To make the catenoid meet up with the RLD solution.

            // First move to north pole, then rotate down to the location.
            Func <Vector3D, Vector3D> transform = v =>
            {
                v = H3Models.BallToUHS(v);
                Vector3D northPole = new Vector3D(0, 0, 1);
                Vector3D axis      = loc.Cross(northPole);
                if (!axis.Normalize())  // North or south pole?
                {
                    return(v);
                }
                double anglXY = Euclidean2D.AngleToCounterClock(new Vector3D(1, 0), new Vector3D(loc.X, loc.Y));
                v.RotateXY(anglXY);
                double angleDown = loc.AngleTo(northPole);
                v.RotateAboutAxis(axis, angleDown);

                if (v.DNE || Infinity.IsInfinite(v))
                {
                    throw new System.Exception();
                }
                return(v);
            };

            mesh.Transform(transform);
            return(mesh);
        }
Example #7
0
    public static Infinity operator /(Infinity inf1, double n)
    {
        Infinity result = inf1;

        result.Number /= n;
        result.RecaculateIndex();
        return(result);
    }
Example #8
0
    public static void Remove(GameObject target)
    {
        Infinity behaviour = target.GetComponent <Infinity>();

        if (behaviour != null)
        {
            Destroy(behaviour);
        }
    }
Example #9
0
    public static Infinity operator /(Infinity inf1, Infinity inf2)
    {
        Infinity result = inf1;

        result.Number /= inf2.Number;
        result.Index  -= inf2.Index;
        result.RecaculateIndex();
        return(result);
    }
Example #10
0
    public static Infinity operator -(Infinity inf1, Infinity inf2)
    {
        Infinity result   = inf1;
        var      subIndex = result.Index - inf2.Index;
        var      t        = Math.Pow(1000.0, subIndex);

        result.Number -= inf2.Number / t;
        return(result);
    }
Example #11
0
        public bool Equals(double d1, double d2)
        {
            if (Infinity.IsInfinite(d1) && Infinity.IsInfinite(d2))
            {
                return(true);
            }

            return(Tolerance.Equal(d1, d2));
        }
Example #12
0
    public static Infinity Apply(GameObject target, float width, float height, float speed)
    {
        Infinity behaviour = target.AddComponent <Infinity>();

        behaviour.width  = width;
        behaviour.height = height;
        behaviour.speed  = speed;

        return(behaviour);
    }
Example #13
0
 private void Invoke()
 {
     if (IsCoroutine)
     {
         Infinity.DOEditorCoroutine((IEnumerator)method.Invoke(declaringObject, arguments));
     }
     else
     {
         method.Invoke(declaringObject, arguments);
     }
 }
Example #14
0
    void DisplayInfiniteAmmo()
    {
        Ammo t_ammo = LoadNewAmmo();

        t_ammo.m_NewLocalPosition = new Vector2(t_ammo.GetComponent <SpriteRenderer>().bounds.size.x * 1.5f, 0);
        m_infinitysign            = Instantiate(AssetManager.m_Instance.GetPrefab("InfinitySign")).GetComponent <Infinity>();
        m_infinitysign.transform.SetParent(m_ammunition[0].transform);
        m_infinitysign.transform.localScale    = new Vector3(1, 1);
        m_infinitysign.transform.localScale   *= m_ammunition[0].GetComponent <SpriteRenderer>().bounds.size.y / m_infinitysign.GetComponent <SpriteRenderer>().bounds.size.y;
        m_infinitysign.transform.localPosition = new Vector2(t_ammo.GetComponent <SpriteRenderer>().bounds.size.x + m_infinitysign.GetComponent <SpriteRenderer>().bounds.size.x / 2f, 0);
    }
Example #15
0
        public int GetHashCode(double d)
        {
            if (Infinity.IsInfinite(d))
            {
                return(double.PositiveInfinity.GetHashCode());
            }

            double inverse  = 1 / m_tolerance;
            int    decimals = (int)Math.Log10(inverse);

            return(Math.Round(d, decimals).GetHashCode());
        }
Example #16
0
    public void addWeaponAmmo(int num)
    {
        if (currentWeapon.AmmoCount != Infinity.InfinityValue())
        {
            currentWeapon.AmmoCount += num;

            if (parentGame != null)
            {
                parentGame.PlayerUpdateAmmoCount(playerNumber, currentWeapon.AmmoCount);
            }
        }
    }
Example #17
0
        // https://plus.google.com/u/0/117663015413546257905/posts/BnCEkdNiTZ2
        public static void TwinDodecs()
        {
            Tiling       tiling = new Tiling();
            TilingConfig config = new TilingConfig(5, 3);

            tiling.GenerateInternal(config, Polytope.Projection.VertexCentered);                // Vertex-centered makes infinities tricky

            Dodec dodec = new Dodec();

            foreach (Tile tile in tiling.Tiles)
            {
                foreach (Segment seg in tile.Boundary.Segments)
                {
                    Vector3D p1 = seg.P1, p2 = seg.P2;
                    if (Infinity.IsInfinite(p1))
                    {
                        p1 = Infinity.InfinityVector;
                    }
                    if (Infinity.IsInfinite(p2))
                    {
                        p2 = Infinity.InfinityVector;
                    }

                    dodec.Verts.Add(p1);
                    dodec.Verts.Add(p2);
                    dodec.Midpoints.Add(Halfway(p1, p2));
                }
            }

            // Now recursively add more vertices.
            HashSet <Vector3D> allVerts = new HashSet <Vector3D>();

            foreach (Vector3D v in dodec.Verts)
            {
                allVerts.Add(v);
            }
            RecurseTwins(allVerts, dodec, 0);

            using (StreamWriter sw = File.CreateText("dual_dodecs_points_sphere.pov"))
            {
                foreach (Vector3D vert in allVerts)
                {
                    Vector3D onSphere = Sterographic.PlaneToSphereSafe(vert);
                    sw.WriteLine(PovRay.Sphere(new Sphere()
                    {
                        Center = onSphere, Radius = 0.01
                    }));

                    //if( !Infinity.IsInfinite( vert ) )
                    //	sw.WriteLine( PovRay.Sphere( new Sphere() { Center = vert, Radius = 0.01 } ) );
                }
            }
        }
Example #18
0
        /// <summary>
        /// Applies a Mobius transformation to a quaternion with a zero k component (handled as a vector).
        /// The complex Mobius coefficients are treated as quaternions with zero j,k values.
        /// This is also infinity safe.
        /// </summary>
        public Vector3D ApplyToQuaternion(Vector3D q)
        {
            if (Infinity.IsInfinite(q))
            {
                return(ApplyToInfinite());                // Is this ok?
            }
            Vector3D a = Vector3D.FromComplex(A);
            Vector3D b = Vector3D.FromComplex(B);
            Vector3D c = Vector3D.FromComplex(C);
            Vector3D d = Vector3D.FromComplex(D);

            return(DivideQuat(MultQuat(a, q) + b, MultQuat(c, q) + d));
        }
    /*Functions To Alter ammo count */
    public void removeWeaponAmmo(int num)
    {
        if (photonView.isMine)
        {
            if (currentWeapon.AmmoCount != Infinity.InfinityValue())
            {
                currentWeapon.AmmoCount -= num;

                if (parentGame != null)
                {
                    parentGame.PlayerUpdateAmmoCount(playerNumber, currentWeapon.AmmoCount);
                }
            }
        }
    }
Example #20
0
 /*Functions To Alter ammo count */
 public void removeWeaponAmmo(int num)
 {
     if (currentWeapon.AmmoCount != Infinity.InfinityValue())
     {
         currentWeapon.AmmoCount -= num;
         if (currentWeapon.AmmoCount == 0)
         {
             currentWeapon = new Weapon();
         }
         if (parentGame != null)
         {
             parentGame.PlayerUpdateAmmoCount(playerNumber, currentWeapon.AmmoCount);
         }
     }
 }
Example #21
0
        public Vector3D ApplyInfiniteSafe(Vector3D z)
        {
            if (Infinity.IsInfinite(z))
            {
                return(ApplyToInfinite());
            }

            Vector3D result = Apply(z);

            if (Infinity.IsInfinite(result))
            {
                return(Infinity.InfinityVector);
            }

            return(result);
        }
Example #22
0
    void ClearAmmo()
    {
        int t_ammocount = m_ammunition.Count;

        for (int i = 0; i < t_ammocount; i++)
        {
            Destroy(m_ammunition[0].gameObject);
            m_ammunition.RemoveAt(0);
        }

        if (m_infinitysign != null)
        {
            Destroy(m_infinitysign.gameObject);
            m_infinitysign = null;
        }
    }
Example #23
0
        public static void Run()
        {
            Zero.Check("Zero == 0.", value => value == 0);
            One.Check("One == 1.", value => value == 1);
            Letter.Check("Letter is letter.", char.IsLetter);
            Digit.Check("Digit is digit.", char.IsDigit);
            ASCII.Check("ASCII is ascii.", value => value < 128);
            Letter.String(Range(100)).Check("String(Letter) is letter.", value => value.Length <= 100 && value.All(char.IsLetter));
            Digit.String(Range(100)).Check("String(Digit) is digit.", value => value.Length <= 100 && value.All(char.IsDigit));
            ASCII.String(Range(100)).Check("String(ASCII) is ascii.", value => value.Length <= 100 && value.All(value => value < 128));
            Infinity.Check("Infinity is infinity.", float.IsInfinity);
            String(Range(100)).Bind(value => Constant(value).Map(constant => (value, constant))).Check("Constant is constant.", pair => pair.value == pair.constant);
            Enumeration().Check("Enumeration is enum.", value => value is Enum);

            All(Zero).Check("All(1) produces arrays of length 1.", values => values.Length == 1 && values.All(value => value == 0));
            All(Zero, Zero).Check("All(2) produces arrays of length 2.", values => values.Length == 2 && values.All(value => value == 0));
            All(Zero, Zero, Zero).Check("All(3) produces arrays of length 3.", values => values.Length == 3 && values.All(value => value == 0));
            Zero.Map(Constant).Repeat(Range(100)).Bind(constants => All(constants).Map(values => (values, constants)))
            .Check("All(x) produces arrays of length x.", pair => pair.values.Length == pair.constants.Length);
            Any(Zero, One).Check("Any(Zero, One) chooses from its inputs.", value => value == 0 || value == 1);
            Any(0, 1).Repeat(100).Check("Any(0, 1).Repeat produces both values.", values => values.Contains(0) && values.Contains(1));
            Range(-10, 10).Check("Range(-10, 10) is in range.", value => value >= -10 && value <= 10);
            Range('a', 'z').Check("Range('a', 'z') is in range.", value => value >= 'a' && value <= 'z');
            Range(-1f, 1f).Check("Range(-1f, 1f) is in range.", value => value >= -1f && value <= 1f);
            Zero.Repeat(Range(100)).Check("Repeat(100) is in range.", values => values.Length <= 100);
            Integer.Filter(value => value % 2 == 0).Check("Filter filters for even numbers.", value => value % 2 == 0);
            Rational.Filter(value => value >= 0f).Check("Filter filters for positive numbers.", value => value >= 0f);

            Types.Concrete.Factory().Check("Factory produces non-null values.", value => value is not null);
            Types.Abstract.Check("Types.Abstract is abstract.", type => type.IsAbstract);
            Types.Interface.Check("Types.Interface is interface.", type => type.IsInterface);
            Types.Reference.Check("Types.Reference is class.", type => type.IsClass);
            Types.Value.Check("Types.Value is value type.", type => type.IsValueType);
            Types.Array.Check("Types.Array is array.", type => type.IsArray);
            Types.Pointer.Check("Types.Pointer is pointer.", type => type.IsPointer);
            Types.Primitive.Check("Types.Primitive is primitive.", type => type.IsPrimitive);
            Types.Enumeration.Check("Types.Enumeration is enum.", type => type.IsEnum);
            Types.Flags.Check("Types.Flags is flags.", type => type.IsEnum && type.IsDefined(typeof(FlagsAttribute), true));
            Types.Default.Check("Types.Default has default constructor.", type => Activator.CreateInstance(type)?.GetType() == type);
            Types.Definition.Check("Types.Definition is generic type definition.", type => type.IsGenericTypeDefinition);
            Types.Definition.Make().Check("Types.Definition is constructed generic type.", type => type.IsConstructedGenericType);
            Types.Enumeration.Bind(type => Enumeration(type).Map(value => (type, value)))
            .Check("Enumeration(type) produces values of the same type.", pair => pair.type == pair.value.GetType());
            Types.Type.Bind(type => Types.Derived(type).Map(derived => (derived, type)))
            .Check("Types.Derived is derived.", pair => pair.derived.Is(pair.type));
        }
 public void ChangeAmmoCount(int number, int textNumber)
 {
     if (!(textNumber == Infinity.InfinityValue()))
     {
         if (number < 100)
         {
             playersInfoUI[number].ChangeAmmoCount(textNumber.ToString(), defaultTextFontSize);
         }
         else
         {
             Debug.Log("Ammo text is too large");
         }
     }
     else
     {
         playersInfoUI[number].ChangeAmmoCount("∞", largerTextFontSize);
     }
 }
        void Start()
        {
            FindComponent();

            if (ISILocalization.LoadIfNotInScene())
            {
                Infinity.When(() => ISILocalization.IsInitialized, _OnLanguageChanged);
            }

            if (LocalizedStrings == null)
            {
                LocalizedStrings = new List <LocalizedString>();
            }

            if (!LocalizedStrings.Contains(this))
            {
                LocalizedStrings.Add(this);
            }
        }
Example #26
0
        private static void ProjectAndSave(List <Circle3D> circlesOnUnitSphere)
        {
            List <Circle3D> projected = new List <Circle3D>();

            foreach (Circle3D c in circlesOnUnitSphere)
            {
                Vector3D[] pp = c.RepresentativePoints.Select(p => Sterographic.SphereToPlane(p)).ToArray();

                Circle3D cProj = new Circle3D(pp[0], pp[1], pp[2]);
                if (Infinity.IsInfinite(cProj.Radius))
                {
                    continue;
                }
                cProj.Color = c.Color;
                projected.Add(cProj);
            }

            SaveToBmp(projected);
        }
Example #27
0
        void Start()
        {
            if (type == SpriteComponentType.Image)
            {
                image = GetComponent <Image>();
                if (image == null)
                {
                    Debugger.LogError("There is no Image component attached to this GameObject", gameObject);
                    return;
                }
            }
            else
            {
                spriteRenderer = GetComponent <SpriteRenderer>();
                if (spriteRenderer == null)
                {
                    Debugger.LogError("There is no SpriteRenderer component attached to this GameObject", gameObject);
                    return;
                }
            }

            if (ISILocalization.LoadIfNotInScene())
            {
                Infinity.When(() => ISILocalization.IsInitialized, _OnLanguageChanged);
            }

            if (LocalizedSprites == null)
            {
                LocalizedSprites = new List <LocalizedSprite>();
            }

            if (!LocalizedSprites.Contains(this))
            {
                LocalizedSprites.Add(this);
            }
        }
Example #28
0
    private IEnumerator ScenarioExecution()
    {
        switch (step)
        {
        case Step.Attraction: {
            if (OrbitController.Instance != null)
            {
                OrbitController.Instance.Apply(p.camView);
            }

            yield return(null);

            break;
        }

        case Step.AttractionUpDown: {
            m_AttractionUpDownCoroutine = StartCoroutine(AttractionUpDownCoroutine());

            step     = Step.Idle;
            parallel = Parallel.LerpToSeparation;
            break;
        }

        case Step.SettleCohesion: {
            Tween.DestroyAll(flock.originTarget.gameObject);
            //Scene_Camera.Instance.SmoothLookAt ( flock.originTarget, 2f, false );
            flock.TransitionToPreset(p.fishSchool1Preset, p.fishSchool1TransitionDuration);
            ConvertBoidsToTemplate(p.fish1Template, p.fishSchool1TransitionDuration);

            float       transitionDuration = p.fishSchool1TransitionDuration * .5f;
            IEnumerator transition         = GenericPresetsUtil.TransitionFromToCoroutine(
                null, p.underwaterOn, p.underwaterMaterial,
                transitionDuration,
                null, null
                );

            StartCoroutine(transition);

            IEnumerator transitionBkg = GenericPresetsUtil.TransitionFromToCoroutine(
                null, p.backgroundWater, p.backgroundMaterial,
                transitionDuration,
                null, null
                );

            StartCoroutine(transitionBkg);

            step     = Step.Idle;
            parallel = Parallel.Idle;
            break;
        }

        case Step.School2: {
            if (m_AttractionUpDownCoroutine != null)
            {
                StopCoroutine(m_AttractionUpDownCoroutine);
            }

            flock.TransitionToPreset(p.fishSchool2Preset, p.fishSchool2TransitionDuration);
            flock.CreateBoidsOverDuration(p.additionalSchool2Pattern, p.fishSchool2TransitionDuration);
            Infinity.Apply(flock.originTarget.gameObject, 10f, 6f, .01f);

            step = Step.Idle;
            break;
        }

        case Step.Birds: {
            Infinity.Remove(flock.originTarget.gameObject);

            StartCoroutine(flock.RandomOriginFromBoidsCoroutine(1f));
            OrbitController.Instance.orbitTarget        = flock.originTarget;
            OrbitController.Instance.rotationalDamping *= .2f;

            flock.TransitionToPreset(p.birdsFlock1Preset, p.birdsFlock1TransitionDuration);
            ConvertBoidsToTemplate(p.birds1Template, p.birdsFlock1TransitionDuration);
            flock.CreateBoidsOverDuration(p.additionalSchool2Pattern, p.birdsFlock1TransitionDuration);

            float       transitionDuration = p.birdsFlock1TransitionDuration * .5f;
            IEnumerator transition         = GenericPresetsUtil.TransitionFromToCoroutine(
                null, p.skySunset, p.underwaterMaterial,
                transitionDuration,
                null, null
                );

            StartCoroutine(transition);

            IEnumerator transitionBkg = GenericPresetsUtil.TransitionFromToCoroutine(
                null, p.backgroundSkySunset, p.backgroundMaterial,
                transitionDuration,
                null, null
                );

            StartCoroutine(transitionBkg);

            step = Step.Idle;
            break;
        }

        case Step.Exit: {
            Director.Instance.LoadNextScene();
            break;
        }
        }
    }
Example #29
0
        // CHEAT! (would be better to do a geometrical construction)
        // We are going to iterate to the starting point that will make all edge lengths the same.
        public static Vector3D IterateToStartingPoint(HoneycombDef?def, int[] activeMirrors, Simplex simplex)
        {
            if (activeMirrors.Length == 1)
            {
                return(simplex.Verts[activeMirrors[0]]);
            }

            // We are minimizing the output of this function,
            // because we want all edge lengths to be as close as possible.
            // Input vector should be in the Ball Model.
            Func <Vector3D, double> diffFunc = v =>
            {
                List <double> lengths = new List <double>();
                for (int i = 0; i < activeMirrors.Length; i++)
                {
                    Vector3D reflected = simplex.ReflectInFacet(v, activeMirrors[i]);
                    lengths.Add(H3Models.Ball.HDist(v, reflected));
                }

                double result  = 0;
                double average = lengths.Average();
                foreach (double length in lengths)
                {
                    result += Math.Abs(length - average);
                }
                if (Infinity.IsInfinite(result))
                {
                    result = double.PositiveInfinity;
                }
                return(result);
            };

            // So that we can leverage Euclidean barycentric coordinates, we will first convert our simplex to the Klein model.
            // We will need to take care to properly convert back to the Ball as needed.
            Vector3D[] kleinVerts = simplex.Verts.Select(v => HyperbolicModels.PoincareToKlein(v)).ToArray();
            if (def != null)
            {
                HoneycombDef d = def.Value;
                Geometry     vertexGeometry = Geometry2D.GetGeometry(d.Q, d.R);
                if (vertexGeometry == Geometry.Hyperbolic)
                {
                    kleinVerts[3] = SimplexCalcs.VertexPointKlein(d.P, d.Q, d.R);
                }
            }

            // Normalizing barycentric coords amounts to making sure the 4 coords add to 1.
            Func <Vector3D, Vector3D> baryNormalize = b =>
            {
                return(b / (b.X + b.Y + b.Z + b.W));
            };

            // Bary Coords to Euclidean
            Func <Vector3D[], Vector3D, Vector3D> baryToEuclidean = (kv, b) =>
            {
                Vector3D result =
                    kv[0] * b.X + kv[1] * b.Y + kv[2] * b.Z + kv[3] * b.W;
                return(result);
            };

            // Our starting barycentric coords (halfway between all active mirrors).
            Vector3D bary = new Vector3D();

            foreach (int a in activeMirrors)
            {
                bary[a] = 0.5;
            }
            bary = baryNormalize(bary);

            // For each iteration, we'll shrink this search offset.
            // NOTE: The starting offset and decrease factor I'm using don't guarantee convergence,
            // but it seems to be working pretty well (even when varying these parameters).
            //double searchOffset = 1.0 - bary[activeMirrors[0]];
            //double searchOffset = bary[activeMirrors[0]];
            double factor       = 1.5;          // Adjusting this helps get some to converge, e.g. 4353-1111
            double searchOffset = bary[activeMirrors[0]] / factor;

            double min        = double.MaxValue;
            int    iterations = 1000;

            for (int i = 0; i < iterations; i++)
            {
                min = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, bary)));
                foreach (int a in activeMirrors)
                {
                    Vector3D baryTest1 = bary, baryTest2 = bary;
                    baryTest1[a] += searchOffset;
                    baryTest2[a] -= searchOffset;
                    baryTest1     = baryNormalize(baryTest1);
                    baryTest2     = baryNormalize(baryTest2);

                    double t1 = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, baryTest1)));
                    double t2 = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, baryTest2)));
                    if (t1 < min)
                    {
                        min  = t1;
                        bary = baryTest1;
                    }
                    if (t2 < min)
                    {
                        min  = t2;
                        bary = baryTest2;
                    }
                }

                if (Tolerance.Equal(min, 0.0, 1e-14))
                {
                    System.Console.WriteLine(string.Format("Converged in {0} iterations.", i));
                    break;
                }

                searchOffset /= factor;
            }

            if (!Tolerance.Equal(min, 0.0, 1e-14))
            {
                System.Console.WriteLine("Did not converge: " + min);

                // Be a little looser before thrown an exception.
                if (!Tolerance.Equal(min, 0.0, 1e-12))
                {
                    System.Console.ReadKey(true);
                    //throw new System.Exception( "Boo. We did not converge." );
                    return(Vector3D.DneVector());
                }
            }

            Vector3D euclidean = baryToEuclidean(kleinVerts, bary);

            return(HyperbolicModels.KleinToPoincare(euclidean));
        }
Example #30
0
 public static Texture2D ColorToTex(string hexcol, int width, int height)
 {
     return(ColorToTex(Infinity.HexToColor(hexcol), width, height));
 }