示例#1
0
        /// <summary>
        /// Determines whether the last click is a double click.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="position">The position.</param>
        /// <returns>True if the click was a double click.</returns>
        internal static bool IsDoubleClick(object sender, Point position)
        {
            long clickTicks = DateTime.Now.Ticks;
            long elapsedTicks = clickTicks - lastClickTicks;
            long elapsedTime = elapsedTicks / TimeSpan.TicksPerMillisecond;
            bool quickClick = elapsedTime <= DoubleClickSpeed;
            bool senderMatch = lastSender != null && sender.Equals(lastSender.Target);

            if (senderMatch && quickClick && position.Distance(lastPosition) <= MaxMoveDistance)
            {
                // Double click!
                lastClickTicks = 0;
                lastSender = null;
                return true;
            }

            // Not a double click
            lastClickTicks = clickTicks;
            lastPosition = position;
            if (!quickClick)
            {
                lastSender = new WeakReference(sender);
            }

            return false;
        }
示例#2
0
        public double GetCentreToBoundaryDistance(ILinearEquation line)
        {
            var relativeOrigin = new Point(0, 0);
            var relativeBoundaryIntersection = GetRelativeIntersectionPoint(line);

            double distanceToBoundary = relativeOrigin.Distance(relativeBoundaryIntersection);

            return distanceToBoundary;
        }
示例#3
0
 /// <summary> 
 /// Computes the closest point on this line segment to another point.
 /// </summary>
 /// <param name="p">The point to find the closest point to.</param>
 /// <returns>
 /// A Coordinate which is the closest point on the line segment to the point p.
 /// </returns>
 public static Point ClosestPoint(Point p, Point LineSegFrom, Point LineSegTo)
 {
     var factor = ProjectionFactor(p, LineSegFrom, LineSegTo);
     if (factor > 0 && factor < 1)
         return Project(p, LineSegFrom, LineSegTo);
     var dist0 = LineSegFrom.Distance(p);
     var dist1 = LineSegTo.Distance(p);
     return dist0 < dist1 ? LineSegFrom : LineSegTo;
 }
 public static Triangle FromTwoPointsAndTwoLengths(Point point1, Point point2, double l1, double l2)
 {
     double l3 = point1.Distance(point2);
     double area = Triangle.AreaByLenghts(l1, l2, l3);
     double angle = Math.Asin(2 * area / (l1 * l3));
     Vector horizontal = point1.VectorTo(point1.AddX(1));
     double angle0 = horizontal.AngleWith(point1.VectorTo(point2));
     double x = l1 * Math.Cos(angle0 - angle);
     double y = l1 * Math.Sin(angle0 - angle);
     Point point3 = point1.AddX(x).AddY(y);
     return new Triangle(point1, point2, point3);
 }
    private static int func(Point p1, Point p2, Point p3)
    {
        int h, t;

        h = p1.Distance();

        t = p2.x + h;
        h += p2.Distance();

        if (p3.y == t)
        {
            h += p3.Distance();
        }

        return h;
    }
 private bool IsClosingALoop(LineString gpxLine, int currentIndex, double closestPointTolerance)
 {
     int indexOfLinePrefix = currentIndex - 1;
     var currentCoordinatePoint = new Point(gpxLine[currentIndex]);
     while (indexOfLinePrefix >= 0)
     {
         if (currentCoordinatePoint.Distance(new Point(gpxLine.Coordinates[indexOfLinePrefix])) >
             closestPointTolerance)
         {
             break;
         }
         indexOfLinePrefix--;
     }
     if (indexOfLinePrefix < 0)
     {
         return false;
     }
     var distance = indexOfLinePrefix > 0
             ? currentCoordinatePoint.Distance(new LineString(gpxLine.Coordinates.Take(indexOfLinePrefix + 1).ToArray()))
             : currentCoordinatePoint.Distance(new Point(gpxLine.Coordinates[indexOfLinePrefix]));
     return distance < closestPointTolerance;
 }
示例#7
0
 public static double Distance(Point a, Point b)
 {
     return a.Distance(b);
 }
示例#8
0
        private void CheckCurvatureQuality(IneqMesh ineqMesh)
        {
            List <Triangle> refList = new List <Triangle>();

            var edges = ineqMesh.Edges
                        .Where(e => e.P1.Boundary.Cast <bool>().Select((b, i) => new { b = b, i = i }).Where(bi => bi.b && e.P2.Boundary[bi.i]).Count() == 2)
                        .Select(e =>
            {
                var cf = e.P1.Boundary.Cast <bool>().Select((b, i) => new { b = b, i = i }).Where(bi => bi.b && e.P2.Boundary[bi.i]).ToArray();

                return(new
                {
                    bf1 = cf[0].i,
                    bf2 = cf[1].i,
                    p = e.Average(),
                    e = e,
                    length = e.P1.Distance(e.P2)
                });
            }).ToArray();

            foreach (var ee in edges)
            {
                if (!ee.e.Valid)
                {
                    continue;
                }
                Point origp = new Point(ee.p.X, ee.p.Y, ee.p.Z);

                ineqMesh.ProjectToEdge(ee.p, ee.bf1, ee.bf2, false);

                double dist = origp.Distance(ee.p);

                if (dist >= ee.length / 25.0d)
                {
                    var e = ee.e;

                    var trians = e
                                 .P1.Tetrahedrons.Intersect(e.P2.Tetrahedrons)
                                 .SelectMany(tt => tt.Triangles())
                                 .Where(tr => tr.Contains(e.P1) && tr.Contains(e.P2))
                                 .GroupBy(tr => tr)
                                 .Where(gr => gr.Count() == 1)
                                 .Select(gr => gr.Single());

                    refList.AddRange(trians);
                }
            }

            var centerPoints = ineqMesh.Tetrahedrons.SelectMany(t => t.Triangles()
                                                                .Where(tr => tr.BoundaryCount == 1 && tr.P1.Tetrahedrons.Intersect(tr.P2.Tetrahedrons).Intersect(tr.P3.Tetrahedrons).Count() == 1))
                               .Select(tr => new
            {
                bf        = tr.CommonBoundaryFlag.Value,
                p         = tr.Average(),
                tr        = tr,
                maxLength = Math.Max(Math.Max(tr.P1.Distance(tr.P2), tr.P1.Distance(tr.P3)), tr.P2.Distance(tr.P3))
            });

            foreach (var cp in centerPoints)
            {
                Point origp = new Point(cp.p.X, cp.p.Y, cp.p.Z);

                ineqMesh.ProjectToSurface(cp.p, 100, cp.bf, false);

                double dist = origp.Distance(cp.p);

                if (dist >= cp.maxLength / 25.0d)
                {
                    refList.Add(cp.tr);
                }
            }

            ineqMesh.RefineBoundaryTriangles(refList);

            ineqMesh.Jiggle(3);
        }
示例#9
0
        /// <summary>
        /// This method is used to remove overlapping tunnels. This method should be used every
        /// tunnel creation method to ensure no overlapping tunnels.
        ///
        /// It is done by tracing the line to see if every point collides with another cell.
        /// This method is the simplest way to do this. To hasten the process, only process
        /// boxes that is within the range.
        ///
        /// </summary>
        public void RemoveOverlapping()
        {
            foreach (Cell cell in cells)
            {
                // Gather all the cells.
                Point pointA = cell.LocationCenter;
                // TODO: Sometimes, there are more than one elements.
                List <Cell> PointBs = cell.ConnectedCell
                                      .Select(hash => cells.Single(c => c.GetHashCode() == hash))
                                      .ToList();

                // Select the unrelated cells that might be overlapping with this one's tunnel.
                // This will be the list that's scanned for overlap.
                // TODO: Unless you're generating hundreds of cells, for now, it scans everything.

                // Check for overlapping cells.
                foreach (Cell unrelatedCell in cells)
                {
                    // Check for its own and other connected cells.
                    //if (unrelatedCell == cell || cell.ConnectedCell.Contains(unrelatedCell.GetHashCode())) continue;
                    if (unrelatedCell == cell)
                    {
                        continue;
                    }

                    // Iterate through the connected cells.
                    foreach (Cell pointB in PointBs)
                    {
                        // You can't check your own.
                        if (unrelatedCell == pointB)
                        {
                            break;
                        }

                        // Create the path points.
                        //List<Point> pathPoints = CreatePathPoints(pointA, pointB.LocationCenter,
                        //    (int)pointA.Distance(pointB.LocationCenter));
                        List <Point> pathPoints = Utility.CreatePathPoints(pointA, pointB.LocationCenter,
                                                                           (int)pointA.Distance(pointB.LocationCenter));

                        // Iterate through them and find any collision.
                        // For some reason, sometimes it detects a collision, sometimes it doesn't.
                        // Sometimes it deletes the wrong connection altogether! It needs fixing.
                        // NOTE: It's fixed. See this commit's message.
                        foreach (Point point in pathPoints)
                        {
                            // Check if it collides.
                            if (unrelatedCell.CheckCollision(point))
                            {
                                // If it does, remove the tunnel connection.
                                cell.ConnectedCell.Remove(pointB.GetHashCode());
                                cells[cells.IndexOf(pointB)].ConnectedCell.Remove(cell.GetHashCode());

                                // There's no point on continuing since the tunnel is disconnected.
                                break;
                            }
                        }
                    }
                }
            }
        }
示例#10
0
        /***************************************************/
        /****       Public Methods - Point/Curve        ****/
        /***************************************************/

        public static double Distance(this Point point, Line line, bool infiniteSegment = false)
        {
            return(point.Distance(line.ClosestPoint(point, infiniteSegment)));
        }
示例#11
0
        /***************************************************/

        public static double Distance(this Point point, Circle circle)
        {
            return(point.Distance(circle.ClosestPoint(point)));
        }
示例#12
0
 public static bool ComparePosition(Point mainPoint, Point comparedPoint, double radius)
 {
     return(mainPoint.Distance(comparedPoint) < radius / (double)(LocationEnum.DistanceToKM));
 }
示例#13
0
        /// <summary>
        /// This one creates a tunnel layer, with given set of grid.
        /// </summary>
        /// <param name="width">Height of the canvas.</param>
        /// <param name="height"></param>
        /// <returns></returns>
        public async Task <GridLayerAsync> CreateTunnelLayer()
        {
            GridLayerAsync output = new GridLayerAsync(Width, Height);

            // Adjust the coordinates first.
            //AdjustNegativePoint();

            // We can't do that since it will invalidate the hash in tunnels.
            // So we have to increase the thing manually.
            // TODO: There must be a better way to do this.
            Point requiredIncrement = (GetLowestPoint() * new Point(-1, -1)) + new Point(2, 2);

            // Get highest point of the block.
            //Point highestPoint = GetHighestPoint() + requiredIncrement;
            Point highestPoint = GetHighestPoint() + requiredIncrement;

            // Now we get the size of the blocks.
            Point blockSize = new Point(highestPoint.X / Width, highestPoint.Y / Height);

            // After we get the info, now we can process the tunnels.
            // Now async!
            List <Task> tasks = new List <Task>();

            foreach (Tunnel tunnel in Tunnels)
            {
                Tunnel tempTunnel = tunnel;
                tasks.Add(Task.Run(async() => {
                    // Get the points in the tunnel.
                    Point cellA = Cells.Single(obj => obj.GetHashCode() == tempTunnel.CellHashA).LocationCenter + requiredIncrement;
                    Point cellB = Cells.Single(obj => obj.GetHashCode() == tempTunnel.CellHashB).LocationCenter + requiredIncrement;

                    // Turn the tunnels into points of path.
                    List <Point> tunnelPaths = new List <Point>();
                    if (tempTunnel.AnglePoint.Any())
                    {
                        // Insert the first one.
                        tunnelPaths.AddRange(Utility.CreatePathPoints(cellA, tempTunnel.AnglePoint.First() + requiredIncrement,
                                                                      (int)cellA.Distance(tempTunnel.AnglePoint.First() + requiredIncrement)));

                        // Insert the stuff in between.
                        if (tempTunnel.AnglePoint.Count > 1)
                        {
                            for (int a = 1; a <= tempTunnel.AnglePoint.Count; a++)
                            {
                                tunnelPaths.AddRange(Utility.CreatePathPoints(tunnelPaths[a - 1] + requiredIncrement,
                                                                              tunnelPaths[a] + requiredIncrement,
                                                                              (int)(tunnelPaths[a - 1] + requiredIncrement)
                                                                              .Distance(tunnelPaths[a] + requiredIncrement) / NodeDivider));
                            }
                        }

                        // Insert the last one.
                        tunnelPaths.AddRange(Utility.CreatePathPoints(cellB,
                                                                      tempTunnel.AnglePoint.Last() + requiredIncrement,
                                                                      (int)cellB.Distance(tempTunnel.AnglePoint.First() + requiredIncrement) / NodeDivider));
                    }
                    else
                    {
                        tunnelPaths.AddRange(Utility.CreatePathPoints(cellA + requiredIncrement,
                                                                      cellB + requiredIncrement,
                                                                      (int)cellA.Distance(cellB) / NodeDivider));
                    }

                    // Now we simply need to process all the points. We do this by iterating through all the
                    // blocks and change the one that collides with every points.
                    // Now async!
                    List <Task> tasks1 = new List <Task>();
                    for (int x = 0, xCoord = 0; x < Width && xCoord <= highestPoint.X; x++, xCoord += blockSize.X)
                    {
                        for (int y = 0, yCoord = 0; y < Height && yCoord <= highestPoint.Y; y++, yCoord += blockSize.Y)
                        {
                            int tx = x;
                            int ty = y;
                            int cx = xCoord;
                            int cy = yCoord;
                            tasks1.Add(Task.Run(() => {
                                // Make a temp cell to check for collision.
                                Cell blockCell = new Cell(blockSize, new Point(cx, cy));

                                // Iterate through path points.
                                foreach (Point point in tunnelPaths)
                                {
                                    // Check for collision. If so, set the grid appropriately and break.
                                    if (blockCell.CheckCollision(point))
                                    {
                                        output[tx, ty].Type = BlockType.Tunnel;
                                        break;
                                    }
                                }
                            }));
                        }
                    }
                    await Task.WhenAll(tasks1);
                }));
            }

            await Task.WhenAll(tasks);

            return(output);
        }
示例#14
0
        private void CanvasImage_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (Drawing)
            {
                Point clickPoint = new Point(e.GetPosition(sender as System.Windows.IInputElement));

                if (floodFill)
                {
                    CanvasImage.Source = drawer.FloodFill(clickPoint, floodFillColor);
                    StopDrawing();

                    floodFill = false;
                    return;
                }


                switch (selectedShapeType)
                {
                case (ShapeType.Line):
                case (ShapeType.Circle):
                case (ShapeType.ClippingLine):

                    if (previousClickPoints.Count >= 1)
                    {
                        Point p1 = previousClickPoints[0];
                        Point p2 = clickPoint;

                        Shape newShape;
                        switch (selectedShapeType)
                        {
                        case ShapeType.Line:
                            newShape = new Line(selectedShapeType.ToString(), p1, p2, 1, new Color(0, 0, 0, 255));
                            break;

                        case ShapeType.Circle:
                            newShape = new Circle(selectedShapeType.ToString(), p1, p2, new Color(0, 0, 0, 255));
                            break;

                        case ShapeType.ClippingLine:
                            newShape = new ClippingLine(selectedShapeType.ToString(), p1, p2, 1, new Color(0, 0, 0, 255), lastCreatedPoly);
                            break;

                        default:
                            throw new NotImplementedException();
                        }

                        CanvasImage.Source      = drawer.AddShape(newShape);
                        ShapeList.SelectedIndex = ShapeList.Items.Count - 1;

                        StopDrawing();
                    }
                    else
                    {
                        previousClickPoints.Add(clickPoint);
                        activeProjectionPoints.Add(CreateProjectionPoint(clickPoint));
                    }
                    break;

                case (ShapeType.Poly):

                    if (previousClickPoints.Count >= 2)
                    {
                        if (clickPoint.Distance(previousClickPoints[0]) < (double)FINISH_POLY_THRESHOLD)       // If is new point is near the first placed point then create polygon
                        {
                            Shape newShape = new Poly(selectedShapeType.ToString(), new List <Point>(previousClickPoints), 1, new Color(0, 0, 0, 255));
                            CanvasImage.Source = drawer.AddShape(newShape);

                            lastCreatedPoly = newShape as Poly;     // For Cyrus-Beck algorithm

                            ShapeList.SelectedIndex = ShapeList.Items.Count - 1;
                            StopDrawing();
                        }
                        else
                        {
                            previousClickPoints.Add(clickPoint);
                            activeProjectionPoints.Add(CreateProjectionPoint(clickPoint));
                        }
                    }
                    else
                    {
                        previousClickPoints.Add(clickPoint);
                        activeProjectionPoints.Add(CreateProjectionPoint(clickPoint));
                    }

                    break;

                case (ShapeType.Capsule):
                    if (previousClickPoints.Count == 2)
                    {
                        Point p1       = previousClickPoints[0];
                        Point p2       = previousClickPoints[1];
                        Point p3       = clickPoint;
                        Shape newShape = new Capsule(selectedShapeType.ToString(), p1, p2, p3, new Color(0, 0, 0, 255));
                        CanvasImage.Source      = drawer.AddShape(newShape);
                        ShapeList.SelectedIndex = ShapeList.Items.Count - 1;
                        StopDrawing();
                    }
                    else
                    {
                        previousClickPoints.Add(clickPoint);
                        activeProjectionPoints.Add(CreateProjectionPoint(clickPoint));
                    }
                    break;

                case (ShapeType.Rectangle):
                    if (previousClickPoints.Count == 1)
                    {
                        Point p1       = previousClickPoints[0];
                        Point p2       = clickPoint;
                        Shape newShape = new Rectangle(selectedShapeType.ToString(), p1, p2, new Color(0, 0, 0, 255));
                        CanvasImage.Source      = drawer.AddShape(newShape);
                        ShapeList.SelectedIndex = ShapeList.Items.Count - 1;
                        StopDrawing();
                    }
                    else
                    {
                        previousClickPoints.Add(clickPoint);
                        activeProjectionPoints.Add(CreateProjectionPoint(clickPoint));
                    }
                    break;


                default:
                    throw new NotImplementedException();
                }
            }
            else
            {
                DeselectShape();
            }
        }
示例#15
0
        /***************************************************/

        public static Output <Point, Point> CurveProximity(this Circle curve1, Circle curve2, double tolerance = Tolerance.Distance)
        {
            List <Point> cIntersections = curve1.CurveIntersections(curve2);

            if (cIntersections.Count > 0)
            {
                return new Output <Point, Point> {
                           Item1 = cIntersections[0], Item2 = cIntersections[0]
                }
            }
            ;

            Output <Point, Point> result = new Output <Point, Point>();

            //if (Math.Abs(curve1.Normal.IsParallel(curve2.Normal)) == 1) //TODO find solution for special case
            //{}

            Plane        ftPln1 = curve1.FitPlane();
            Plane        ftPln2 = curve2.FitPlane();
            List <Point> intPts = new List <Point>();
            Point        tmp    = null;

            if ((intPts = curve1.PlaneIntersections(ftPln2)).Count != 0)
            {
                if (intPts.Count == 1)
                {
                    tmp = intPts[0];
                }
                else
                {
                    if (intPts[0].Distance(curve2) < intPts[1].Distance(curve2))
                    {
                        tmp = intPts[0];
                    }
                    else
                    {
                        tmp = intPts[1];
                    }
                }
            }
            else if ((intPts = curve2.PlaneIntersections(ftPln1)).Count != 0)
            {
                if (intPts.Count == 1)
                {
                    if (tmp == null)
                    {
                        tmp = intPts[0];
                    }
                    else if (tmp.Distance(curve2) > intPts[0].Distance(curve1))
                    {
                        tmp = intPts[0];
                    }
                }
                else
                {
                    if (intPts[0].Distance(curve1) < intPts[1].Distance(curve1))
                    {
                        if (tmp == null)
                        {
                            tmp = intPts[0];
                        }
                        else if (tmp.Distance(curve2) > intPts[0].Distance(curve1))
                        {
                            tmp = intPts[0];
                        }
                    }
                    else
                    {
                        if (tmp == null)
                        {
                            tmp = intPts[1];
                        }
                        else if (tmp.Distance(curve2) > intPts[1].Distance(curve1))
                        {
                            tmp = intPts[1];
                        }
                    }
                }
            }

            Output <Point, Point> oldresult2 = new Output <Point, Point>();
            Output <Point, Point> result2    = new Output <Point, Point>();
            Output <Point, Point> oldresult  = new Output <Point, Point>();

            if (tmp != null)
            {
                if (tmp.IsOnCurve(curve1))
                {
                    result.Item1  = curve1.PointAtParameter(curve1.ParameterAtPoint(tmp) + 0.25);
                    result.Item2  = curve2.ClosestPoint(tmp);
                    result2.Item1 = curve1.PointAtParameter((curve1.ParameterAtPoint(tmp) + 0.75) % 1);
                    result2.Item2 = curve2.ClosestPoint(result2.Item1);
                }
                else
                {
                    result.Item2  = curve2.PointAtParameter(curve2.ParameterAtPoint(tmp) + 0.25);
                    result.Item1  = curve1.ClosestPoint(tmp);
                    result2.Item2 = curve2.PointAtParameter((curve2.ParameterAtPoint(tmp) + 0.75) % 1);
                    result2.Item1 = curve1.ClosestPoint(result2.Item2);
                }

                do
                {
                    oldresult.Item1 = result.Item1;
                    oldresult.Item2 = result.Item2;
                    result.Item1    = curve2.ClosestPoint(result.Item2);
                    result.Item2    = curve1.ClosestPoint(result.Item1);
                }while (oldresult.Item2.Distance(result.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result.Item1) > tolerance * tolerance);

                do
                {
                    oldresult2.Item1 = result2.Item1;
                    oldresult2.Item2 = result2.Item2;
                    result2.Item1    = curve2.ClosestPoint(result2.Item2);
                    result2.Item2    = curve1.ClosestPoint(result2.Item1);
                }while (oldresult2.Item2.Distance(result2.Item2) > tolerance * tolerance && oldresult2.Item1.Distance(result2.Item1) > tolerance * tolerance);

                if (result.Item1.Distance(result.Item2) < result2.Item1.Distance(result2.Item2))
                {
                    return(result);
                }
                else
                {
                    return(result2);
                }
            }

            Line intersect = new Line {
                Start = curve1.Centre, End = curve2.Centre
            };
            Point tmp1 = intersect.CurveProximity(curve1).Item1;
            Point tmp2 = intersect.CurveProximity(curve2).Item1;

            if (tmp == null)
            {
                tmp = tmp1;
            }
            if (tmp1.Distance(curve2) < tmp.Distance(curve1) || tmp1.Distance(curve2) < tmp.Distance(curve2))
            {
                tmp = tmp1;
            }

            if (tmp2.Distance(curve1) < tmp.Distance(curve1) || tmp2.Distance(curve1) < tmp.Distance(curve2))
            {
                tmp = tmp2;
            }

            if (tmp.IsOnCurve(curve1))
            {
                result.Item1 = tmp;
                result.Item2 = curve2.ClosestPoint(tmp);
            }
            else
            {
                result.Item2 = tmp;
                result.Item1 = curve1.ClosestPoint(tmp);
            }

            do
            {
                oldresult.Item1 = result.Item1;
                oldresult.Item2 = result.Item2;
                result.Item1    = curve2.ClosestPoint(result.Item2);
                result.Item2    = curve1.ClosestPoint(result.Item1);
            }while (oldresult.Item2.Distance(result.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result.Item1) > tolerance * tolerance);

            tmp           = curve1.PointAtParameter((curve1.ParameterAtPoint(result.Item1) + 0.6) % 1);
            result2.Item1 = tmp;
            result2.Item2 = curve2.ClosestPoint(tmp);

            do
            {
                oldresult2.Item1 = result2.Item1;
                oldresult2.Item2 = result2.Item2;
                result2.Item1    = curve2.ClosestPoint(result2.Item2);
                result2.Item2    = curve1.ClosestPoint(result2.Item1);
            }while (oldresult2.Item2.Distance(result2.Item2) > tolerance * tolerance && oldresult2.Item1.Distance(result2.Item1) > tolerance * tolerance);

            if (result.Item1.Distance(result.Item2) > result2.Item1.Distance(result2.Item2))
            {
                result = result2;
            }

            return(result);
        }
示例#16
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static Output <Point, Point> CurveProximity(this Line curve1, Line curve2, double tolerance = Tolerance.Distance)
        {
            List <Point> cIntersections = curve1.CurveIntersections(curve2);

            if (cIntersections.Count > 0)
            {
                return new Output <Point, Point> {
                           Item1 = cIntersections[0], Item2 = cIntersections[0]
                }
            }
            ;

            Point min1 = new Point();
            Point min2 = new Point();

            min1 = curve1.Start;
            min2 = curve2.Start;

            if (curve1.End.Distance(curve2) < min1.Distance(curve2))
            {
                min1 = curve1.End;
            }

            if (curve2.End.Distance(curve1) < min2.Distance(curve1))
            {
                min2 = curve2.End;
            }

            if (min2.Distance(curve1) < min1.Distance(curve2))
            {
                min1 = curve1.ClosestPoint(min2);
            }
            else
            {
                min2 = curve2.ClosestPoint(min1);
            }

            if (curve1.IsCoplanar(curve2))
            {
                return new Output <Point, Point> {
                           Item1 = min1, Item2 = min2
                }
            }
            ;

            Output <double, double> skewLineProximity = curve1.SkewLineProximity(curve2);

            double[] t  = new double[] { skewLineProximity.Item1, skewLineProximity.Item2 };
            double   t1 = Math.Max(Math.Min(t[0], 1), 0);
            double   t2 = Math.Max(Math.Min(t[1], 1), 0);
            Vector   e1 = curve1.End - curve1.Start;
            Vector   e2 = curve2.End - curve2.Start;

            if ((curve1.Start + e1 * t1).Distance(curve2.Start + e2 * t2) < min1.Distance(min2))
            {
                return new Output <Point, Point> {
                           Item1 = curve1.Start + e1 * t1, Item2 = curve2.Start + e2 * t2
                }
            }
            ;
            else
            {
                return new Output <Point, Point> {
                           Item1 = min1, Item2 = min2
                }
            };
        }
示例#17
0
        /***************************************************/

        public static Output <Point, Point> CurveProximity(this Arc curve1, Arc curve2, double tolerance = Tolerance.Distance)
        {
            List <Point> cIntersections = curve1.CurveIntersections(curve2);

            if (cIntersections.Count > 0)
            {
                return new Output <Point, Point> {
                           Item1 = cIntersections[0], Item2 = cIntersections[0]
                }
            }
            ;

            Output <Point, Point> result    = new Output <Point, Point>();
            Output <Point, Point> oldresult = new Output <Point, Point>();
            Output <Point, Point> result2   = new Output <Point, Point>();
            Output <Point, Point> result3   = new Output <Point, Point>();
            Output <Point, Point> result4   = new Output <Point, Point>();
            Output <Point, Point> result5   = new Output <Point, Point>();
            Output <Point, Point> result6   = new Output <Point, Point>();
            Plane        ftPln1             = curve1.FitPlane();
            Plane        ftPln2             = curve2.FitPlane();
            List <Point> fitPoints          = new List <Point>();
            bool         check = false;

            if ((fitPoints = curve1.PlaneIntersections(ftPln2)).Count > 0)
            {
                if (fitPoints.Count == 1)
                {
                    result.Item1 = fitPoints[0];
                    result.Item2 = curve2.ClosestPoint(fitPoints[0]);
                    check        = true;
                }
                else if (fitPoints.Count > 1)
                {
                    if (fitPoints[0].Distance(curve2) < fitPoints[1].Distance(curve2))
                    {
                        result.Item1 = fitPoints[0];
                        result.Item2 = curve2.ClosestPoint(fitPoints[0]);
                        check        = true;
                    }
                    else
                    {
                        result.Item1 = fitPoints[1];
                        result.Item2 = curve2.ClosestPoint(fitPoints[1]);
                        check        = true;
                    }
                }
            }

            if ((fitPoints = curve2.PlaneIntersections(ftPln1)).Count > 0)
            {
                if (check)
                {
                    if (fitPoints.Count == 1 && (fitPoints[0].Distance(curve1) < result.Item1.Distance(curve2)))
                    {
                        result.Item2 = fitPoints[0];
                        result.Item1 = curve1.ClosestPoint(fitPoints[0]);
                    }
                    else if (fitPoints.Count > 1)
                    {
                        if (fitPoints[0].Distance(curve1) < fitPoints[1].Distance(curve1))
                        {
                            if (fitPoints[0].Distance(curve1) < result.Item1.Distance(curve2))
                            {
                                result.Item2 = fitPoints[0];
                                result.Item1 = curve1.ClosestPoint(fitPoints[0]);
                            }
                        }
                        else
                        {
                            if (fitPoints[1].Distance(curve1) < result.Item1.Distance(curve2))
                            {
                                result.Item2 = fitPoints[1];
                                result.Item1 = curve1.ClosestPoint(fitPoints[1]);
                            }
                        }
                    }
                }
                else if (fitPoints.Count == 1)
                {
                    result.Item2 = fitPoints[0];
                    result.Item1 = curve1.ClosestPoint(fitPoints[0]);
                    check        = true;
                }
                else if (fitPoints.Count > 1)
                {
                    if (fitPoints[0].Distance(curve1) < fitPoints[1].Distance(curve1))
                    {
                        result.Item2 = fitPoints[0];
                        result.Item1 = curve1.ClosestPoint(fitPoints[0]);
                        check        = true;
                    }
                    else
                    {
                        result.Item2 = fitPoints[1];
                        result.Item1 = curve1.ClosestPoint(fitPoints[1]);
                        check        = true;
                    }
                }
            }

            if (check)
            {
                do
                {
                    oldresult.Item1 = result.Item1;
                    oldresult.Item2 = result.Item2;
                    result.Item1    = curve2.ClosestPoint(result.Item2);
                    result.Item2    = curve1.ClosestPoint(result.Item1);
                }while (oldresult.Item2.Distance(result.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result.Item1) > tolerance * tolerance);
            }

            check = false;
            Line intersect = new Line {
                Start = curve1.Centre(), End = curve2.Centre()
            };
            Point tmp1 = intersect.CurveProximity(curve1).Item2;
            Point tmp2 = intersect.CurveProximity(curve2).Item2;

            if (tmp1.Distance(curve2) < tmp2.Distance(curve1))
            {
                result2.Item1 = tmp1;
                result2.Item2 = curve2.ClosestPoint(tmp1);
            }
            else
            {
                result2.Item2 = tmp2;
                result2.Item1 = curve1.ClosestPoint(tmp2);
            }

            do
            {
                oldresult.Item1 = result2.Item1;
                oldresult.Item2 = result2.Item2;
                result2.Item1   = curve2.ClosestPoint(result2.Item2);
                result2.Item2   = curve1.ClosestPoint(result2.Item1);
            }while (oldresult.Item2.Distance(result2.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result2.Item1) > tolerance * tolerance);

            if (curve1.EndPoint().Distance(curve2.ClosestPoint(curve1.EndPoint())) < curve1.StartPoint().Distance(curve2.ClosestPoint(curve1.StartPoint())))
            {
                result3.Item1 = curve1.EndPoint();
                result3.Item2 = curve2.ClosestPoint(result3.Item1);
            }
            else
            {
                result3.Item1 = curve1.StartPoint();
                result3.Item2 = curve2.ClosestPoint(result3.Item1);
            }

            if (curve2.EndPoint().Distance(curve1.ClosestPoint(curve2.EndPoint())) < curve2.StartPoint().Distance(curve1.ClosestPoint(curve2.StartPoint())))
            {
                result4.Item2 = curve2.EndPoint();
                result4.Item1 = curve1.ClosestPoint(result4.Item2);
            }
            else
            {
                result4.Item2 = curve2.StartPoint();
                result4.Item1 = curve1.ClosestPoint(result4.Item2);
            }

            do
            {
                oldresult.Item1 = result3.Item1;
                oldresult.Item2 = result3.Item2;
                result3.Item1   = curve2.ClosestPoint(result3.Item2);
                result3.Item2   = curve1.ClosestPoint(result3.Item1);
            }while (oldresult.Item2.Distance(result3.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result3.Item1) > tolerance * tolerance);

            do
            {
                oldresult.Item1 = result4.Item1;
                oldresult.Item2 = result4.Item2;
                result4.Item1   = curve2.ClosestPoint(result4.Item2);
                result4.Item2   = curve1.ClosestPoint(result4.Item1);
            }while (oldresult.Item2.Distance(result4.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result4.Item1) > tolerance * tolerance);

            result5.Item2 = curve2.PointAtParameter(0.5);
            result5.Item1 = curve1.ClosestPoint(result5.Item2);
            result6.Item1 = curve1.PointAtParameter(0.5);
            result6.Item2 = curve2.ClosestPoint(result6.Item1);

            do
            {
                oldresult.Item1 = result5.Item1;
                oldresult.Item2 = result5.Item2;
                result5.Item1   = curve2.ClosestPoint(result5.Item2);
                result5.Item2   = curve1.ClosestPoint(result5.Item1);
            }while (oldresult.Item2.Distance(result5.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result5.Item1) > tolerance * tolerance);

            do
            {
                oldresult.Item1 = result6.Item1;
                oldresult.Item2 = result6.Item2;
                result6.Item1   = curve2.ClosestPoint(result6.Item2);
                result6.Item2   = curve1.ClosestPoint(result6.Item1);
            }while (oldresult.Item2.Distance(result6.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result6.Item1) > tolerance * tolerance);

            if (result.Item1 == null || result.Item2 == null)
            {
                result = result2;
            }

            if (result2.Item2.Distance(result2.Item1) < result.Item1.Distance(result.Item2))
            {
                result = result2;
            }

            if (result3.Item2.Distance(result3.Item1) < result.Item1.Distance(result.Item2))
            {
                result = result3;
            }

            if (result4.Item2.Distance(result4.Item1) < result.Item1.Distance(result.Item2))
            {
                result = result4;
            }

            if (result5.Item2.Distance(result5.Item1) < result.Item1.Distance(result.Item2))
            {
                result = result5;
            }

            if (result6.Item2.Distance(result6.Item1) < result.Item1.Distance(result.Item2))
            {
                result = result6;
            }

            return(result);
        }
示例#18
0
 public static bool IsCloseTo(this Point p1, Point p2, int tollerance)
 {
     return(p1.Distance(p2) <= tollerance);
 }
示例#19
0
 public double Dist(ICoord p)
 {
     return(Point.Distance(p.GetCoord(), this.coord));
 }
示例#20
0
 private static Boolean CloseEnough(Point p1, Point p2)
 {
     return(Point.Distance(p1, p2) < EPSILON);
 }
示例#21
0
        public static IFeature GetNearestFeature(ICoordinate coordinate, IEnumerable<IFeature> features, double tolerance)
        {
            var minDistance = tolerance;
            IFeature minDistanceFeature = null;

            var point = new Point(coordinate);

            foreach (var feature in features)
            {
                if(feature.Geometry == null) continue;

                var distance = point.Distance(feature.Geometry);
                if (distance <= minDistance)
                {
                    minDistance = distance;
                    minDistanceFeature = feature;
                }
            }

            return minDistanceFeature;
        }
示例#22
0
    Point GetEndPoint(Point startPoint, int minSteps, int maxSteps, int maxSize)
    {
        Point endPoint = null;
        var maxTryes = maxSteps * maxSteps;
        var distance = 0;

        do {
            endPoint = new Point(random.Next(0, maxSize), random.Next(0, maxSize));
            maxTryes--;
            distance = startPoint.Distance(endPoint);
        } while (maxTryes > 0 && (distance < minSteps || distance >= maxSteps));

        if (maxTryes == 0) {
            return null;
        }

        return endPoint;
    }
示例#23
0
        /// <summary>
        /// Determines if the polygon is within the specified distance from the point.
        /// </summary>
        /// <param name="polygon"></param>
        /// <param name="point"></param>
        /// <param name="distance"></param>
        /// <returns></returns>
        public static bool WithinDistance(this Polygon polygon, Point point, double distance)
        {
            if (Null(polygon, point))
                return false;

            return point.Distance(polygon) < distance;
        }
示例#24
0
 public int Should_Calculate_Manhatan_Distance(Point point)
 {
     return(point.Distance());
 }
示例#25
0
        /// <summary>
        /// Calculates the shortest distance to the point.
        /// </summary>
        /// <param name="multipoint"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static double Distance(this Multipoint multipoint, Point point)
        {
            AssertNotNull(multipoint, point);

            return point.Distance(multipoint);
        }
示例#26
0
        /***************************************************/

        public static double Distance(this Point point, Arc arc)
        {
            return(point.Distance(arc.ClosestPoint(point)));
        }
示例#27
0
        /// <summary>
        /// Calculates the shortest distance to the point.
        /// </summary>
        /// <param name="polyline"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static double Distance(this Polyline polyline, Point point)
        {
            AssertNotNull(polyline, point);

            return point.Distance(polyline);
        }
示例#28
0
        /***************************************************/

        public static double Distance(this Point point, PolyCurve curve)
        {
            return(point.Distance(curve.ClosestPoint(point)));
        }
示例#29
0
        /// <summary>
        /// Calculates the shortest distance to the point.
        /// </summary>
        /// <param name="polygon"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static double Distance(this Polygon polygon, Point point)
        {
            AssertNotNull(polygon, point);

            return point.Distance(polygon);
        }
示例#30
0
        /***************************************************/

        public static bool IsEqual(this Point pt, Point other, double tolerance = Tolerance.Distance)
        {
            return(pt.Distance(other) < tolerance);
        }
示例#31
0
        /// <summary>
        /// Determines if the multipoint is within the specified distance from the point.
        /// </summary>
        /// <param name="multipoint"></param>
        /// <param name="point"></param>
        /// <param name="distance"></param>
        /// <returns></returns>
        public static bool WithinDistance(this Multipoint multipoint, Point point, double distance)
        {
            if (Null(multipoint, point))
                return false;

            return point.Distance(multipoint) < distance;
        }
示例#32
0
            /// <summary> 
            /// Computes the distance from a point p to a line segment AB.
            /// Note: NON-ROBUST!
            /// </summary>
            /// <param name="p">The point to compute the distance for.</param>
            /// <param name="A">One point of the line.</param>
            /// <param name="B">Another point of the line (must be different to A).</param>
            /// <returns> The distance from p to line segment AB.</returns>
            public static double DistancePointLine(Point p, Point A, Point B)
            {
                // if start == end, then use pt distance
                if (A.Equals(B))
                    return p.Distance(A);

                // otherwise use comp.graphics.algorithms Frequently Asked Questions method
                /*(1)     	      AC dot AB
                            r =   ---------
                                  ||AB||^2
             
                            r has the following meaning:
                            r=0 Point = A
                            r=1 Point = B
                            r<0 Point is on the backward extension of AB
                            r>1 Point is on the forward extension of AB
                            0<r<1 Point is interior to AB
                */

                double r = ((p.X - A.X) * (B.X - A.X) + (p.Y - A.Y) * (B.Y - A.Y))
                            /
                            ((B.X - A.X) * (B.X - A.X) + (B.Y - A.Y) * (B.Y - A.Y));

                if (r <= 0.0) return p.Distance(A);
                if (r >= 1.0) return p.Distance(B);


                /*(2)
                                (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
                            s = -----------------------------
                                            Curve^2

                            Then the distance from C to Point = |s|*Curve.
                */

                double s = ((A.Y - p.Y) * (B.X - A.X) - (A.X - p.X) * (B.Y - A.Y))
                            /
                            ((B.X - A.X) * (B.X - A.X) + (B.Y - A.Y) * (B.Y - A.Y));

                return Math.Abs(s) * Math.Sqrt(((B.X - A.X) * (B.X - A.X) + (B.Y - A.Y) * (B.Y - A.Y)));
            }
示例#33
0
    //Method - This is the main body of A*
    List <Point> GetPath(Index start, Index end)
    {
        //get the start and end Point from the grid
        Point startPoint = grid[start.x, start.y];
        Point endPoint   = grid[end.x, end.y];

        //create the open and closed lists
        PriorityQueue open   = new PriorityQueue();
        List <Point>  closed = new List <Point>();

        //push the starting Point int the Open PriorityQueue
        open.Push(startPoint);

        //keep looping while the Priority Queue isn't empty
        while (open.Length > 0)
        {
            //get the first Point (will always have the lowest f value)
            Point q = open.Pop();

            //get the surround points, (only does the for 4 direct sides)
            Point[] nextMoves = new Point[4];
            nextMoves[0] = grid[q.index.x, q.index.y + 1];
            nextMoves[1] = grid[q.index.x + 1, q.index.y];
            nextMoves[2] = grid[q.index.x, q.index.y - 1];
            nextMoves[3] = grid[q.index.x - 1, q.index.y];

            //cycle through the new point
            foreach (Point p in nextMoves)
            {
                //check if the current Point is the end point
                if (p.Equals(endPoint))
                {
                    p.parentPoint = q;
                    closed.Add(p);
                    return(ReturnPathList(endPoint, startPoint));
                }

                //calculate this Point heuristic values
                p.g = q.g + q.Distance(p);
                p.h = endPoint.Distance(p);
                p.f = p.g + p.h;

                //if the Point isn't over terrain or is blocked, ignore
                if (p.state == pointState.blocked || p.state == pointState.space)
                {
                    continue;
                }
                //check to see if this Point is already in the closed list
                else if (closed.Contains(p))
                {
                    //remove that preexisting value if its worse then the current one
                    int index = closed.IndexOf(p);
                    if (closed[index].f <= p.f)
                    {
                        continue;
                    }
                    else
                    {
                        closed.RemoveAt(index);
                        p.parentPoint = q;
                        open.Push(p);
                    }
                }
                //check to see if this Point is already in the open list
                else if (open.Contains(p))
                {
                    //remove that preexisting value if its worse then the current one
                    int index = open.IndexOf(p);
                    if (open.GetFAt(index) <= p.f)
                    {
                        continue;
                    }
                    else
                    {
                        open.RemoveAt(index);
                        p.parentPoint = q;
                        open.Push(p);
                    }
                }
                //if the Point doesn't already exist in either list, add it to the open list
                else
                {
                    p.parentPoint = q;
                    open.Push(p);
                }
            }
            //set the state to visited
            q.state = pointState.visited;
            //add to the closed list (has already been removed from the open list)
            closed.Add(q);
        }

        //get the path from the closed list
        return(ReturnPathList(endPoint, startPoint));
    }
示例#34
0
 public Node(Point pos_, float G_, Point fromPos, Point toPos)
 {
     pos = pos_;
     G = G_ + pos.Distance(fromPos);
     H = pos.Distance(toPos);
     F = G + H;
 }
示例#35
0
 public virtual int Distance(VisibleObject obj)
 {
     return(Point.Distance(obj.X, obj.Y, X, Y));
 }
示例#36
0
        Element ElementNearestToPoint(Point position, Element caller, out double minDistance, out ThumbPosition nearestThumbPosition)
        {
            minDistance = double.PositiveInfinity;
            Element hitElement = null;
            nearestThumbPosition = ThumbPosition.NotSet;

            foreach (Element element in UnconnectedElements)
            {
                if(element == caller) continue;

                foreach (ThumbPosition thumbPosition in element.AvailableIncomingConnectors)
                {
                    Point elementLocation = element.GetCanvasThumbPosition(thumbPosition);
                    double distance = position.Distance(elementLocation);
                    if(distance < minDistance)
                    {
                        minDistance = distance;
                        hitElement = element;
                        nearestThumbPosition = thumbPosition;
                    }
                }
            }

            return hitElement;
        }
示例#37
0
        public void SelectTarget(Point target)
        {
            MapManager mapManager  = game.MapManager;
            Player     player      = game.Player;
            Point      playerPoint = new Point {
                X = player.X, Y = player.Y
            };

            game.Logger.Add(string.Format("{0} стреляет из {1}", player.Name, Name));
            Actor dummy = new Actor(game)
            {
                Attack       = attack,
                AttackChance = attackChance,
                Name         = Name
            };

            foreach (RogueSharp.Cell cell in mapManager.Map.GetCellsAlongLine(player.X, player.Y, target.X, target.Y))
            {
                Point cellPoint = new Point {
                    X = cell.X, Y = cell.Y
                };

                Enemy enemy = mapManager.GetEnemyAt(cell.X, cell.Y);
                if (enemy != null)
                {
                    game.CommandSystem.Attack(dummy, enemy);
                    return;
                }

                if (cell.IsWalkable)
                {
                    if (Point.Distance(playerPoint, cellPoint) > maxDistance)
                    {
                        game.Logger.Add(string.Format("{0}(РДС) / {1}(макс дист). Пуля не долетела до цели.", Point.Distance(playerPoint, cellPoint), maxDistance));
                        return;
                    }
                    continue;
                }

                if (cell.X == player.X && cell.Y == player.Y)
                {
                    continue;
                }

                return;
            }
        }
示例#38
0
        public static IEnumerable<IFeature> GetFeaturesInRange(ICoordinate coordinate, IEnumerable<IFeature> features, double tolerance)
        {
            var minDistance = tolerance;
            var point = new Point(coordinate);

            return (from feature in features
                    where feature.Geometry != null // Distance method requires a defined Geometry
                    let distance = point.Distance(feature.Geometry)
                    where distance <= minDistance
                    select feature).ToList();
        }
示例#39
0
        public static List <Point> FindBoundingContourPoints(IEnumerable <Point> contours, Point[] boundingPoints)
        {
            if (boundingPoints.Length != 2)
            {
                return(null);
            }

            List <Point> contourPoints           = contours.ToList();
            List <Point> actualContourPointsList = new List <Point>();

            foreach (Point point in contourPoints)
            {
                if (!actualContourPointsList.Contains(point))
                {
                    actualContourPointsList.Add(point);
                }
                else
                {
                    break;
                }
            }

            Point firstPoint = boundingPoints[0];
            Point lastPoint  = boundingPoints[1];

            int   firstIndex = -1;
            int   lastIndex  = -1;
            float p1Dist     = 10000;
            float p2Dist     = 10000;

            //Loop through all the points and find the closest points to the bounds
            for (int i = 0; i < actualContourPointsList.Count; i++)
            {
                float dist1 = firstPoint.Distance(actualContourPointsList[i]);
                float dist2 = lastPoint.Distance(actualContourPointsList[i]);

                if (dist1 < p1Dist)
                {
                    p1Dist = dist1;
                    //closestFirstPoint = contourPoints[i];
                    firstIndex = i;
                }

                if (dist2 < p2Dist)
                {
                    p2Dist = dist2;
                    //closestLastPoint = contourPoints[i];
                    lastIndex = i;
                }
            }

            List <Point> result = new List <Point>();

            //Return all the points that lie between first index and last index
            int start = firstIndex <= lastIndex ? firstIndex : lastIndex;
            int end   = lastIndex >= firstIndex ? lastIndex : firstIndex;

            for (int j = start; j <= end; j++)
            {
                result.Add(actualContourPointsList[j]);
            }

            return(result);
        }
示例#40
0
    /// <summary>
    /// The magic is here
    /// </summary>
    private void CalculateOutput()
    {
        Mat matGray = null;

        // instead of regular Grayscale, we use BGR -> HSV and take Hue channel as
        // source
        if (Settings.GrayMode == ScannerSettings.ColorMode.HueGrayscale)
        {
            var   matHSV      = matInput_.CvtColor(ColorConversionCodes.RGB2HSV);
            Mat[] hsvChannels = matHSV.Split();
            matGray = hsvChannels[0];
        }
        // Alternative: just plain BGR -> Grayscale
        else
        {
            matGray = matInput_.CvtColor(ColorConversionCodes.BGR2GRAY);
        }

        // scale down if necessary
        var   matScaled = matGray;
        float sx = 1, sy = 1;

        if (Settings.Scale != 0)
        {
            if (matGray.Width > Settings.Scale)
            {
                sx = (float)Settings.Scale / matGray.Width;
            }
            if (matGray.Height > Settings.Scale)
            {
                sy = (float)Settings.Scale / matGray.Height;
            }

            matScaled = matGray.Resize(new Size(Math.Min(matGray.Width, Settings.Scale), Math.Min(matGray.Height, Settings.Scale)));
        }

        // reduce noise
        var matBlur = matScaled;

        if (Settings.NoiseReduction != 0)
        {
            int medianKernel = 11;

            // calculate kernel scale
            double kernelScale = Settings.NoiseReduction;
            if (0 == Settings.Scale)
            {
                kernelScale *= Math.Max(matInput_.Width, matInput_.Height) / 512.0;
            }

            // apply scale
            medianKernel = (int)(medianKernel * kernelScale + 0.5);
            medianKernel = medianKernel - (medianKernel % 2) + 1;

            if (medianKernel > 1)
            {
                matBlur = matScaled.MedianBlur(medianKernel);
            }
        }

        // detect edges with our 'adaptive' algorithm that computes bounds automatically with
        // image's mean value
        var matEdges = matBlur.AdaptiveEdges(Settings.EdgesTight);

        // now find contours
        Point[][]        contours;
        HierarchyIndex[] hierarchy;
        Cv2.FindContours(matEdges, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxNone, null);

        // check contours and drop those we consider "noise", all others put into a single huge "key points" map
        // also, detect all almost-rectangular contours with big area and try to determine whether they're exact match
        List <Point>   keyPoints      = new List <Point>();
        List <Point[]> goodCandidates = new List <Point[]>();
        double         referenceArea  = matScaled.Width * matScaled.Height;

        foreach (Point[] contour in contours)
        {
            double length = Cv2.ArcLength(contour, true);

            // drop mini-contours
            if (length >= 25.0)
            {
                Point[] approx = Cv2.ApproxPolyDP(contour, length * 0.01, true);
                keyPoints.AddRange(approx);

                if (approx.Length >= 4 && approx.Length <= 6)
                {
                    double area = Cv2.ContourArea(approx);
                    if (area / referenceArea >= Settings.ExpectedArea)
                    {
                        goodCandidates.Add(approx);
                    }
                }
            }
        }

        // compute convex hull, considering we presume having an image of a document on more or less
        // homogeneous background, this accumulated convex hull should be the document bounding contour
        Point[] hull        = Cv2.ConvexHull(keyPoints);
        Point[] hullContour = Cv2.ApproxPolyDP(hull, Cv2.ArcLength(hull, true) * 0.01, true);

        // find best guess for our contour
        Point[] paperContour = GetBestMatchingContour(matScaled.Width * matScaled.Height, goodCandidates, hullContour);
        if (null == paperContour)
        {
            shape_     = null;
            dirty_     = false;
            matOutput_ = matInput_;
            return;
        }

        // exact hit - we have 4 corners
        if (paperContour.Length == 4)
        {
            paperContour = SortCorners(paperContour);
        }
        // some hit: we either have 3 points or > 4 which we can try to make a 4-corner shape
        else if (paperContour.Length > 2)
        {
            // yet contour might contain too much points: along with calculation inaccuracies we might face a
            // bended piece of paper, missing corner etc.
            // the solution is to use bounding box
            RotatedRect bounds      = Cv2.MinAreaRect(paperContour);
            Point2f[]   points      = bounds.Points();
            Point[]     intPoints   = Array.ConvertAll(points, p => new Point(Math.Round(p.X), Math.Round(p.Y)));
            Point[]     fourCorners = SortCorners(intPoints);

            // array.ClosestElement is not efficient but we can live with it since it's quite few
            // elements to search for
            System.Func <Point, Point, double> distance = (Point x, Point y) => Point.Distance(x, y);
            Point[] closest = new Point[4];
            for (int i = 0; i < fourCorners.Length; ++i)
            {
                closest[i] = paperContour.ClosestElement(fourCorners[i], distance);
            }

            paperContour = closest;
        }

        // scale contour back to input image coordinate space - if necessary
        if (sx != 1 || sy != 1)
        {
            for (int i = 0; i < paperContour.Length; ++i)
            {
                Point2f pt = paperContour[i];
                paperContour[i] = new Point2f(pt.X / sx, pt.Y / sy);
            }
        }

        // un-wrap
        var  matUnwrapped        = matInput_;
        bool needConvertionToBGR = true;

        if (paperContour.Length == 4)
        {
            matUnwrapped = matInput_.UnwrapShape(Array.ConvertAll(paperContour, p => new Point2f(p.X, p.Y)));

            // automatic color converter
            bool convertColor = (ScannerSettings.DecolorizationMode.Always == Settings.Decolorization);
            if (ScannerSettings.DecolorizationMode.Automatic == Settings.Decolorization)
            {
                convertColor = !IsColored(matUnwrapped);
            }

            // perform color conversion to b&w
            if (convertColor)
            {
                matUnwrapped = matUnwrapped.CvtColor(ColorConversionCodes.BGR2GRAY);

                // we have some constants for Adaptive, but this can be improved with some 'educated guess' for the constants depending on input image
                if (ScannerSettings.ScanType.Adaptive == Settings.ColorThreshold)
                {
                    matUnwrapped = matUnwrapped.AdaptiveThreshold(255, AdaptiveThresholdTypes.MeanC, ThresholdTypes.Binary, 47, 25);
                }
                // Otsu doesn't need our help, decent on it's own
                else
                {
                    matUnwrapped = matUnwrapped.Threshold(0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
                }
            }
            else
            {
                needConvertionToBGR = false;
            }
        }

        // assign result
        shape_ = paperContour;

        matOutput_ = matUnwrapped;
        if (needConvertionToBGR)
        {
            matOutput_ = matOutput_.CvtColor(ColorConversionCodes.GRAY2BGR);                        // to make it compatible with input texture
        }
        // mark we're good
        dirty_ = false;
    }
示例#41
0
        /// <summary>
        /// This method is used to create the cell wall layer of a grid.
        /// </summary>
        /// <returns></returns>
        public async Task <GridLayerAsync> CreateCellWallLayer()
        {
            GridLayerAsync output = new GridLayerAsync(Width, Height);

            Point requiredIncrement = (GetLowestPoint() * new Point(-1, -1)) + new Point(2, 2);

            // Get highest point of the block.
            Point highestPoint = GetHighestPoint() + requiredIncrement;

            // Now we get the size of the blocks.
            Point blockSize = new Point(highestPoint.X / Width, highestPoint.Y / Height);

            // After getting the info, we can process the cells.
            // Now async!
            List <Task> tasks = new List <Task>();

            foreach (Cell cell in Cells)
            {
                Cell tempCell = cell;
                tasks.Add(Task.Run(async() => {
                    // Each cell has 4 points. We get all those 4 points.
                    Point topLeft     = tempCell.Location + requiredIncrement;
                    Point topRight    = new Point(tempCell.Location.X, tempCell.Location.Y + tempCell.Size.Y) + requiredIncrement;
                    Point bottomLeft  = new Point(tempCell.Location.X + tempCell.Size.X, tempCell.Location.Y) + requiredIncrement;
                    Point bottomRight = tempCell.Location + tempCell.Size + requiredIncrement;

                    //Create the path points.
                    List <Point> cellPaths = new List <Point>();

                    cellPaths.AddRange(Utility.CreatePathPoints(topLeft, topRight, (int)topLeft.Distance(topRight) / NodeDivider));
                    cellPaths.AddRange(Utility.CreatePathPoints(topRight, bottomRight, (int)topRight.Distance(bottomRight) / NodeDivider));
                    cellPaths.AddRange(Utility.CreatePathPoints(bottomRight, bottomLeft, (int)bottomRight.Distance(bottomLeft) / NodeDivider));
                    cellPaths.AddRange(Utility.CreatePathPoints(bottomLeft, topLeft, (int)bottomLeft.Distance(topLeft) / NodeDivider));


                    //Now we simply need to process all the points.We do this by iterating through all the
                    // blocks and change the one that collides with every points.
                    // Now async!
                    List <Task> tasks1 = new List <Task>();
                    for (int x = 0, xCoord = 0; x < Width && xCoord <= highestPoint.X; x++, xCoord += blockSize.X)
                    {
                        for (int y = 0, yCoord = 0; y < Height && yCoord <= highestPoint.Y; y++, yCoord += blockSize.Y)
                        {
                            int tx = x;
                            int ty = y;
                            int cx = xCoord;
                            int cy = yCoord;
                            tasks1.Add(Task.Run(() => {
                                // Make a temp cell to check for collision.
                                Cell blockCell = new Cell(blockSize, new Point(cx, cy));

                                // Iterate through path points.
                                foreach (Point point in cellPaths)
                                {
                                    // Check for collision. If so, set the grid appropriately and break.
                                    if (blockCell.CheckCollision(point))
                                    {
                                        output[tx, ty].Type = BlockType.RoomWall;
                                        break;
                                    }
                                }
                            }));
                        }
                    }
                    await Task.WhenAll(tasks1);
                }));
            }

            await Task.WhenAll(tasks);

            return(output);
        }
示例#42
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GesturesContentViewRenderer"/> class.
        /// </summary>
        /// Element created at 07/11/2014,3:31 PM by Charles
        public GesturesContentViewRenderer()
        {
            // Single Tap
            _recognizers.Add(new UITapGestureRecognizer((x) =>
            {
                if (x.State == UIGestureRecognizerState.Ended)
                {
                    var viewpoint = x.LocationInView(this);
                    Element.ProcessGesture(new GestureResult {
                        GestureType = GestureType.SingleTap, Direction = Directionality.None, Origin = viewpoint.ToPoint()
                    });
                }
            })
            {
                NumberOfTapsRequired = 1
            });
            //Double Tap
            _recognizers.Add(new UITapGestureRecognizer((x) =>
            {
                if (x.State == UIGestureRecognizerState.Ended)
                {
                    var viewpoint = x.LocationInView(this);
                    Element.ProcessGesture(new GestureResult {
                        GestureType = GestureType.DoubleTap, Direction = Directionality.None, Origin = viewpoint.ToPoint()
                    });
                }
            })
            {
                NumberOfTapsRequired = 2
            });
            // Longpress
            _recognizers.Add(new UILongPressGestureRecognizer((x) =>
            {
                if (x.State == UIGestureRecognizerState.Ended)
                {
                    var viewpoint = x.LocationInView(this);
                    Element.ProcessGesture(new GestureResult {
                        GestureType = GestureType.DoubleTap, Direction = Directionality.None, Origin = viewpoint.ToPoint()
                    });
                }
            }));
            // Swipe
            _recognizers.Add(new UISwipeGestureRecognizer((x) =>
            {
                if (x.State == UIGestureRecognizerState.Began)
                {
                    _swipeStart = x.LocationInView(this).ToPoint();
                }
                if (x.State == UIGestureRecognizerState.Ended)
                {
                    var endpoint  = x.LocationInView(this).ToPoint();
                    var distance  = _swipeStart.Distance(endpoint);
                    var distanceX = Math.Abs(_swipeStart.X - endpoint.X);
                    var distanceY = Math.Abs(_swipeStart.Y - endpoint.Y);
                    var direction = Directionality.None;
                    direction    |= ((x.Direction & UISwipeGestureRecognizerDirection.Left) == UISwipeGestureRecognizerDirection.Left ? Directionality.Left : Directionality.None);
                    direction    |= ((x.Direction & UISwipeGestureRecognizerDirection.Right) == UISwipeGestureRecognizerDirection.Right ? Directionality.Right : Directionality.None);
                    direction    |= ((x.Direction & UISwipeGestureRecognizerDirection.Up) == UISwipeGestureRecognizerDirection.Up ? Directionality.Up : Directionality.None);
                    direction    |= ((x.Direction & UISwipeGestureRecognizerDirection.Down) == UISwipeGestureRecognizerDirection.Down ? Directionality.Down : Directionality.None);

                    Element.ProcessGesture(new GestureResult {
                        Direction = direction, GestureType = GestureType.Swipe, HorizontalDistance = distanceX, VerticalDistance = distanceY, Origin = _swipeStart, Length = distance
                    });
                }
            })
            {
                Direction = AllDirections, NumberOfTouchesRequired = 1
            });
        }
示例#43
0
 public double DistanceFromJoyPad(Point point)
 {
     return(point.Distance(Center));
 }
示例#44
0
 public static double Distance(this Point self, Point other) => self.Distance(other.X, other.Y);
示例#45
0
        public async Task <IEnumerable <Contact> > GetNearbyAsync(double userLongitude, double userLatitude)
        {
            var allCDAs = await GetAllAsync();

            var userPoint   = new Point(userLongitude, userLatitude);
            var feedOptions = new FeedOptions {
                MaxItemCount = -1, EnableCrossPartitionQuery = true
            };

            // Find the CDAs with hometowns by the user
            var hometownCDAQuery = DocClient.CreateDocumentQuery <Contact>(allCDACollectionLink, feedOptions)
                                   .Where(cda => userPoint.Distance(cda.Hometown.Position) < maximumCDADistance)
                                   .AsDocumentQuery();

            List <Contact> hometownCDAs = new List <Contact>();

            while (hometownCDAQuery.HasMoreResults)
            {
                hometownCDAs.AddRange(await hometownCDAQuery.ExecuteNextAsync <Contact>());
            }

            // Find the CDAs who checked in within the last 7Days
            var daysAgo = DateTimeOffset.UtcNow.AddDays(-7).Date;

            var latestClosestPositionsQuery = DocClient.CreateDocumentQuery <LocationUpdate>(locationCollectionLink, feedOptions)
                                              .Where(ll => ll.InsertTime > daysAgo)
                                              .Where(ll => userPoint.Distance(ll.Position) < maximumCDADistance)
                                              .AsDocumentQuery();

            List <LocationUpdate> latestClosestPositions = new List <LocationUpdate>();

            while (latestClosestPositionsQuery.HasMoreResults)
            {
                latestClosestPositions.AddRange(await latestClosestPositionsQuery.ExecuteNextAsync <LocationUpdate>());
            }

            // Make sure only the most recent update per CDA is grabbed
            var mostRecentCDACheckins = from lcp in latestClosestPositions
                                        group lcp by lcp.UserPrincipalName into g
                                        select g.OrderByDescending(t => t.InsertTime).FirstOrDefault();

            // Remove any hometownCDAs that are in the latest closest position
            foreach (var cdaCheckin in mostRecentCDACheckins)
            {
                hometownCDAs.RemoveAll(cda => cdaCheckin.UserPrincipalName == cda.UserPrincipalName);
            }

            // Create a list that will hold all the CDAs that are nearby
            List <Contact> allCDAsNearby = new List <Contact>();

            // Add CDAs in the latest closest position
            foreach (var cdaCheckin in mostRecentCDACheckins)
            {
                // Use the Contact class - so match up a cda check-in location class to their corresponding contact
                var foundCDA = allCDAs.First(cda => cda.UserPrincipalName == cdaCheckin.UserPrincipalName);

                // Then mark their curent location
                foundCDA.CurrentLocation = cdaCheckin.Position;

                allCDAsNearby.Add(foundCDA);
            }

            // Make sure the current location of the CDAs whose hometowns are near also have the current location set properly
            hometownCDAs.ForEach(cda => cda.CurrentLocation = cda.Hometown.Position);
            allCDAsNearby.AddRange(hometownCDAs);

            foreach (var cda in allCDAsNearby)
            {
                if (cda.Image.TryGetValue("Src", out string imgSrc))
                {
                    // Image source could be a full url or a partial
                    if (imgSrc.StartsWith("http", StringComparison.OrdinalIgnoreCase))
                    {
                        cda.PhotoUrl = imgSrc;
                    }
                    else
                    {
                        cda.PhotoUrl = $"https://developer.microsoft.com/en-us/advocates/{imgSrc}";
                    }
                }

                var twitterUserName = cda.Twitter.Substring(
                    cda.Twitter.LastIndexOf("/", StringComparison.OrdinalIgnoreCase) + 1);

                cda.TwitterHandle = $"@{twitterUserName}";
            }

            return(allCDAsNearby);
        }