//rotate this point about another point
        public void Rotate(double angle, Point2D point)
        {
            x -= point.x;
            y -= point.y;

            var ox = x;
            var oy = y;

            x = Math.Cos(angle)*ox - Math.Sin(angle)*oy;
            y = Math.Sin(angle)*ox + Math.Cos(angle)*oy;

            x += point.x;
            y += point.y;
        }
 //what is the squared dist to another point
 public double distance_sq(Point2D point)
 {
     var dx = point.x - x;
     var dy = point.y - y;
     return dx*dx + dy*dy;
 }
 public Point2D(Point2D another)
 {
     x = another.x;
     y = another.y;
 }
        //what is the squared distance from this line to a point 
        public double distance_sq(Point2D n)
        {
            var utop = (n.x - P1.x)*(P2.x - P1.x) + (n.y - P1.y)*(P2.y - P1.y);
            var ubot = P1.distance_sq(P2);
            var u = utop/ubot;

            if (u < 0 || u > 1)
            {
                var d1 = P1.distance_sq(n);
                var d2 = P2.distance_sq(n);
                if (d1 < d2) return d1;
                return d2;
            }
            var p = new Point2D(0.0, 0.0) {x = P1.x + u*(P2.x - P1.x), y = P1.y + u*(P2.y - P1.y)};
            return p.distance_sq(n);
        }
 //what is the distance from this line to a point
 public double Distance(Point2D n)
 {
     return Math.Sqrt(distance_sq(n));
 }
 public Circle2D(Point2D a, double rad)
 {
     Radius = rad;
     p = a;
 }
        //calculate the point of intersection between two line segments
        public Point2D Intersection(Line2D L, out bool found)
        {
            var pt = new Point2D(0.0, 0.0);
            var a = P1;
            var b = P2;
            var c = L.P1;
            var d = L.P2;

            var rTop = (a.y - c.y)*(d.x - c.x) - (a.x - c.x)*(d.y - c.y);
            var rBot = (b.x - a.x)*(d.y - c.y) - (b.y - a.y)*(d.x - c.x);

            var sTop = (a.y - c.y)*(b.x - a.x) - (a.x - c.x)*(b.y - a.y);
            var sBot = (b.x - a.x)*(d.y - c.y) - (b.y - a.y)*(d.x - c.x);

            if ((rBot == 0 || sBot == 0))
            {
                found = false;
                return pt;
            }
            var r = rTop/rBot;
            var s = sTop/sBot;
            if ((r > 0) && (r < 1) && (s > 0) && (s < 1))
            {
                pt.x = a.x + r*(b.x - a.x);
                pt.y = a.y + r*(b.y - a.y);
                found = true;
                return pt;
            }
            found = false;
            return pt;
        }
 public Circle2D(Circle2D other)
 {
     p = other.p;
     Radius = other.Radius;
 }
 public Line2D(Line2D other)
 {
     P1 = other.P1;
     P2 = other.P2;
 }
 public Line2D(Point2D a, Point2D b)
 {
     P1 = a;
     P2 = b;
 }
 //what is the distance to another point
 public double Distance(Point2D point)
 {
     return Math.Sqrt(distance_sq(point));
 }
 public double ManhattanDistance(Point2D point)
 {
     var dx = Math.Abs(point.x - x);
     var dy = Math.Abs(point.y - y);
     return dx + dy;
 }