// 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); }
/// <summary> /// Converts to spherical coordinates. /// </summary> /// <returns>SphericalCoordinate.</returns> public static SphericalCoordinate ToSpherical(CartesianCoordinate3D coordinate) { double radialDistance = AlgebraLibrary.SRSS(coordinate.X, coordinate.Y.Squared(), coordinate.Z.Squared()); double angleAzimuth = NMath.Atan(coordinate.Y / coordinate.X); double angleInclination = NMath.Acos(coordinate.Z / radialDistance); return(new SphericalCoordinate(radialDistance, angleInclination, angleAzimuth, coordinate.Tolerance)); }
public PolarCoordinate ToPolar() { return(new PolarCoordinate { Radius = Algebra.SRSS(X, Y), Rotation = new Angle(NMath.Atan(Y / X)) }); }
/// <summary> /// Converts to spherical coordinates. /// </summary> /// <returns>SphericalCoordinate.</returns> public static SphericalCoordinate ToSpherical(CylindricalCoordinate coordinate) { double radius = AlgebraLibrary.SRSS(coordinate.Radius, coordinate.Height); double azimuth = coordinate.Azimuth.Radians; double inclination = NMath.Atan(coordinate.Radius / coordinate.Height); return(new SphericalCoordinate(radius, inclination, azimuth, coordinate.Tolerance)); }
/// <summary> /// NOTE: Not general, and assumes some things we know about this problem domain, /// e.g. that c1 and c2 live on the same sphere of radius 1, and have two intersection points. /// </summary> public static void IntersectionCircleCircle(Vector3D sphereCenter, Circle3D c1, Circle3D c2, out Vector3D i1, out Vector3D i2) { // Spherical analogue of our flat circle-circle intersection. // Spherical pythagorean theorem for sphere where r=1: cos(hypt) = cos(A)*cos(B) Circle3D clone1 = c1.Clone(), clone2 = c2.Clone(); //clone1.Center -= sphereCenter; //clone2.Center -= sphereCenter; // Great circle (denoted by normal vector), and distance between the centers. Vector3D gc = clone2.Normal.Cross(clone1.Normal); double d = clone2.Normal.AngleTo(clone1.Normal); double r1 = clone1.Normal.AngleTo(clone1.PointOnCircle); double r2 = clone2.Normal.AngleTo(clone2.PointOnCircle); // Calculate distances we need. So ugly! // http://www.wolframalpha.com/input/?i=cos%28r1%29%2Fcos%28r2%29+%3D+cos%28x%29%2Fcos%28d-x%29%2C+solve+for+x double t1 = Math.Pow(Math.Tan(d / 2), 2); double t2 = Math.Cos(r1) / Math.Cos(r2); double t3 = Math.Sqrt((t1 + 1) * (t1 * t2 * t2 + 2 * t1 * t2 + t1 + t2 * t2 - 2 * t2 + 1)) - 2 * t1 * t2; double x = 2 * Math.Atan(t3 / (t1 * t2 + t1 - t2 + 1)); double y = Math.Acos(Math.Cos(r1) / Math.Cos(x)); i1 = clone1.Normal; i1.RotateAboutAxis(gc, x); i2 = i1; // Perpendicular to gc through i1. Vector3D gc2 = i1.Cross(gc); i1.RotateAboutAxis(gc2, y); i2.RotateAboutAxis(gc2, -y); i1 += sphereCenter; i2 += sphereCenter; /* * // It would be nice to do the spherical analogue of circle-circle intersections, like here: * // http://mathworld.wolfram.com/Circle-CircleIntersection.html * // But I don't want to jump down that rabbit hole and am going to sacrifice some speed to use * // my existing euclidean function. * * // Stereographic projection to the plane. XXX - Crap, circles may become lines, and this isn't being handled well. * Circle3D c1Plane = H3Models.BallToUHS( clone1 ); * Circle3D c2Plane = H3Models.BallToUHS( clone2 ); * if( 2 != Euclidean2D.IntersectionCircleCircle( c1Plane.ToFlatCircle(), c2Plane.ToFlatCircle(), out i1, out i2 ) ) * throw new System.Exception( "Expected two intersection points" ); * i1 = H3Models.UHSToBall( i1 ); i1 += sphereCenter; * i2 = H3Models.UHSToBall( i2 ); i2 += sphereCenter; */ }
/// <summary> /// Helper to project points from S3 -> S2, then add an associated curve. /// </summary> private static void ProjectAndAddS3Points(Shapeways mesh, Vector3D[] pointsS3, bool shrink) { // Project to S3, then to R3. List <Vector3D> projected = new List <Vector3D>(); foreach (Vector3D v in pointsS3) { v.Normalize(); Vector3D c = v.ProjectTo3DSafe(1.0); // Pull R3 into a smaller open disk. if (shrink) { double mag = Math.Atan(c.Abs()); c.Normalize(); c *= mag; } projected.Add(c); } System.Func <Vector3D, double> sizeFunc = v => { // Constant thickness. // return 0.08; double sphericalThickness = 0.002; double abs = v.Abs(); if (shrink) { abs = Math.Tan(abs); // The unshrunk abs. } // The thickness at this vector location. double result = Spherical2D.s2eNorm(Spherical2D.e2sNorm(abs) + sphericalThickness) - abs; if (shrink) { result *= Math.Atan(abs) / abs; // shrink it back down. } return(result); }; mesh.AddCurve(projected.ToArray(), sizeFunc); }
private static int Math_Atan(ILuaState lua) { lua.PushNumber(Math.Atan(lua.L_CheckNumber(1))); return(1); }
/// <summary> /// Handles the calculation for inverse cotangent. /// </summary> /// <param name="x">A double to be evaluated.</param> /// <returns>Returns the principal value of the arccotangent, or inverse cotangent, of a number.</returns> public static double InverseCotangent(double x) { return(2.0 * MathObj.Atan(1) - MathObj.Atan(x)); }
public static double Atan(object self, [DefaultProtocol] double x) { return(SM.Atan(x)); }
// Inverse Sine public static double Arcsin(double x) { return(MathObj.Atan(x / MathObj.Sqrt(-x * x + 1))); }
// Inverse Secant public static double Arcsec(double x) { return(2 * MathObj.Atan(1) - MathObj.Atan(MathObj.Sign(x) / MathObj.Sqrt(x * x - 1))); }
/// <summary> /// Returns the angle whose tangent is the specified ratio. /// </summary> /// <param name="ratio">The ratio of 'opposite / adjacent'.</param> /// <returns>System.Double.</returns> public static double ArcTan(double ratio) { return(NMath.Atan(ratio)); }
// Inverse Cosine public static double Arccos(double x) { return(MathObj.Atan(-x / MathObj.Sqrt(-x * x + 1)) + 2 * MathObj.Atan(1)); }
public static double Atan(object self, double x) { return(SM.Atan(x)); }
/// <summary> /// Returns the angle [radians] from the x-axis, counter clockwise. /// </summary> /// <returns></returns> public static double Angle(double y, double x) { return(NMath.Atan(y / x)); }
e2sNorm(double eNorm) { return(2 * Math.Atan(eNorm)); }
/// <summary> /// Returns the angle [radians] of the vector from the x-axis, counter clockwise. /// </summary> /// <param name="vector1"></param> /// <returns></returns> public static double Angle(this NVector vector1) { return(NMath.Atan(vector1.Y / vector1.X)); }
// Inverse Cotangent public static double Arccotan(double x) { return(2 * MathObj.Atan(1) - MathObj.Atan(x)); }