Example #1
0
        // 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
        }
Example #2
0
        public override List <Intersection> Intersect(CircLine other)
        {
            List <Intersection> intersections = new List <Intersection>();

            if (other is Circle)
            {
                Circle otherC = (Circle)other;
                intersections = otherC.Intersect(this);
                if (intersections == null)
                {
                    intersections = otherC.Intersect(this);
                }

                return(intersections.Select(i => new CircLine.Intersection(i.Point, i.ParamB, i.ParamA)).ToList());
            }

            Line line = (Line)other;

            Complex denominator = b.Conjugate * line.b - b * line.b.Conjugate;

            if (denominator == Complex.Zero)
            {
                return(null);
            }

            Complex z = -(b * line.c - line.b * c) / denominator;

            intersections.Add(new Intersection(z, Project(z).Param, line.Project(z).Param));

            return(intersections);
        }
Example #3
0
        public bool Equals(CircLine circLine)
        {
            if (circLine == null)
            {
                return(false);
            }

            return(Accuracy.LengthEquals(a, circLine.a) && b == circLine.b && Accuracy.LengthEquals(c, circLine.c));
        }
Example #4
0
        public override bool IsNormalTo(CircLine circLine)
        {
            if (circLine is Line)
            {
                return(Math.Abs(Angle - ((Line)circLine).Angle) % (2 * Math.PI) == Math.PI);
            }

            Complex center = ((Circle)circLine).Center;

            return(this.Project(center).Point == center);
        }
Example #5
0
        public override bool IsNormalTo(CircLine circLine)
        {
            if (circLine is Line)
            {
                return(circLine.IsNormalTo(this));
            }

            List <Intersection> intersections = this.Intersect(circLine);

            if (intersections == null || intersections.Count == 0)
            {
                return(false);
            }

            Circle  other = (Circle)circLine;
            Complex p     = intersections[0].Point;

            return(Accuracy.AngularTolerance >
                   Math.Abs((p - this.Center).ModulusSquared + (p - other.Center).ModulusSquared - (this.Center - other.Center).ModulusSquared));
        }
Example #6
0
 public TrimmedCircLine(CircLine circLine, Interval bounds)
 {
     this.circLine = circLine;
     this.bounds = bounds;
 }
Example #7
0
        public override bool IsNormalTo(CircLine circLine)
        {
            if (circLine is Line)
                return Math.Abs(Angle - ((Line)circLine).Angle) % (2 * Math.PI) == Math.PI;

            Complex center = ((Circle)circLine).Center;
            return this.Project(center).Point == center;
        }
Example #8
0
        public override List<Intersection> Intersect(CircLine other)
        {
            List<Intersection > intersections = new List<Intersection>();

            if (other is Circle) {
                Circle otherC = (Circle)other;
                intersections = otherC.Intersect(this);
                if (intersections == null)
                    intersections = otherC.Intersect(this);

                return intersections.Select(i => new CircLine.Intersection(i.Point, i.ParamB, i.ParamA)).ToList();
            }

            Line line = (Line)other;

            Complex denominator = b.Conjugate * line.b - b * line.b.Conjugate;
            if (denominator == Complex.Zero)
                return null;

            Complex z = -(b * line.c - line.b * c) / denominator;
            intersections.Add(new Intersection(z, Project(z).Param, line.Project(z).Param));

            return intersections;
        }
Example #9
0
        public override List <Intersection> Intersect(CircLine other)
        {
            List <Intersection> intersections = new List <Intersection>();

            if (other is Circle)
            {
                Circle otherC = (Circle)other;

                Complex p0 = this.Center;
                Complex p1 = otherC.Center;
                double  d  = (p1 - p0).Modulus;
                double  r0 = this.Radius;
                double  r1 = otherC.Radius;

                if (d > (r0 + r1))                 // outside
                {
                    return(null);
                }
                if (d < Math.Abs(r0 - r1))
                {
                    return(intersections);
                }
                if (d == 0)
                {
                    return(intersections);
                }

                double  a  = (r0 * r0 - r1 * r1 + d * d) / (2 * d);
                double  h  = Math.Sqrt(r0 * r0 - a * a);
                Complex p2 = p0 + a * (p1 - p0) / d;

                Complex intersect;
                intersect = new Complex(
                    p2.Re + h * (p1.Im - p0.Im) / d,
                    p2.Im - h * (p1.Re - p0.Re) / d
                    );

                intersections.Add(new Intersection(
                                      intersect,
                                      Math.Atan2(p0.Im - intersect.Im, p0.Re - intersect.Re),
                                      Math.Atan2(p1.Im - intersect.Im, p1.Re - intersect.Re)
                                      ));

                intersect = new Complex(
                    p2.Re - h * (p1.Im - p0.Im) / d,
                    p2.Im + h * (p1.Re - p0.Re) / d
                    );

                intersections.Add(new Intersection(
                                      intersect,
                                      Math.Atan2(p0.Im - intersect.Im, p0.Re - intersect.Re),
                                      Math.Atan2(p1.Im - intersect.Im, p1.Re - intersect.Re)
                                      ));

                return(intersections);
            }

            Line line = (Line)other;

            Complex nearPoint = line.Project(Center).Point - line.Origin;

            double dist = (Center - nearPoint).Modulus;

            if (dist - Radius > 0)
            {
                return(null);
            }

            Complex p;

            p = Line.Create(nearPoint, line.Angle).Evaluate(Math.Sqrt(RadiusSquared - dist * dist));
            intersections.Add(new Intersection(
                                  p,
                                  line.Angle - Math.Asin(dist / Radius),
                                  line.Project(p).Param
                                  ));

            p = Line.Create(nearPoint, line.Angle).Evaluate(-Math.Sqrt(RadiusSquared - dist * dist));
            intersections.Add(new Intersection(
                                  p,
                                  line.Angle + Math.Asin(dist / Radius) + Math.PI,
                                  line.Project(p).Param
                                  ));

            return(intersections);
        }
Example #10
0
 public abstract List<Intersection> Intersect(CircLine other);
Example #11
0
        public override bool IsNormalTo(CircLine circLine)
        {
            if (circLine is Line)
                return circLine.IsNormalTo(this);

            List<Intersection > intersections = this.Intersect(circLine);
            if (intersections == null || intersections.Count == 0)
                return false;

            Circle other = (Circle)circLine;
            Complex p = intersections[0].Point;

            return Accuracy.AngularTolerance >
                Math.Abs((p - this.Center).ModulusSquared + (p - other.Center).ModulusSquared - (this.Center - other.Center).ModulusSquared);
        }
Example #12
0
        public override List<Intersection> Intersect(CircLine other)
        {
            List<Intersection > intersections = new List<Intersection>();

            if (other is Circle) {
                Circle otherC = (Circle)other;

                Complex p0 = this.Center;
                Complex p1 = otherC.Center;
                double d = (p1 - p0).Modulus;
                double r0 = this.Radius;
                double r1 = otherC.Radius;

                if (d > (r0 + r1)) // outside
                    return null;
                if (d < Math.Abs(r0 - r1))
                    return intersections;
                if (d == 0)
                    return intersections;

                double a = (r0 * r0 - r1 * r1 + d * d) / (2 * d);
                double h = Math.Sqrt(r0 * r0 - a * a);
                Complex p2 = p0 + a * (p1 - p0) / d;

                Complex intersect;
                intersect = new Complex(
                        p2.Re + h * (p1.Im - p0.Im) / d,
                        p2.Im - h * (p1.Re - p0.Re) / d
                    );

                intersections.Add(new Intersection(
                    intersect,
                    Math.Atan2(p0.Im - intersect.Im, p0.Re - intersect.Re),
                    Math.Atan2(p1.Im - intersect.Im, p1.Re - intersect.Re)
                ));

                intersect = new Complex(
                    p2.Re - h * (p1.Im - p0.Im) / d,
                    p2.Im + h * (p1.Re - p0.Re) / d
                );

                intersections.Add(new Intersection(
                    intersect,
                    Math.Atan2(p0.Im - intersect.Im, p0.Re - intersect.Re),
                    Math.Atan2(p1.Im - intersect.Im, p1.Re - intersect.Re)
                ));

                return intersections;
            }

            Line line = (Line)other;

            Complex nearPoint = line.Project(Center).Point - line.Origin;

            double dist = (Center - nearPoint).Modulus;
            if (dist - Radius > 0)
                return null;

            Complex p;

            p = Line.Create(nearPoint, line.Angle).Evaluate(Math.Sqrt(RadiusSquared - dist * dist));
            intersections.Add(new Intersection(
                p,
                line.Angle - Math.Asin(dist / Radius),
                line.Project(p).Param
            ));

            p = Line.Create(nearPoint, line.Angle).Evaluate(-Math.Sqrt(RadiusSquared - dist * dist));
            intersections.Add(new Intersection(
                p,
                line.Angle + Math.Asin(dist / Radius) + Math.PI,
                line.Project(p).Param
            ));

            return intersections;
        }
Example #13
0
 public abstract List <Intersection> Intersect(CircLine other);
Example #14
0
 public abstract bool IsNormalTo(CircLine circLine);
Example #15
0
 public TrimmedCircLine(Complex start, Complex end)
 {
     this.circLine = Line.Create(start, end);
     this.bounds = circLine.MinorInterval(CircLine.Project(start).Param, CircLine.Project(end).Param);
 }
Example #16
0
        public bool Equals(CircLine circLine)
        {
            if (circLine == null)
                return false;

            return Accuracy.LengthEquals(a, circLine.a) && b == circLine.b && Accuracy.LengthEquals(c, circLine.c);
        }
Example #17
0
 public TrimmedCircLine(CircLine circLine, Interval bounds)
 {
     this.circLine = circLine;
     this.bounds   = bounds;
 }
Example #18
0
 public abstract bool IsNormalTo(CircLine circLine);
Example #19
0
 public TrimmedCircLine(Complex start, Complex end)
 {
     this.circLine = Line.Create(start, end);
     this.bounds   = circLine.MinorInterval(CircLine.Project(start).Param, CircLine.Project(end).Param);
 }