예제 #1
0
        private void createFeatureEllipse(int index, CameraSpacePoint left, CameraSpacePoint right)
        {
            //calculate vectors between the reference and the left and right feature
            double leftLength  = Math.Sqrt(Math.Pow((left.X - _referencePoint.X), 2) + Math.Pow((left.Y - _referencePoint.Y), 2) + Math.Pow((left.Z - _referencePoint.Z), 2)) * 1000;
            double rightLength = Math.Sqrt(Math.Pow((right.X - _referencePoint.X), 2) + Math.Pow((right.Y - _referencePoint.Y), 2) + Math.Pow((right.Z - _referencePoint.Z), 2)) * 1000;

            //Calculates difference and scales up to 0 - 255 range (ish)
            double vectDiff = Math.Abs(leftLength - rightLength) * 50;

            if (vectDiff > 255)
            {
                vectDiff = 255;
            }

            Color featureColor = Colors.Black;

            featureColor.R = System.Convert.ToByte(vectDiff);
            featureColor.G = System.Convert.ToByte(vectDiff);
            featureColor.B = System.Convert.ToByte(vectDiff);

            for (int i = 0; i < 2; i++)
            {
                createEllipseInstance(featureColor);
            }
        }
예제 #2
0
파일: Math.cs 프로젝트: Jupotter/Lights-Out
        static public int Distance_Euclide(int x1, int y1, int x2, int y2)
        {
            int i1 = (int)SMath.Pow(SMath.Abs(x1 - x2), 2);
            int i2 = (int)SMath.Pow(SMath.Abs(y1 - y2), 2);

            return((int)SMath.Sqrt(i1 + i2));
        }
예제 #3
0
        /// <summary>
        /// Finds the intersection (a circle) between us and another sphere.
        /// Returns null if sphere centers are coincident or no intersection exists.
        /// Does not currently work for planes.
        /// </summary>
        public Circle3D Intersection(Sphere s)
        {
            if (this.IsPlane || s.IsPlane)
            {
                throw new System.NotImplementedException();
            }

            double r = s.Radius;
            double R = this.Radius;

            Vector3D diff = this.Center - s.Center;
            double   d    = diff.Abs();

            if (Tolerance.Zero(d) || d > r + R)
            {
                return(null);
            }

            double x = (d * d + r * r - R * R) / (2 * d);
            double y = Math.Sqrt(r * r - x * x);

            Circle3D result = new Circle3D();

            diff.Normalize();
            result.Normal = diff;
            result.Center = s.Center + diff * x;
            result.Radius = y;
            return(result);
        }
예제 #4
0
        public bool WasHit(Ray p_ray, double p_tMin, double p_tMax, ref HitRecord p_hitRecord)
        {
            // If the quadratic is confusing, remember that several 2s are pre-canceled out. - Comment by Matt Heimlich on 06/23/2019 @ 12:15:02
            var oc           = p_ray.Origin - Center;
            var a            = Vec3.GetDotProduct(p_ray.Direction, p_ray.Direction);
            var b            = Vec3.GetDotProduct(oc, p_ray.Direction);
            var c            = Vec3.GetDotProduct(oc, oc) - Radius * Radius;
            var discriminant = b * b - a * c;

            if (discriminant > 0)
            {
                var sqrtCache = Math.Sqrt(b * b - a * c);
                var temp      = (-b - sqrtCache) / a;
                if (temp < p_tMax && temp > p_tMin)
                {
                    p_hitRecord.T        = temp;
                    p_hitRecord.Point    = p_ray.PointAt(p_hitRecord.T);
                    p_hitRecord.Normal   = (p_hitRecord.Point - Center) / Radius;
                    p_hitRecord.Material = Material;
                    return(true);
                }
                temp = (-b + sqrtCache) / a;
                if (temp < p_tMax && temp > p_tMin)
                {
                    p_hitRecord.T        = temp;
                    p_hitRecord.Point    = p_ray.PointAt(p_hitRecord.T);
                    p_hitRecord.Normal   = (p_hitRecord.Point - Center) / Radius;
                    p_hitRecord.Material = Material;
                    return(true);
                }
            }

            return(false);
        }
예제 #5
0
        private static double DistOriginToOrthogonalSphere(double r)
        {
            // http://mathworld.wolfram.com/OrthogonalCircles.html
            double d = Math.Sqrt(1 + r * r);

            return(d - r);
        }
예제 #6
0
파일: Sf2Synth.cs 프로젝트: DotLab/Midif
            public void Set(Table table, float fc, float q)
            {
                // Console.Log("\tfilter set fc", this.fc , "->", fc, "q", this.q, "->", q);
                this.fc = fc;
                this.q  = q;

                // https://github.com/FluidSynth/fluidsynth/blob/29c668683f43e3b8b4aab0b8aa73cb02aacd6fcb/src/rvoice/fluid_iir_filter.c#L382
                // filter will defunct in 22050Hz sample rate
                float maxFc = .45f * table.sampleRate;

                if (fc > maxFc)
                {
                    fc = maxFc;
                }
                else if (fc < 5)
                {
                    fc = 5;
                }

                gain = 1.0 / Math.Sqrt(q);

                // https://github.com/FluidSynth/fluidsynth/blob/29c668683f43e3b8b4aab0b8aa73cb02aacd6fcb/src/rvoice/fluid_iir_filter.c#L278
                // previous simple bipolar lowpass is faulty when fc is large and should not be used:
                // http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/
                double omega   = Table.Pi2 * fc * table.sampleRateRecip;
                double sin     = Math.Sin(omega);
                double cos     = Math.Cos(omega);
                double alpha   = sin / (2f * q);
                double a0Recip = 1f / (1 + alpha);

                a1 = -2f * cos * a0Recip;
                a2 = (1f - alpha) * a0Recip;
                b1 = (1f - cos) * a0Recip * gain;
                b2 = b1 * .5f;
            }
예제 #7
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);
        }
예제 #8
0
        public static Vector3D SpiralToIsometric(Vector3D v, int p, int m, int n)
        {
            Complex vc = v.ToComplex();

            v = new Vector3D(Math.Log(vc.Magnitude), vc.Phase);

            Vector3D e1 = new Vector3D(0, 1);
            Vector3D e2;

            switch (p)
            {
            case 3:
                e2 = new Vector3D(); break;

            case 4:
                e2 = new Vector3D(); break;

            case 6:
                e2 = new Vector3D(); break;

            default:
                throw new System.ArgumentException();
            }

            double scale = Math.Sqrt(m * m + n * n);
            double a     = Euclidean2D.AngleToClock(new Vector3D(0, 1), new Vector3D(m, n));

            v.RotateXY(a);          // Rotate
            v *= scale;             // Scale

            v *= Math.Sqrt(2) * Geometry2D.EuclideanHypotenuse / (2 * Math.PI);
            v.RotateXY(Math.PI / 4);
            return(v);
        }
예제 #9
0
        public virtual Vector2d GetFirstDerivative(double t)
        {
            Vector2d df   = this.curve.GetFirstDerivative(t);
            double   df_x = df.X;
            double   df_y = df.Y;

            Vector2d d2f   = this.curve.GetSecondDerivative(t);
            double   d2f_x = d2f.X;
            double   d2f_y = d2f.Y;

            double n  = this.displacement.GetPosition(t);
            double dn = this.displacement.GetFirstDerivative(t);

            /*double a = df_y * df_y + df_x * df_x;
             * double sqrt_a = SysMath.Sqrt(a);
             * double b = (df_x * d2f_x + df_y * d2f_y) / a;
             *
             * double c = (n * b - dn);
             *
             * double x = df_x + (c * df_y - n * d2f_y) / sqrt_a;
             * double y = df_y - (c * df_x - n * d2f_x) / sqrt_a;
             *
             * return new Vector2d(x, y);*/

            /*UnaryFunction fdx = Derivative.Central(tt => this.GetPosition(tt).X, 1, 5);
             * UnaryFunction fdy = Derivative.Central(tt => this.GetPosition(tt).Y, 1, 5);
             * return new Vector2d(fdx(t), fdy(t));*/

            double df2 = ((df_y * df_y) + (df_x * df_x));

            double x = -((df_y) * (dn)) / SysMath.Sqrt(df2) + (n * (df_y) * (2 * (df_y) * (d2f_y) + 2 * (df_x) * (d2f_x))) / (2 * (SysMath.Sqrt(df2) * df2)) - (n * (d2f_y)) / SysMath.Sqrt(df2) + df_x;
            double y = +((df_x) * (dn)) / SysMath.Sqrt(df2) - (n * (df_x) * (2 * (df_y) * (d2f_y) + 2 * (df_x) * (d2f_x))) / (2 * (SysMath.Sqrt(df2) * df2)) + (n * (d2f_x)) / SysMath.Sqrt(df2) + df_y;

            return(new Vector2d(x, y));
        }
예제 #10
0
        /// <summary>
        /// Calculates distance/bearing between two geographic locations on Rhumb line (loxodrome)
        /// </summary>
        /// <param name="origin">origin location in geographic degrees</param>
        /// <param name="destination">destination location in geographic degrees</param>
        /// <param name="radius">radius of a geographic sphere, in kilometers</param>
        /// <remarks>radius defaults to Earth's mean radius</remarks>
        public static GeoRhumb GetRhumb(GeoPoint origin, GeoPoint destination, double radius = GeoGlobal.Earths.Radius)
        {
            origin      = origin.ToRadians();
            destination = destination.ToRadians();
            var dLat = (destination.Latitude - origin.Latitude);
            var dLon = (destination.Longitude - origin.Longitude);

            var tDestination = Math.Tan(Math.PI / 4 + destination.Latitude / 2);
            var tOrigin      = Math.Tan(Math.PI / 4 + origin.Latitude / 2);

            var dPhi = Math.Log(tDestination / tOrigin);    // E-W line gives dPhi=0
            var q    = (IsFinite(dLat / dPhi)) ? dLat / dPhi : Math.Cos(origin.Latitude);

            // if dLon over 180° take shorter Rhumb across anti-meridian:
            if (Math.Abs(dLon) > Math.PI)
            {
                dLon = dLon > 0 ? -(2 * Math.PI - dLon) : (2 * Math.PI + dLon);
            }

            var distance = Math.Sqrt(dLat * dLat + q * q * dLon * dLon) * radius;
            var bearing  = Math.Atan2(dLon, dPhi);

            return(new GeoRhumb {
                Distance = distance, Bearing = bearing.ToDegreesNormalized()
            });
        }
예제 #11
0
        /// <summary>
        /// Returns the midpoint of our polygon edge on the sphere.
        /// </summary>
        private Vector3D MidPoint(double inRadius, double faceRadius)
        {
            // Using info from:
            // http://en.wikipedia.org/wiki/Tetrahedron
            // http://eusebeia.dyndns.org/4d/tetrahedron

            // XXX - Should make this method just work in all {p,q,r} cases!

            // tet
            //double vertexToFace = Math.Acos( 1.0 / 3 );  // 338

            // icosa
            double polyCircumRadius = Math.Sin(2 * Math.PI / 5);
            double polyInRadius     = Math.Sqrt(3) / 12 * (3 + Math.Sqrt(5));

            // cube
            //double polyCircumRadius = Math.Sqrt( 3 );
            //double polyInRadius = 1;

            double vertexToFace = Math.Acos(polyInRadius / polyCircumRadius);
            double angleTemp    = Math.Acos(RBall / (inRadius + faceRadius));

            double angleToRotate = (Math.PI - vertexToFace) - angleTemp;

            angleToRotate = vertexToFace - angleTemp;

            Vector3D zVec = new Vector3D(0, 0, 1);

            zVec.RotateAboutAxis(new Vector3D(0, 1, 0), angleToRotate);
            return(zVec);
        }
예제 #12
0
        }         //SplitIntoComplex

        static int NormalizeArray(double[,] result)
        {
            double max            = double.NegativeInfinity;
            int    maxIndex       = 0;
            int    longIndexBound = result.GetUpperBound(1);

            for (var index = 0; index <= longIndexBound; ++index)
            {
                double re       = result[0, index];
                double im       = result[1, index];
                double absValue = Math.Sqrt(re * re + im * im);
                if (absValue > max)
                {
                    max      = absValue;
                    maxIndex = index;
                }         //if
            }             //loop
            for (var reimIndex = 0; reimIndex <= 1; ++reimIndex)
            {
                for (var index = 0; index <= longIndexBound; ++index)
                {
                    result[reimIndex, index] /= max;
                }
            }
            return(maxIndex);
        }         //NormalizeArray
예제 #13
0
        // In hyperboloid model
        public static Vector3D PlaneDualPoint(Geometry g, Vector3D planeKlein)
        {
            if (g != Geometry.Hyperbolic)
            {
                throw new System.NotImplementedException();
            }

            if (Math.Abs(planeKlein.W) < 1e-7)
            {
                return(new Vector3D(planeKlein.X, planeKlein.Y, 0.0));
            }

            double inv = 1.0 / planeKlein.W;
            //Vector3D dual = new Vector3D( planeKlein.X * inv, planeKlein.Y * inv, planeKlein.Z * inv, 1.0 );
            Vector3D dual = new Vector3D(planeKlein.X * inv, planeKlein.Y * inv, 1.0);                  // Turn into 2D, would be nice to be more general.

            //NormalizeInGeometry( g, ref dual );
            // Ugh, sign convention of function above messing me up.
            System.Func <Vector3D, Vector3D> lorentzNormalize = v =>
            {
                double normSquared = Math.Abs(LorentzDot(v, v));
                double norm        = Math.Sqrt(normSquared);
                v /= norm;
                return(v);
            };

            dual = lorentzNormalize(dual);

            return(dual);
        }
예제 #14
0
        // The Lanczos approximation, should only be good for z >= 0.5,
        // but we get the right answers anyway.
        private static double gamma(double z)
        {
            double[] p = new double[8]
            {
                676.5203681218851,
                -1259.1392167224028,
                771.32342877765313,
                -176.61502916214059,
                12.507343278686905,
                -0.13857109526572012,
                9.9843695780195716e-6,
                1.5056327351493116e-7
            };
            z -= 1.0;
            double x = 0.99999999999980993;             // Unnecessary precision

            for (int i = 0; i < 8; i++)
            {
                double pval = p[i];
                x += pval / (z + i + 1);
            }
            double t = z + 8.0 - 0.5;

            return(Math.Sqrt(2.0 * Math.PI) * Math.Pow(t, z + 0.5) * Math.Exp(-t) * x);
        }
예제 #15
0
파일: Plane.cs 프로젝트: truongascii/Win2D
        public static Plane CreateFromVertices(Vector3 point1, Vector3 point2, Vector3 point3)
        {
            Plane result;

            float ax = point2.X - point1.X;
            float ay = point2.Y - point1.Y;
            float az = point2.Z - point1.Z;

            float bx = point3.X - point1.X;
            float by = point3.Y - point1.Y;
            float bz = point3.Z - point1.Z;

            // N=Cross(a,b)
            float nx = ay * bz - az * by;
            float ny = az * bx - ax * bz;
            float nz = ax * by - ay * bx;

            // Normalize(N)
            float ls      = nx * nx + ny * ny + nz * nz;
            float invNorm = 1.0f / (float)SM.Sqrt((double)ls);

            result.Normal.X = nx * invNorm;
            result.Normal.Y = ny * invNorm;
            result.Normal.Z = nz * invNorm;

            // D = - Dot(N, point1)
            result.D = -(result.Normal.X * point1.X + result.Normal.Y * point1.Y + result.Normal.Z * point1.Z);

            return(result);
        }
예제 #16
0
        private static H3.Cell.Edge[] ParameterizedFibers(Complex z)
        {
            List <H3.Cell.Edge> fibers = new List <H3.Cell.Edge>();

            double   scale = 0.1;
            Vector3D v1    = new Vector3D(0, -1);            // -i
            Vector3D v2    = Vector3D.FromComplex(z);

            int count = (int)Math.Round(Math.Sqrt(NumFibers), 0);

            for (int i = -count / 2; i < count / 2; i++)
            {
                for (int j = 1; j < count; j++)         // dilations should remain positive.
                {
                    double t1 = scale * i;
                    double t2 = scale * j;

                    // Apply the dilation first.
                    Vector3D _v1 = v1;
                    Vector3D _v2 = v2;
                    _v1   *= t2;
                    _v2   *= t2;
                    _v1.X += t1;
                    _v2.X += t1;

                    fibers.Add(new H3.Cell.Edge(
                                   H3Models.UHSToBall(_v1),
                                   H3Models.UHSToBall(_v2)));
                }
            }

            return(fibers.ToArray());
        }
예제 #17
0
        /// <summary>
        /// Gets fibers for the only fibration with parallel (vs. ultraparallel) fibers.
        /// Returns result in the ball model.
        /// </summary>
        private static H3.Cell.Edge[] ParallelFibers()
        {
            List <H3.Cell.Edge> fibers = new List <H3.Cell.Edge>();

            double scale = 0.3;

            // Just a grid of vertical fibers.
            // We could do any kind of grid we want here really (square, hexagonal, random...)
            // Each would likely produce different results.
            // It'd be nice to figure out how to space out the results near the north pole.

            int count = (int)Math.Round(Math.Sqrt(NumFibers), 0);

            for (int i = -count / 2; i < count / 2; i++)
            {
                for (int j = -count / 2; j < count / 2; j++)
                {
                    //double off1 = Math.Pow( scale*i, 3 );
                    //double off2 = Math.Pow( scale*j, 3 );
                    double off1 = scale * i;
                    double off2 = scale * j;

                    Vector3D v1 = new Vector3D(off1, off2);
                    Vector3D v2 = new Vector3D(double.PositiveInfinity, 1);

                    // Don't use Infinity.InfinityVector, because we want to distiguish this point as being on the boundary.
                    fibers.Add(new H3.Cell.Edge(
                                   H3Models.UHSToBall(v1),
                                   H3Models.UHSToBall(v2)));
                }
            }

            return(fibers.ToArray());
        }
예제 #18
0
        /// <summary>
        /// Helper to construct some points we need for calculating simplex facets for a {p,q,r} honeycomb.
        /// </summary>
        private static void TilePoints(int p, int q, out Vector3D p1, out Vector3D p2, out Vector3D p3, out Segment seg)
        {
            if (Infinite(p) && Infinite(q) /*&& FiniteOrInfinite( r )*/)
            {
                p1 = new Vector3D(1, 0, 0);
                p2 = new Vector3D(0, Math.Sqrt(2) - 1);
                p3 = Vector3D.DneVector();

                Circle3D arcCircle;
                H3Models.Ball.OrthogonalCircleInterior(p2, p1, out arcCircle);
                seg = Segment.Arc(p1, p2, arcCircle.Center, clockwise: true);
            }
            else
            {
                Segment[] baseTileSegments;
                if (Infinite(q))
                {
                    baseTileSegments = BaseTileSegments(p, q);                          // Can't use dual here.
                }
                else
                {
                    baseTileSegments = BaseTileSegments(q, p);                          // Intentionally using dual.
                }
                seg = baseTileSegments.First();

                p1 = seg.P1;
                p2 = seg.Midpoint;
                p3 = p2;
                p3.RotateXY(-Math.PI / 2);
            }
        }
예제 #19
0
        public static void NormalizeToHyperboloid(ref Vector3D v)
        {
            double normSquared = v.Z * v.Z - (v.X * v.X + v.Y * v.Y);
            double norm        = Math.Sqrt(normSquared);

            v /= norm;
        }
예제 #20
0
        public static Vector3D[] VertsEuclidean()
        {
            int p = 4;
            int q = 3;

            //int r = 4;

            // Get a {q,p} tiling on the z=0 plane.
            Segment[] baseTileSegments = BaseTileSegments(q, p);

            // These will be unit length.
            Vector3D pFaceDirection    = H3Models.UHSToBall(baseTileSegments.First().P1);
            Vector3D pMidEdgeDirection = H3Models.UHSToBall(baseTileSegments.First().Midpoint);
            Vector3D pVertexDirection  = new Vector3D(0, 0, -1);

            // Order is same as facets (these are the points opposite facets).
            List <Vector3D> verts = new List <Vector3D>();

            verts.Add(new Vector3D());
            verts.Add(pFaceDirection * m_eScale);
            verts.Add(pMidEdgeDirection * Math.Sqrt(2) * m_eScale);
            verts.Add(pVertexDirection * Math.Sqrt(3) * m_eScale);

            // Apply rotations.
            double   rotation = Math.PI / 2;
            Vector3D zAxis    = new Vector3D(0, 0, 1);

            for (int i = 0; i < 4; i++)
            {
                verts[i].RotateAboutAxis(zAxis, rotation);
            }

            return(verts.ToArray());
        }
예제 #21
0
        /// <summary>
        /// Calculates distance between two geographic locations on equirectangular map projection
        /// <para>Using Pythagoras’ theorem </para>
        /// </summary>
        public static GeoDistance GetDistanceAppx(IGeoLocatable origin, IGeoLocatable destination, double radius = GeoGlobal.Earths.Radius)
        {
            origin      = origin.ToRadians();
            destination = destination.ToRadians();
            var dLat = (destination.Latitude - origin.Latitude);
            var dLon = (destination.Longitude - origin.Longitude);

            var x        = (dLon) * Math.Cos((origin.Latitude + destination.Latitude) / 2);
            var y        = (dLat);
            var distance = Math.Sqrt(x * x + y * y) * radius;

            return(new GeoDistance {
                Kilometers = distance
            });
            //return distance;

            //var yMin = Math.Min(origin.Latitude, destination.Latitude);
            //var yMax = Math.Max(origin.Latitude, destination.Latitude);
            //var xMin = Math.Min(origin.Longitude, destination.Longitude);
            //var xMax = Math.Max(origin.Longitude, destination.Longitude);
            //var yDelta = (yMax - yMin) * (yMax - yMin);
            //var xDelta = (xMax - xMin) * (xMax - xMin);

            //var distance = Math.Sqrt(xDelta + yDelta);
            //return new GeoDistance { Degrees = distance };
        }
예제 #22
0
파일: Plane.cs 프로젝트: truongascii/Win2D
        public static Plane Normalize(Plane value)
        {
            const float FLT_EPSILON = 1.192092896e-07f; // smallest such that 1.0+FLT_EPSILON != 1.0

            Plane result;

            float f = value.Normal.X * value.Normal.X + value.Normal.Y * value.Normal.Y + value.Normal.Z * value.Normal.Z;

            if (SM.Abs(f - 1.0f) < FLT_EPSILON)
            {
                result.Normal = value.Normal;
                result.D      = value.D;
                return(result); // It already normalized, so we don't need to farther process.
            }

            float fInv = 1.0f / (float)SM.Sqrt(f);

            result.Normal.X = value.Normal.X * fInv;
            result.Normal.Y = value.Normal.Y * fInv;
            result.Normal.Z = value.Normal.Z * fInv;

            result.D = value.D * fInv;

            return(result);
        }
예제 #23
0
        private static void From3Points(Vector3D v1, Vector3D v2, Vector3D v3,
                                        out Vector3D center, out double radius)
        {
            // Circumcenter/Circumradius of triangle (circle from 3 points)
            // http://mathworld.wolfram.com/Circumcenter.html
            // http://mathworld.wolfram.com/Circumradius.html
            // http://mathworld.wolfram.com/BarycentricCoordinates.html

            // side lengths and their squares
            double a  = (v3 - v2).Abs();                // Opposite v1
            double b  = (v1 - v3).Abs();                // Opposite v2
            double c  = (v2 - v1).Abs();                // Opposite v3
            double a2 = a * a;
            double b2 = b * b;
            double c2 = c * c;

            Vector3D circumCenterBary = new Vector3D(
                a2 * (b2 + c2 - a2),
                b2 * (c2 + a2 - b2),
                c2 * (a2 + b2 - c2));

            circumCenterBary /= (circumCenterBary.X + circumCenterBary.Y + circumCenterBary.Z);                 // Normalize.
            center            = BaryToCartesian(v1, v2, v3, circumCenterBary);

            double s = (a + b + c) / 2;             // semiperimeter

            radius = a * b * c / (4 * Math.Sqrt(s * (a + b - s) * (a + c - s) * (b + c - s)));
        }
예제 #24
0
        /// <summary>
        /// Calculates the point of our simplex that is at a vertex.
        /// </summary>
        public static Vector3D VertexPointBall(int p, int q, int r)
        {
            Geometry vertexGeometry = Geometry2D.GetGeometry(q, r);

            if (vertexGeometry == Geometry.Hyperbolic)
            {
                // Outside the ball, and not in a good way.  Use the Klein version.
                //throw new System.NotImplementedException();
                return(new Vector3D(0, 0, -1));
            }

            // Get in UHS first.
            Sphere cellFacet = Mirrors(p, q, r, moveToBall: false).First();
            double rSquared  = Math.Pow(cellFacet.Radius, 2);
            double cSquared  = Math.Pow(cellFacet.Center.Abs(), 2);

            Vector3D uhs;

            if (Tolerance.Equal(rSquared, cSquared))                    // e.g. 363
            {
                uhs = new Vector3D();
            }
            else
            {
                double height = Math.Sqrt(rSquared - cSquared);
                uhs = new Vector3D(0, 0, height);
            }
            return(H3Models.UHSToBall(uhs));
        }
예제 #25
0
        public static void CalcEScale()
        {
            // Euclidean scale is arbitrary, but put it in the middle of the projections of 433 and 435.
            double r3 = Spherical2D.s2eNorm(Honeycomb.CircumRadius(4, 3, 3));
            double r5 = DonHatch.h2eNorm(Honeycomb.CircumRadius(4, 3, 5));

            m_eScale = (r3 + r5) / (2 * Math.Sqrt(3));
        }
예제 #26
0
        // Minkowski normalization.
        private static Vector3D MinkowskiNormalize(Vector3D v)
        {
            double mag2 = MinkowskiInnerProduct(v, v);
            double abs  = mag2 < 0 ? Math.Sqrt(-mag2) : Math.Sqrt(mag2);

            v.Divide(abs);
            return(v);
        }
예제 #27
0
 /// <summary>
 /// Returns the distance between two vectors.
 /// </summary>
 public static float Distance(Vector3 a, Vector3 b)
 {
     Vector3 diff = new Vector3(
           a.X - b.X,
           a.Y - b.Y,
           a.Z - b.Z);
     return (float)Maths.Sqrt(Maths.Pow(diff.X, 2f) + Maths.Pow(diff.Y, 2f) + Maths.Pow(diff.Z, 2f));
 }
예제 #28
0
 public static double CircInOut(double b, double c, double t, double d = 1)
 {
     if ((t /= d / 2) < 1)
     {
         return(-c / 2 * (Math.Sqrt(1 - t * t) - 1) + b);
     }
     return(c / 2 * (Math.Sqrt(1 - (t -= 2) * t) + 1) + b);
 }
예제 #29
0
        private static void HopfFibration(Tiling tiling)
        {
            int       segDivisions    = 10;
            int       circleDivisions = 125;
            Shapeways mesh            = new Shapeways();

            HashSet <Vector3D> done = new HashSet <Vector3D>();

            foreach (Tile tile in tiling.Tiles)
            {
                foreach (Segment seg in tile.Boundary.Segments)
                {
                    if (done.Contains(seg.Midpoint))
                    {
                        continue;
                    }

                    // Subdivide the segment, and project points to S2.
                    Vector3D[] points = seg.Subdivide(segDivisions).Select(v => Spherical2D.PlaneToSphere(v)).ToArray();
                    foreach (Vector3D point in points)
                    {
                        // Get the hopf circle and add to mesh.
                        // http://en.wikipedia.org/wiki/Hopf_fibration#Explicit_formulae
                        double a      = point.X;
                        double b      = point.Y;
                        double c      = point.Z;
                        double factor = 1 / (Math.Sqrt(1 + c));
                        if (Tolerance.Equal(c, -1))
                        {
                            continue;
                        }

                        List <Vector3D> circlePoints = new List <Vector3D>();
                        double          angleInc     = 2 * Math.PI / circleDivisions;
                        double          angle        = 0;
                        for (int i = 0; i <= circleDivisions; i++)
                        {
                            double sinTheta = Math.Sin(angle);
                            double cosTheta = Math.Cos(angle);
                            circlePoints.Add(new Vector3D(
                                                 (1 + c) * cosTheta,
                                                 a * sinTheta - b * cosTheta,
                                                 a * cosTheta + b * sinTheta,
                                                 (1 + c) * sinTheta));

                            angle += angleInc;
                        }

                        bool shrink = false;
                        ProjectAndAddS3Points(mesh, circlePoints.ToArray(), shrink);
                    }

                    done.Add(seg.Midpoint);
                }
            }

            STL.SaveMeshToSTL(mesh.Mesh, @"D:\p4\R3\sample\out1.stl");
        }
예제 #30
0
        public static float Distance(Vector2 value1, Vector2 value2)
        {
            float dx = value1.X - value2.X;
            float dy = value1.Y - value2.Y;

            float ls = dx * dx + dy * dy;

            return((float)SM.Sqrt((double)ls));
        }