/// <summary> /// Allow a hyperbolic transformation using an absolute offset. /// offset is specified in the respective geometry. /// </summary> public void Hyperbolic2(Geometry g, Complex fixedPlus, Complex point, double offset) { // To the origin. Mobius m = new Mobius(); m.Isometry(g, 0, fixedPlus * -1); double eRadius = m.Apply(point).Magnitude; double scale = 1; switch (g) { case Geometry.Spherical: double sRadius = Spherical2D.e2sNorm(eRadius); sRadius += offset; scale = Spherical2D.s2eNorm(sRadius) / eRadius; break; case Geometry.Euclidean: scale = (eRadius + offset) / eRadius; break; case Geometry.Hyperbolic: double hRadius = DonHatch.e2hNorm(eRadius); hRadius += offset; scale = DonHatch.h2eNorm(hRadius) / eRadius; break; } Hyperbolic(g, fixedPlus, scale); }
public void AnimationSections(Settings config) { HoneycombDef imageData = new HoneycombDef(config.P, config.Q, config.R); int p = imageData.P, q = imageData.Q, r = imageData.R; string filename = imageData.FormatFilename(); Sphere[] mirrors = SimplexCalcs.Mirrors(p, q, r); double bounds = 1.0; //config.UhsBoundary.Bounds; bounds = 9.0; // Calculate the color scale. int size = 200; CoxeterImages.Settings settings = new CoxeterImages.Settings() { Honeycomb = imageData, Width = size, Height = size, Bounds = bounds, Mirrors = mirrors, FileName = imageData.FormatFilename(), }; CoxeterImages imageCalculator = new CoxeterImages(); //imageCalculator.AutoCalcScale( settings ); if (settings.ColorScaling < 1) { settings.ColorScaling = 15; } settings.ColorScaling = 11; Program.Log("\nGenerating sections..."); size = 500; settings.Width = size; settings.Height = size; settings.FileName = filename; double max = Spherical2D.e2sNorm(15); double min = Spherical2D.e2sNorm(1.0 / 15); DonHatch.e2hNorm(max); int numSteps = 1800; // 1 minute double step = (max - min) / numSteps; for (int i = 0; i < 1; i++) { Program.Log("\nSection " + i); imageCalculator.m_z = 1.0 / 0.5; Spherical2D.s2eNorm(min + step * i); DonHatch.h2eNorm(step * i); settings.FileName = string.Format("533_{0:D4}.png", i); imageCalculator.GenImage(settings); } }
/// <summary> /// Equally subdivides a segment with a startpoint at the origin, in the respective geometry. /// </summary> private static Vector3D[] SubdivideRadialInGeometry(Segment radial, int divisions, Geometry g) { List <Vector3D> result = new List <Vector3D>(); if (radial.Type != SegmentType.Line) { Debug.Assert(false); return(result.ToArray()); } switch (g) { case Geometry.Spherical: { double eLength = radial.Length; double sLength = Spherical2D.e2sNorm(eLength); double divLength = sLength / divisions; for (int i = 0; i <= divisions; i++) { double temp = Spherical2D.s2eNorm(divLength * i); result.Add(radial.P2 * temp / eLength); } break; } case Geometry.Euclidean: return(radial.Subdivide(divisions)); case Geometry.Hyperbolic: { double eLength = radial.Length; double hLength = DonHatch.e2hNorm(eLength); double divLength = hLength / divisions; for (int i = 0; i <= divisions; i++) { double temp = DonHatch.h2eNorm(divLength * i); result.Add(radial.P2 * temp / eLength); } break; } } return(result.ToArray()); }
public static Sphere GeodesicOffset(Sphere s, double offset, bool ball = true) { Sphere offsetSphere; if (ball) { // Geodesic offset (ball). { // Hyperbolic honeycomb double mag = s.Center.Abs() - s.Radius; mag = s.IsPlane ? DonHatch.h2eNorm(offset) : DonHatch.h2eNorm(DonHatch.e2hNorm(mag) - offset); Vector3D closestPointToOrigin = s.IsPlane ? s.Normal : s.Center; closestPointToOrigin.Normalize(); closestPointToOrigin *= mag; offsetSphere = H3Models.Ball.OrthogonalSphereInterior(closestPointToOrigin); // There are multiple ultraparallel spheres. // This experiments with picking others. Mobius m = new Mobius(); m.Isometry(Geometry.Hyperbolic, 0, new Vector3D(0, -0.2)); //H3Models.TransformInBall2( offsetSphere, m ); } { // Spherical honeycomb //offset *= -1; double mag = -s.Center.Abs() + s.Radius; Spherical2D.s2eNorm(Spherical2D.e2sNorm(mag) + offset); offsetSphere = s.Clone(); offsetSphere.Radius += offset * 10; } } else { // Geodesic offset (UHS). // XXX - not scaled right. offsetSphere = s.Clone(); offsetSphere.Radius += offset; } return(offsetSphere); }