예제 #1
0
        public static double ElasticInOut(double b, double c, double t, double d = 1)
        {
            if (t == 0)
            {
                return(b);
            }
            if ((t /= d / 2) == 2)
            {
                return(b + c);
            }
            double s;
            double a = c;
            double p = d * (.3 * 1.5);

            if (a < Math.Abs(c))
            {
                a = c;
                s = p / 4;
            }
            else
            {
                s = p / (2 * Math.PI) * Math.Asin(c / a);
            }
            if (t < 1)
            {
                return(-.5 * (a * Math.Pow(2, 10 * (t -= 1)) * Math.Sin((t * d - s) * (2 * Math.PI) / p)) + b);
            }
            return(a * Math.Pow(2, -10 * (t -= 1)) * Math.Sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b);
        }
예제 #2
0
        public static void GenCapWithHole()
        {
            Shapeways mesh = new Shapeways();

            double overallScale = 12.5;                 // 2.5 cm = 1 in diameter

            // Make hole 2 mm
            double startAngle = Math.Asin(2.0 / 2 / overallScale);
            double endAngle   = Math.PI / 8;            // Slightly larger than hole above.

            int    div      = 75;
            double angleInc = (endAngle - startAngle) / div;

            for (int i = 0; i < div; i++)
            {
                double   angle1 = startAngle + angleInc * i;
                double   angle2 = startAngle + angleInc * (i + 1);
                Vector3D s1 = new Vector3D(0, 0, 1), s2 = new Vector3D(0, 0, 1);
                s1.RotateAboutAxis(new Vector3D(0, 1, 0), angle1);
                s2.RotateAboutAxis(new Vector3D(0, 1, 0), angle2);

                Vector3D p1 = s1 * (1 + SizeFunc(s1, overallScale));
                Vector3D p2 = s2 * (1 + SizeFunc(s2, overallScale));
                Vector3D n1 = s1 * (1 - SizeFunc(s1, overallScale));
                Vector3D n2 = s2 * (1 - SizeFunc(s2, overallScale));

                List <Vector3D> pointsP1 = new List <Vector3D>();
                List <Vector3D> pointsP2 = new List <Vector3D>();
                List <Vector3D> pointsN1 = new List <Vector3D>();
                List <Vector3D> pointsN2 = new List <Vector3D>();
                for (int j = 0; j < div; j++)
                {
                    pointsP1.Add(p1);
                    pointsP2.Add(p2);
                    pointsN1.Add(n1);
                    pointsN2.Add(n2);
                    p1.RotateAboutAxis(new Vector3D(0, 0, 1), 2 * Math.PI / div);
                    p2.RotateAboutAxis(new Vector3D(0, 0, 1), 2 * Math.PI / div);
                    n1.RotateAboutAxis(new Vector3D(0, 0, 1), 2 * Math.PI / div);
                    n2.RotateAboutAxis(new Vector3D(0, 0, 1), 2 * Math.PI / div);
                }

                mesh.AddSegment(pointsP1.ToArray(), pointsP2.ToArray());
                mesh.AddSegment(pointsN2.ToArray(), pointsN1.ToArray());
                if (i == 0)
                {
                    mesh.AddSegment(pointsN1.ToArray(), pointsP1.ToArray());
                }
                if (i == div - 1)
                {
                    mesh.AddSegment(pointsP2.ToArray(), pointsN2.ToArray());
                }
            }

            mesh.Mesh.Scale(overallScale);

            string outputFileName = @"d:\temp\cap_with_hole.stl";

            STL.SaveMeshToSTL(mesh.Mesh, outputFileName);
        }
예제 #3
0
        public static double ElasticOut(double b, double c, double t, double d = 1)
        {
            if (t == 0)
            {
                return(b);
            }
            if ((t /= d) == 1)
            {
                return(b + c);
            }
            double s;
            double a = c;
            double p = d * .3;

            if (a < Math.Abs(c))
            {
                a = c;
                s = p / 4;
            }
            else
            {
                s = p / (2 * Math.PI) * Math.Asin(c / a);
            }
            return(a * Math.Pow(2, -10 * t) * Math.Sin((t * d - s) * (2 * Math.PI) / p) + c + b);
        }
예제 #4
0
        private static void GetSphereUv(Vec3 p_point, ref HitRecord p_hitRecord)
        {
            var phi   = Math.Atan2(p_point.Z, p_point.X);
            var theta = Math.Asin(p_point.Y);

            p_hitRecord.U = 1 - (phi + Math.PI) / (2 * Math.PI);
            p_hitRecord.V = (theta + Math.PI / 2) / Math.PI;
        }
예제 #5
0
        /// <summary>
        /// Returns the mid-radius, in the induced geometry.
        /// </summary>
        public static double MidRadius(int p, int q, int r)
        {
            double pir = PiOverNSafe(r);

            double inRadius  = InRadius(p, q, r);
            double midRadius = DonHatch.sinh(inRadius) / Math.Sin(pir);

            switch (GetGeometry(p, q, r))
            {
            case Geometry.Hyperbolic:
                return(DonHatch.asinh(midRadius));

            case Geometry.Spherical:
                return(Math.Asin(midRadius));
            }

            throw new System.NotImplementedException();
        }
예제 #6
0
        /// <summary>
        /// Calculates the destination location at distance and in direction of bearing from origin location
        /// <para>Using the Spherical law of cosines </para>
        /// </summary>
        /// <param name="origin">location in geographic degrees </param>
        /// <param name="bearing">bearing in geographic degrees from origin</param>
        /// <param name="distance">distance in km</param>
        /// <param name="radius">radius in km</param>
        /// <remarks>radius defaults to Earth's mean radius</remarks>
        public static GeoPoint GetDestination(IGeoLocatable origin, double bearing, double distance, double radius = GeoGlobal.Earths.Radius)
        {
            origin   = origin.ToRadians();
            bearing  = bearing.ToRadians();
            distance = distance / radius; // angular distance in radians

            var latitude = Math.Asin(Math.Sin(origin.Latitude) * Math.Cos(distance) +
                                     Math.Cos(origin.Latitude) * Math.Sin(distance) * Math.Cos(bearing));
            var x         = Math.Sin(bearing) * Math.Sin(distance) * Math.Cos(origin.Latitude);
            var y         = Math.Cos(distance) - Math.Sin(origin.Latitude) * Math.Sin(origin.Latitude);
            var longitude = origin.Longitude + Math.Atan2(x, y);

            longitude = (longitude + 3 * Math.PI) % (2 * Math.PI) - Math.PI;  // normalize to -180..+180º

            var destination = new GeoPoint(longitude.ToDegrees(), latitude.ToDegrees());

            return(destination);
        }
예제 #7
0
        /// <summary>
        /// Converts to cylindrical coordinates.
        /// </summary>
        /// <returns>CylindricalCoordinate.</returns>
        public static CylindricalCoordinate ToCylindrical(CartesianCoordinate3D coordinate)
        {
            double radialDistance = AlgebraLibrary.SRSS(coordinate.X, coordinate.Y);
            double height         = coordinate.Z;
            double angleAzimuth   = 0;

            if (coordinate.X.IsZeroSign() && coordinate.Y.IsZeroSign())
            {
                angleAzimuth = 0;
            }
            else if (coordinate.X.IsGreaterThanOrEqualTo(0) && !coordinate.Y.IsZeroSign())
            {
                angleAzimuth = NMath.Asin(coordinate.Y / radialDistance);
            }
            else if (coordinate.X.IsNegativeSign())
            {
                angleAzimuth = -NMath.Asin(coordinate.Y / radialDistance) + Numbers.Pi;
            }

            return(new CylindricalCoordinate(radialDistance, height, angleAzimuth, coordinate.Tolerance));
        }
예제 #8
0
 private static int Math_Asin(ILuaState lua)
 {
     lua.PushNumber(Math.Asin(lua.L_CheckNumber(1)));
     return(1);
 }
예제 #9
0
 public static double Asin(object self, [DefaultProtocol] double x)
 {
     return(DomainCheck(SM.Asin(x), "asin"));
 }
예제 #10
0
        public static Sphere[] Mirrors(int p, int q, int r, ref Vector3D cellCenter, bool moveToBall = true, double scaling = -1)
        {
            Geometry g = Util.GetGeometry(p, q, r);

            if (g == Geometry.Spherical)
            {
                // These are in the ball model.
                Sphere[] result = SimplexCalcs.MirrorsSpherical(p, q, r);
                return(result);
            }
            else if (g == Geometry.Euclidean)
            {
                return(SimplexCalcs.MirrorsEuclidean());
            }

            // This is a rotation we'll apply to the mirrors at the end.
            // This is to try to make our image outputs have vertical bi-lateral symmetry and the most consistent in all cases.
            // NOTE: + is CW, not CCW. (Because the way I did things, our images have been reflected vertically, and I'm too lazy to go change this.)
            double rotation = Math.PI / 2;

            // Some construction points we need.
            Vector3D p1, p2, p3;
            Segment  seg = null;

            TilePoints(p, q, out p1, out p2, out p3, out seg);

            //
            // Construct in UHS
            //

            Geometry cellGeometry = Geometry2D.GetGeometry(p, q);

            Vector3D center = new Vector3D();
            double   radius = 0;

            if (cellGeometry == Geometry.Spherical)
            {
                // Finite or Infinite r

                // Spherical trig
                double halfSide = Geometry2D.GetTrianglePSide(q, p);
                double mag      = Math.Sin(halfSide) / Math.Cos(Util.PiOverNSafe(r));
                mag = Math.Asin(mag);

                // e.g. 43j
                //mag *= 0.95;

                // Move mag to p1.
                mag = Spherical2D.s2eNorm(mag);
                H3Models.Ball.DupinCyclideSphere(p1, mag, Geometry.Spherical, out center, out radius);
            }
            else if (cellGeometry == Geometry.Euclidean)
            {
                center = p1;
                radius = p1.Dist(p2) / Math.Cos(Util.PiOverNSafe(r));
            }
            else if (cellGeometry == Geometry.Hyperbolic)
            {
                if (Infinite(p) && Infinite(q) && FiniteOrInfinite(r))
                {
                    //double iiiCellRadius = 2 - Math.Sqrt( 2 );
                    //Circle3D iiiCircle = new Circle3D() { Center = new Vector3D( 1 - iiiCellRadius, 0, 0 ), Radius = iiiCellRadius };
                    //radius = iiiCellRadius;	// infinite r
                    //center = new Vector3D( 1 - radius, 0, 0 );

                    // For finite r, it was easier to calculate cell facet in a more symmetric position,
                    // then move into position with the other mirrors via a Mobius transformation.
                    double rTemp = 1 / (Math.Cos(Util.PiOverNSafe(r)) + 1);
                    Mobius m     = new Mobius();
                    m.Isometry(Geometry.Hyperbolic, -Math.PI / 4, new Vector3D(0, Math.Sqrt(2) - 1));
                    Vector3D c1 = m.Apply(new Vector3D(1 - 2 * rTemp, 0, 0));
                    Vector3D c2 = c1;
                    c2.Y *= -1;
                    Vector3D c3 = new Vector3D(1, 0);
                    Circle3D c  = new Circle3D(c1, c2, c3);

                    radius = c.Radius;
                    center = c.Center;
                }
                else if (Infinite(p) && Finite(q) && FiniteOrInfinite(r))
                {
                    // http://www.wolframalpha.com/input/?i=r%2Bx+%3D+1%2C+sin%28pi%2Fp%29+%3D+r%2Fx%2C+solve+for+r
                    // radius = 2 * Math.Sqrt( 3 ) - 3;	// Appolonian gasket wiki page
                    //radius = Math.Sin( Math.PI / q ) / ( Math.Sin( Math.PI / q ) + 1 );
                    //center = new Vector3D( 1 - radius, 0, 0 );

                    // For finite r, it was easier to calculate cell facet in a more symmetric position,
                    // then move into position with the other mirrors via a Mobius transformation.
                    double rTemp = 1 / (Math.Cos(Util.PiOverNSafe(r)) + 1);
                    Mobius m     = new Mobius();
                    m.Isometry(Geometry.Hyperbolic, 0, p2);
                    Vector3D findingAngle = m.Inverse().Apply(new Vector3D(1, 0));
                    double   angle        = Math.Atan2(findingAngle.Y, findingAngle.X);

                    m.Isometry(Geometry.Hyperbolic, angle, p2);
                    Vector3D c1 = m.Apply(new Vector3D(1 - 2 * rTemp, 0, 0));
                    Vector3D c2 = c1;
                    c2.Y *= -1;
                    Vector3D c3 = new Vector3D(1, 0);
                    Circle3D c  = new Circle3D(c1, c2, c3);

                    radius = c.Radius;
                    center = c.Center;
                }
                else if (Finite(p) && Infinite(q) && FiniteOrInfinite(r))
                {
                    radius = p2.Abs();                                                                              // infinite r
                    radius = DonHatch.asinh(Math.Sinh(DonHatch.e2hNorm(p2.Abs())) / Math.Cos(Util.PiOverNSafe(r))); // hyperbolic trig

                    // 4j3
                    //m_jOffset = radius * 0.02;
                    //radius += m_jOffset ;

                    radius    = DonHatch.h2eNorm(radius);
                    center    = new Vector3D();
                    rotation *= -1;
                }
                else if (/*Finite( p ) &&*/ Finite(q))
                {
                    // Infinite r
                    //double mag = Geometry2D.GetTrianglePSide( q, p );

                    // Finite or Infinite r
                    double halfSide = Geometry2D.GetTrianglePSide(q, p);
                    double mag      = DonHatch.asinh(Math.Sinh(halfSide) / Math.Cos(Util.PiOverNSafe(r)));                              // hyperbolic trig
                    H3Models.Ball.DupinCyclideSphere(p1, DonHatch.h2eNorm(mag), out center, out radius);
                }
                else
                {
                    throw new System.NotImplementedException();
                }
            }
            Sphere cellBoundary = new Sphere()
            {
                Center = center,
                Radius = radius
            };

            Sphere[] interior = InteriorMirrors(p, q);
            Sphere[] surfaces = new Sphere[] { cellBoundary, interior[0], interior[1], interior[2] };

            // Apply rotations.
            bool applyRotations = true;

            if (applyRotations)
            {
                foreach (Sphere s in surfaces)
                {
                    RotateSphere(s, rotation);
                }
                p1.RotateXY(rotation);
            }

            // Apply scaling
            bool applyScaling = scaling != -1;

            if (applyScaling)
            {
                //double scale = 1.0/0.34390660467269524;
                //scale = 0.58643550768408892;
                foreach (Sphere s in surfaces)
                {
                    Sphere.ScaleSphere(s, scaling);
                }
            }

            bool facetCentered = false;

            if (facetCentered)
            {
                PrepForFacetCentering(p, q, surfaces, ref cellCenter);
            }

            // Move to ball if needed.
            if (moveToBall)
            {
                surfaces = MoveToBall(surfaces, ref cellCenter);
            }

            return(surfaces);
        }
예제 #11
0
        /// <summary>
        /// Calculates intersection point of paths from two geographic locations
        /// </summary>
        /// <param name="origin1">origin of first location in geographic degrees</param>
        /// <param name="origin2">origin of second location in geographic degrees</param>
        /// <param name="bearing1">bearing from first location in geographic degrees</param>
        /// <param name="bearing2">bearing from second 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 GeoPoint GetIntersection(
            IGeoLocatable origin1, double bearing1,
            IGeoLocatable origin2, double bearing2, double radius = GeoGlobal.Earths.Radius)
        {
            origin1 = origin1.ToRadians();
            origin2 = origin2.ToRadians();
            var brng13 = bearing1.ToRadians();
            var brng23 = bearing2.ToRadians();
            var dLat   = (origin2.Latitude - origin1.Latitude);
            var dLon   = (origin2.Longitude - origin1.Longitude);

            var dist12 = 2 * Math.Asin(Math.Sqrt(Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
                                                 Math.Cos(origin1.Latitude) * Math.Cos(origin2.Latitude) *
                                                 Math.Sin(dLon / 2) * Math.Sin(dLon / 2)));

            if (dist12 == 0)
            {
                return(GeoPoint.Invalid);
            }

            // initial/final bearings between points
            var brngA = Math.Acos((Math.Sin(origin2.Latitude) - Math.Sin(origin1.Latitude) * Math.Cos(dist12)) /
                                  (Math.Sin(dist12) * Math.Cos(origin1.Latitude)));

            if (double.IsNaN(brngA))
            {
                brngA = 0;                       // protect against rounding
            }
            var brngB = Math.Acos((Math.Sin(origin1.Latitude) - Math.Sin(origin2.Latitude) * Math.Cos(dist12)) /
                                  (Math.Sin(dist12) * Math.Cos(origin2.Latitude)));

            double brng12, brng21;

            if (Math.Sin(dLon) > 0)
            {
                brng12 = brngA;
                brng21 = 2 * Math.PI - brngB;
            }
            else
            {
                brng12 = 2 * Math.PI - brngA;
                brng21 = brngB;
            }
            var alpha1 = (brng13 - brng12 + Math.PI) % (2 * Math.PI) - Math.PI;  // angle 2-1-3
            var alpha2 = (brng21 - brng23 + Math.PI) % (2 * Math.PI) - Math.PI;  // angle 1-2-3

            if (Math.Sin(alpha1) == 0 && Math.Sin(alpha2) == 0)
            {
                return(GeoPoint.Invalid);                                                 // infinite intersections
            }
            if (Math.Sin(alpha1) * Math.Sin(alpha2) < 0)
            {
                return(GeoPoint.Invalid);                                                 // ambiguous intersection
            }
            var alpha3 = Math.Acos(-Math.Cos(alpha1) * Math.Cos(alpha2) +
                                   Math.Sin(alpha1) * Math.Sin(alpha2) * Math.Cos(dist12));
            var dist13 = Math.Atan2(Math.Sin(dist12) * Math.Sin(alpha1) * Math.Sin(alpha2),
                                    Math.Cos(alpha2) + Math.Cos(alpha1) * Math.Cos(alpha3));
            var lat3 = Math.Asin(Math.Sin(origin1.Latitude) * Math.Cos(dist13) +
                                 Math.Cos(origin1.Latitude) * Math.Sin(dist13) * Math.Cos(brng13));
            var dLon13 = Math.Atan2(Math.Sin(brng13) * Math.Sin(dist13) * Math.Cos(origin1.Latitude),
                                    Math.Cos(dist13) - Math.Sin(origin1.Latitude) * Math.Sin(lat3));

            var lon3 = origin1.Longitude + dLon13;

            lon3 = (lon3 + 3 * Math.PI) % (2 * Math.PI) - Math.PI;  // normalize to -180..+180º

            return(new GeoPoint(lat3.ToDegrees(), lon3.ToDegrees()));
        }
예제 #12
0
 public static double Asin(object self, double x)
 {
     return(DomainCheck(SM.Asin(x), "asin"));
 }
예제 #13
0
 /// <summary>
 /// Returns the angle whose sine is the specified ratio.
 /// </summary>
 /// <param name="ratio">The ratio of 'opposite / hypotenuse'.</param>
 /// <returns>System.Double.</returns>
 public static double ArcSin(double ratio)
 {
     return(NMath.Asin(ratio));
 }