public static void GenImage() { int size = 1000; Bitmap image = new Bitmap( size, size ); ImageSpace i = new ImageSpace( size, size ); double b = 1.1; i.XMin = -b; i.XMax = b; i.YMin = -b; i.YMax = b; Vector3D cen = HoneycombPaper.CellCenBall; cen = H3Models.BallToUHS( cen ); Sphere[] simplex = Simplex( ref cen ); Sphere inSphere = InSphere( simplex ); using( Graphics g = Graphics.FromImage( image ) ) foreach( int[] reflections in AllCells() ) { Sphere clone = inSphere.Clone(); foreach( int r in reflections ) clone.Reflect( simplex[r] ); Sphere ball = new Sphere(); Circle3D inSphereIdealBall = ball.Intersection( clone ); Circle3D inSphereIdealUHS = H3Models.BallToUHS( inSphereIdealBall ); Circle inSphereIdeal = new Circle { Center = inSphereIdealUHS.Center, Radius = inSphereIdealUHS.Radius }; using( Brush brush = new SolidBrush( Color.Blue ) ) DrawUtils.DrawFilledCircle( inSphereIdeal, g, i, brush ); } image.Save( "threefifty.png", ImageFormat.Png ); }
private static Circle3D HoneycombEdgeUHS(int p, int q, int r) { Sphere[] simplex = Mirrors(p, q, r, moveToBall: false); Sphere s1 = simplex[0].Clone(); Sphere s2 = s1.Clone(); s2.Reflect(simplex[1]); Circle3D intersection = s1.Intersection(s2); return(intersection); }
/// <summary> /// This will return an altered facet to create true apparent 2D tilings (proper bananas) on the boundary. /// Notes: /// The input simplex must be in the ball model. /// The first mirror of the simplex (the one that mirrors across cells) is the one we end up altering. /// </summary> public static Sphere AlteredFacetForTrueApparent2DTilings( Sphere[] simplex ) { // We first need to find the size of the apparent 2D disk surrounding the leg. // This is also the size of the apparent cell head disk of the dual. // So we want to get the midsphere (insphere would also work) of the dual cell with that head, // then calculate the intersection of that with the boundary. Sphere cellMirror = simplex[0]; if( cellMirror.IsPlane ) throw new System.NotImplementedException(); // The point centered on a face is the closest point of the cell mirror to the origin. // This will be the point centered on an edge on the dual cell. Vector3D facePoint = cellMirror.ProjectToSurface( new Vector3D() ); // Reflect it to get 3 more points on our midsphere. Vector3D reflected1 = simplex[1].ReflectPoint( facePoint ); Vector3D reflected2 = simplex[2].ReflectPoint( reflected1 ); Vector3D reflected3 = simplex[0].ReflectPoint( reflected2 ); Sphere midSphere = Sphere.From4Points( facePoint, reflected1, reflected2, reflected3 ); // Get the ideal circles of the cell mirror and midsphere. // Note: The midsphere is not geodesic, so we can't calculate it the same. Sphere cellMirrorUHS = H3Models.BallToUHS( cellMirror ); Circle cellMirrorIdeal = H3Models.UHS.IdealCircle( cellMirrorUHS ); Sphere ball = new Sphere(); Circle3D midSphereIdealBall = ball.Intersection( midSphere ); // This should exist because we've filtered for honeycombs with hyperideal verts. Circle3D midSphereIdealUHS = H3Models.BallToUHS( midSphereIdealBall ); Circle midSphereIdeal = new Circle { Center = midSphereIdealUHS.Center, Radius = midSphereIdealUHS.Radius }; // The intersection point of our cell mirror and the disk of the apparent 2D tiling // gives us "ideal" points on the apparent 2D boundary. These points will be on the new cell mirror. Vector3D i1, i2; if( 2 != Euclidean2D.IntersectionCircleCircle( cellMirrorIdeal, midSphereIdeal, out i1, out i2 ) ) { //throw new System.ArgumentException( "Since we have hyperideal vertices, we should have an intersection with 2 points." ); // Somehow works in the euclidean case. // XXX - Make this better. return H3Models.UHSToBall( new Sphere() { Center = Vector3D.DneVector(), Radius = double.NaN } ); } double bananaThickness = 0.025; //bananaThickness = 0.15; //bananaThickness = 0.04; // Transform the intersection points to a standard Poincare disk. // The midsphere radius is the scale of the apparent 2D tilings. double scale = midSphereIdeal.Radius; Vector3D offset = midSphereIdeal.Center; i1 -= offset; i2 -= offset; i1 /= scale; i2 /= scale; Circle3D banana = H3Models.Ball.OrthogonalCircle( i1, i2 ); Vector3D i3 = H3Models.Ball.ClosestToOrigin( banana ); i3 = Hyperbolic2D.Offset( i3, -bananaThickness ); // Transform back. i1 *= scale; i2 *= scale; i3 *= scale; i1 += offset; i2 += offset; i3 += offset; // Construct our new simplex mirror with these 3 points. Circle3D c = new Circle3D( i1, i2, i3 ); Sphere result = new Sphere() { Center = c.Center, Radius = c.Radius }; return H3Models.UHSToBall( result ); }