示例#1
0
        private static Ship CreateShip(Point startPoint, Point endPoint)
        {
            var list = new List<Point> { startPoint };
            if (startPoint != endPoint)
            {
                list.Add(endPoint);
            }
            list.Sort();

            if (list.Count > 1 && startPoint.DistanceTo(endPoint) > 2)
            {
                if (list[0].X == list[1].X)
                {
                    // vertical
                    for (var y = (byte)(list[0].Y + 1); y < list[1].Y; ++y)
                    {
                        list.Add(new Point(list[0].X, y, true, false));
                    }
                }
                else
                {
                    // Horiz
                    for (var x = (char)(list[0].X + 1); x < list[1].X; ++x)
                    {
                        list.Add(new Point(x, list[0].Y, true, false));
                    }
                }
            }

            list.Sort();
            return new Ship(list.ToArray());
        }
示例#2
0
文件: PointTest.cs 项目: cudima/lines
    public void DistanceTest()
    {
      Point p1 = new Point(0, 0);
      Point p2 = new Point(1, 1);

      Assert.AreEqual<double>(p1.DistanceTo(p2), 2, "Distance unexpected");
      Assert.AreEqual<double>(p1.DistanceTo(p2), p2.DistanceTo(p1), "Distance not equal in both directions");

      bool threwException = false;

      try
      {
        p1.DistanceTo(null);
      }
      catch (ArgumentNullException)
      {
        threwException = true;
      }

      Assert.IsTrue(threwException, "Did not throw ArgumentNullException");
    }
示例#3
0
 bool CreateEdgesFromEdges(Point p)
 {
     // Point p is near an edge, and we build a perpendicular edge from p to that edge,
     // or a new edge from p to an end of the edge.
     bool created = false;
     int i, N = edges.Count;
     Edge e;
     for (i = 0; i < N; i++)
     {
         e = edges[i];
         double dist = p.DistanceTo(e);
         // If point p is close to e, but not on e...
         if (dist < Epsilon && !Util.IsZero(dist))
         {
             Point intersection = e.IntersectWithPerpendicular(p);
             if (e.Contains(intersection))
             {
                 edges.Add(new Edge(p, intersection));
                 created = true;
             }
             else
                 // Or just create with nearest edge end, if possible
                 if (p.DistanceTo(e.P1) < Epsilon)
                 {
                     edges.Add(new Edge(p, e.P1));
                     created = true;
                 }
                 else
                     if (p.DistanceTo(e.P2) < Epsilon)
                     {
                         edges.Add(new Edge(p, e.P2));
                         created = true;
                     }
         }
     }
     return created;
 }
示例#4
0
 bool MergePointInEdge(Point p)
 {
     // Checks if this point belongs to an already existing edge.
     foreach (Edge e in edges)
         if (p.DistanceTo(e) < Epsilon && p.Between(e.P1, e.P2))
             return true;
     return false;
 }
示例#5
0
 bool ExtendEdges(Point p)
 {
     // Point p is on director vector of edge e, and we extend e to include p.
     List<Edge> extended = new List<Edge>();
     foreach (Edge e in edges)
         if (p.OnLine(e.P1, e.P2) && p != e.P1 && p != e.P2)
         {
             int where = p.Where(e.P1, e.P2);
             if (where == 1 && p.DistanceTo(e.P1) < Epsilon)
             {
                 e.P1 = p;
                 extended.Add(e);
             }
             if (where == 2 && p.DistanceTo(e.P2) < Epsilon)
             {
                 e.P2 = p;
                 extended.Add(e);
             }
         }
     if (extended.Count == 0) return false;
     // We try to link 2 extended edges to p to form a single edge.
     Point P1, P2;
     for (int i = 0; i < extended.Count; i++)
         if (extended[i] != null)
         {
             if (extended[i].P1 == p) P1 = extended[i].P2;
             else P1 = extended[i].P1;
             for (int j = i + 1; j < extended.Count; j++)
                 if (extended[j] != null)
                 {
                     if (extended[j].P1 == p) P2 = extended[j].P2;
                     else P2 = extended[j].P1;
                     if (p.OnLine(P1, P2))
                     {
                         // This works because extended[i] is a pointer!
                         extended[i].P1 = P1;
                         extended[i].P2 = P2;
                         edges.Remove(extended[j]);
                         extended[j] = null;
                         break;
                     }
                 }
         }
     return true;
 }
示例#6
0
        bool CreateEdgesFromPoints(Point p)
        {
            // Finds >= MinPointsInLine points (including point p) that are ~ colinear and
            // creates an edge from them. Can build multiple edges.
            bool created = false;
            Dictionary<double, List<int>> dex = new Dictionary<double, List<int>>();

            for (int i = 0; i < points.Count; i++)
                if (p.DistanceTo(points[i]) < MinPointsInLine * Epsilon)
                {
                    double angle;
                    if (Util.IsEqual(p.X, points[i].X))
                        angle = double.NaN;
                    else
                    {
                        angle = (p.Y - points[i].Y) / (p.X - points[i].X);
                        angle = Math.Truncate(angle / EpsilonAngle) * EpsilonAngle;
                    }
                    if (!dex.ContainsKey(angle))
                        dex[angle] = new List<int>(2 * MinPointsInLine);
                    dex[angle].Add(i);
                }
            foreach (KeyValuePair<double, List<int>> item in dex)
                if (item.Value.Count >= MinPointsInLine)
                {
                    // Merge the points from item.Value into a single edge.
                    List<int> indexes = item.Value;
                    Point min, max;
                    min = points[indexes[0]];
                    max = points[indexes[0]];
                    for (int i = 1; i < indexes.Count; i++)
                    {
                        min = Point.Min(min, points[indexes[i]]);
                        max = Point.Max(max, points[indexes[i]]);
                    }
                    // Remove the points.
                    indexes.Sort();
                    for (int i = indexes.Count - 1; i >= 0; i--)
                        points.RemoveAt(indexes[i]);
                    // Add the new edge.
                    Edge newEdge = new Edge(min, max);
                    if (!MergeEdge(newEdge))
                        edges.Add(newEdge);
                    created = true;
                }
            return created;
        }
示例#7
0
        /// <summary>
        /// Calculate Euclidean distance between a point and a finite line segment.
        /// </summary>
        /// 
        /// <param name="point">The point to calculate the distance to.</param>
        /// 
        /// <returns>Returns the Euclidean distance between this line segment and the specified point. Unlike
        /// <see cref="Line.DistanceToPoint"/>, this returns the distance from the finite segment. (0,0) is 5 units
        /// from the segment (0,5)-(0,8), but is 0 units from the line through those points.</returns>
        /// 
        public float DistanceToPoint(Point point)
        {
            float segmentDistance;

            switch (LocateProjection(point))
            {
                case ProjectionLocation.RayA:
                    segmentDistance = point.DistanceTo(start);
                    break;
                case ProjectionLocation.RayB:
                    segmentDistance = point.DistanceTo(end);
                    break;
                default:
                    segmentDistance = line.DistanceToPoint(point);
                    break;
            };

            return segmentDistance;
        }
示例#8
0
        public Point IntersectCircles(Point c1, double r1, Point c2, double r2, Point c3, double r3)
        {
            // To compute the intersection of the 3 circle, we intersect two of them, get 2
            // solutions, and see which one is on the third circle.

            // Step 1: Translate all circle centers so that c1 = (0, 0).
            c2 = c2 - c1;
            c3 = c3 - c1;

            // Step 2: Rotate all around (0, 0) so that c2 is now on Ox axis.
            double O = Math.Atan2(c2.Y, c2.X);
            c2 = c2.Rotate(-O);
            c3 = c3.Rotate(-O);

            // Step 3: Intersect circles (0, 0, r1) with (c2.X, 0, r2)
            Point p1 = new Point(), p2 = new Point(), sol;
            p1.X = p2.X = (r1 * r1 - r2 * r2 + c2.X * c2.X) / (2 * c2.X);
            // sqrt( negative zero ) = NaN
            if (r1 > p1.X) p1.Y = Math.Sqrt(r1 * r1 - p1.X * p1.X);
            else p1.Y = 0;
            p2.Y = - p1.Y;

            if (Util.IsEqual(p2.DistanceTo(c3), r3))
                sol = p2;
            else
                sol = p1;

            // Unapply step 2
            sol = sol.Rotate(O);

            // Unapply step 1
            sol = sol + c1;

            return sol;
        }
示例#9
0
        public override void Query(ref Point point, out Sample.Location sample)
        {
            sample.Distance = float.MaxValue;

            FullLine selectedLine = _Lines[0];

            if(_Lines.Length > 1)
            {
                foreach(FullLine line in _Lines)
                {
                    Point point1 = line.Point1;
                    Point point2 = line.Point2;

                    float newDistance = point.SquaredDistanceTo(point1, point2);

                    if(newDistance < sample.Distance)
                    {
                        sample.Distance = newDistance;

                        selectedLine = line;
                    }
                }
            }

            sample.Distance = point.DistanceTo(
                selectedLine.Point1, selectedLine.Point2, out sample.Intersection);
        }