// these sources don't seem to agree, and what I ended up using is still different. WHY? // http://en.wikipedia.org/wiki/Generalised_circle // http://www.math.ubc.ca/~cass/research/pdf/Geometry.pdf // http://www.math.okstate.edu/~wrightd/INDRA/MobiusonCircles.mpl public static CircLine operator *(Mobius m, CircLine circLine) { #if true Mobius inverse = m.Inverse; Mobius b = new Mobius(new Complex(circLine.a, 0), circLine.b.Conjugate, circLine.b, new Complex(circLine.c, 0)); Mobius hermitian = inverse.Transpose * new Mobius(new Complex(circLine.a, 0), circLine.b.Conjugate, circLine.b, new Complex(circLine.c, 0)) * inverse.Conjugate; return CircLine.Create(hermitian.A.Re, hermitian.C, hermitian.D.Re); #else // do it by decomposing the mobius -- slower Complex a = m.A; Complex b = m.B; Complex c = m.C; Complex d = m.D; CircLine toInvert, inverted, scaled; if (c == Complex.Zero) { scaled = circLine.Scale(a / d); return scaled.Translate(b / d); } toInvert = circLine.Translate(d / c); inverted = toInvert.Inverse; scaled = inverted.Scale(-(a * d - b * c) / (c * c)); return scaled.Translate(a / c); #endif }
// these sources don't seem to agree, and what I ended up using is still different. WHY? // http://en.wikipedia.org/wiki/Generalised_circle // http://www.math.ubc.ca/~cass/research/pdf/Geometry.pdf // http://www.math.okstate.edu/~wrightd/INDRA/MobiusonCircles.mpl public static CircLine operator *(Mobius m, CircLine circLine) { #if true Mobius inverse = m.Inverse; Mobius b = new Mobius(new Complex(circLine.a, 0), circLine.b.Conjugate, circLine.b, new Complex(circLine.c, 0)); Mobius hermitian = inverse.Transpose * new Mobius(new Complex(circLine.a, 0), circLine.b.Conjugate, circLine.b, new Complex(circLine.c, 0)) * inverse.Conjugate; return(CircLine.Create(hermitian.A.Re, hermitian.C, hermitian.D.Re)); #else // do it by decomposing the mobius -- slower Complex a = m.A; Complex b = m.B; Complex c = m.C; Complex d = m.D; CircLine toInvert, inverted, scaled; if (c == Complex.Zero) { scaled = circLine.Scale(a / d); return(scaled.Translate(b / d)); } toInvert = circLine.Translate(d / c); inverted = toInvert.Inverse; scaled = inverted.Scale(-(a * d - b * c) / (c * c)); return(scaled.Translate(a / c)); #endif }
public static Mobius CreateDiscTranslation(Complex a, Complex b) { return (Mobius.CreateDiscAutomorphism(b, 0) * Mobius.CreateDiscAutomorphism(a, 0).Inverse); }
// Visual Complex Analysis p320 public static Mobius CreateDiscAutomorphism(Complex a, double phi) { return (Mobius.CreateRotation(phi) * new Mobius(Complex.One, -a, a.Conjugate, -Complex.One)); }