/// <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); }
/// <summary> /// Move from a point p1 -> p2 along a geodesic. /// Also somewhat from Don. /// factor can be used to only go some fraction of the distance from p1 to p2. /// </summary> public void Geodesic(Geometry g, Complex p1, Complex p2, double factor = 1.0) { Mobius t = new Mobius(); t.Isometry(g, 0, p1 * -1); Complex p2t = t.Apply(p2); // Only implemented for hyperbolic so far. if (factor != 1.0 && g == Geometry.Hyperbolic) { double newMag = DonHatch.h2eNorm(DonHatch.e2hNorm(p2t.Magnitude) * factor); Vector3D temp = Vector3D.FromComplex(p2t); temp.Normalize(); temp *= newMag; p2t = temp.ToComplex(); } Mobius m1 = new Mobius(), m2 = new Mobius(); m1.Isometry(g, 0, p1 * -1); m2.Isometry(g, 0, p2t); Mobius m3 = m1.Inverse(); this = m3 * m2 * m1; }