예제 #1
0
        public static void ConvexHull()
        {
            int[] testSizes = new int[] { 12345, 100, 316, 1000, 3160, 10000, 31600, 100000, 316000, 1000000, 3160000, 10000000 };
            for (int iter = 0; iter < testSizes.Length; iter++)
            {
                Random r = new Random();

                List <PointD> points = new List <PointD>(testSizes[iter]);
                for (int i = 0; i < points.Capacity; i++)
                {
                    double size = r.NextDouble();
                    double ang  = r.NextDouble() * (Math.PI * 2);
                    points.Add(new PointD(size * Math.Cos(ang), size * Math.Sin(ang)));
                }
                // Plus: test sorting time to learn how much of the time is spent sorting
                var         points2 = new List <PointD>(points);
                EzStopwatch timer   = new EzStopwatch(true);
                points2.Sort((a, b) => a.X == b.X ? a.Y.CompareTo(b.Y) : (a.X < b.X ? -1 : 1));
                Stopwatch timer2   = new Stopwatch(); timer2.Start();
                int       sortTime = timer.Restart();
                IListSource <Point <double> > output = PointMath.ComputeConvexHull(points, true);
                int hullTime = timer.Millisec;
                Console.WriteLine("{0:c}   (ticks:{1,10} freq:{2})", timer2.Elapsed, timer2.ElapsedTicks, Stopwatch.Frequency);

                if (iter == 0)
                {
                    continue;                            // first iteration primes the JIT/caches
                }
                Console.WriteLine("Convex hull of {0,8} points took {1} ms ({2} ms for sorting step). Output has {3} points.",
                                  testSizes[iter], hullTime, sortTime, output.Count);
            }
        }
        public void ComputeVertices()
        {
            ////use convex hull to find vertices
            planeVertices.Clear();
            List <Point <double> > points2 = new List <Point <double> >();

            foreach (MyVector3 p in planePoints)
            {
                Point <double> pt = new Point <double>(p.x, p.y);
                points2.Add(pt);
            }
            List <Point <double> > convex_hull = PointMath.ComputeConvexHull(points2, false).ToList();

            foreach (Point <double> point in convex_hull)
            {
                MyVector3 u = new MyVector3(point.X, point.Y, ComputeZ(point.X, point.Y));
                planeVertices.Add(u);
            }
            ProjectVerticesTo2d();
            //ComputePlaneArea();
        }
예제 #3
0
        // To recognize a scribble we require the simplified line to reverse
        // direction at least three times. There are separate criteria for
        // erasing a shape currently being drawn and for erasing existing
        // shapes.
        //
        // The key difference between an "erase scribble" and a "cancel
        // scribble" is that an erase scribble starts out as such, while
        // a cancel scribble indicates that the user changed his mind, so
        // the line will not appear to be a scribble at the beginning.
        // The difference is detected by timestamps. For example, the
        // following diagram represents an "erase" operation and a "cancel"
        // operation. Assume the input points are evenly spaced in time,
        // and that the dots represent points where the input reversed
        // direction.
        //
        // Input points         ..........................
        // Reversals (erase)      .  .  .  .     .     .
        // Reversals (cancel)              .   .   .   .
        //
        // So, a scribble is considered an erasure if it satisfies t0 < t1,
        // where t0 is the time between mouse-down and the first reversal,
        // and t1 is the time between the first and third reversals. A cancel
        // operation satisfies t0 > t1 instead.
        //
        // Both kinds of scribble need to satisfy the formula LL*c > CHA,
        // where c is a constant factor in pixels, LL is the drawn line
        // length and CHA is the area of the Convex Hull that outlines the
        // drawn figure. This formula basically detects that the user
        // is convering the same ground repeatedly; if the pen reverses
        // direction repeatedly but goes to new places each time, it's not
        // considered an erasure scribble. For a cancel scribble, LL is
        // computed starting from the first reversal.
        IEnumerable <Shape> RecognizeScribbleForEraseOrCancel(DragState state, out bool cancel, out List <PointT> simplifiedSS)
        {
            cancel       = false;
            simplifiedSS = null;
            var tolerance    = state._inputTransform.Transform(new VectorT(0, 10)).Length();
            var simplifiedMP = LineMath.SimplifyPolyline(
                state.UnfilteredMousePoints.Select(p => p.Point), tolerance);
            List <int> reversals = FindReversals(simplifiedMP, 3);

            if (reversals.Count >= 3)
            {
                simplifiedSS = simplifiedMP.Select(p => state._inputTransform.Transform(p)).ToList();
                // 3 reversals confirmed. Now decide: erase or cancel?
                int[] timeStampsMs = FindTimeStamps(state.UnfilteredMousePoints, simplifiedMP);
                int   t0 = timeStampsMs[reversals[0]], t1 = timeStampsMs[reversals[2]] - t0;
                cancel = t0 > t1 + 500;

                // Now test the formula LL*c > CHA as explained above
                IListSource <PointT> simplifiedMP_ = cancel ? simplifiedMP.Slice(reversals[0]) : simplifiedMP.AsListSource();
                float LL   = simplifiedMP_.AdjacentPairs().Sum(pair => pair.A.Sub(pair.B).Length());
                var   hull = PointMath.ComputeConvexHull(simplifiedMP);
                float CHA  = PolygonMath.PolygonArea(hull);
                if (LL * EraseNubWidth > CHA)
                {
                    // Erasure confirmed.
                    if (cancel)
                    {
                        return(EmptyList <Shape> .Value);
                    }

                    // Figure out which shapes to erase. To do this, we compute for
                    // each shape the amount of the scribble that overlaps that shape.
                    var simplifiedSS_ = simplifiedSS;
                    return(_doc.Shapes.Where(s => ShouldErase(s, simplifiedSS_)).ToList());
                }
            }
            return(null);
        }
예제 #4
0
        public JsonResult ConvexHull(int Id, int Forecast)
        {
            if (Forecast > 0)
            {
                using (MeteoDataEntities me = new MeteoDataEntities())
                {
                    var    asciiResult = me.IndexMaps.Where(x => x.Id == Id).Select(x => x.IndexMapZipAscii).First();
                    Byte[] ascii       = ex.Uncompress(asciiResult);
                    //System.IO.File.WriteAllBytes(@"C:\Static\test.asc", ascii);

                    #region Read ascii

                    List <AsciiValues> listasp = new List <AsciiValues>();
                    int    counter             = 0;
                    string line;
                    int    ncols        = 0;
                    int    nrows        = 0;
                    int    xllcorner    = 0;
                    int    yllcorner    = 0;
                    int    cellsize     = 0;
                    int    NODATA_value = 0;
                    using (MemoryStream memoryStream = new MemoryStream(ascii))
                    {
                        using (StreamReader st = new StreamReader(memoryStream))
                        {
                            while ((line = st.ReadLine()) != null)
                            {
                                //System.Console.WriteLine(line);
                                if (!string.IsNullOrWhiteSpace(line))
                                {
                                    counter++;

                                    #region ASC Details

                                    if (counter < 7)
                                    {
                                        string[] result = line.Split(' ');
                                        if (result[0].Contains("ncols"))
                                        {
                                            for (int i = 1; i < result.Length; i++)
                                            {
                                                if (!String.IsNullOrWhiteSpace(result[i]))
                                                {
                                                    int number;
                                                    if (int.TryParse(result[i], out number))
                                                    {
                                                        ncols = number;
                                                    }
                                                }
                                            }
                                        }
                                        if (result[0].Contains("nrows"))
                                        {
                                            for (int i = 1; i < result.Length; i++)
                                            {
                                                if (!String.IsNullOrWhiteSpace(result[i]))
                                                {
                                                    int number;
                                                    if (int.TryParse(result[i], out number))
                                                    {
                                                        nrows = number;
                                                    }
                                                }
                                            }
                                        }

                                        if (result[0].Contains("xllcorner"))
                                        {
                                            for (int i = 1; i < result.Length; i++)
                                            {
                                                if (!String.IsNullOrWhiteSpace(result[i]))
                                                {
                                                    int number;
                                                    if (int.TryParse(result[i], out number))
                                                    {
                                                        xllcorner = number;
                                                    }
                                                }
                                            }
                                        }
                                        if (result[0].Contains("yllcorner"))
                                        {
                                            for (int i = 1; i < result.Length; i++)
                                            {
                                                if (!String.IsNullOrWhiteSpace(result[i]))
                                                {
                                                    int number;
                                                    if (int.TryParse(result[i], out number))
                                                    {
                                                        yllcorner = number;
                                                    }
                                                }
                                            }
                                        }
                                        if (result[0].Contains("cellsize"))
                                        {
                                            for (int i = 1; i < result.Length; i++)
                                            {
                                                if (!String.IsNullOrWhiteSpace(result[i]))
                                                {
                                                    int number;
                                                    if (int.TryParse(result[i], out number))
                                                    {
                                                        cellsize = number;
                                                    }
                                                }
                                            }
                                        }
                                        if (result[0].Contains("NODATA_value"))
                                        {
                                            for (int i = 1; i < result.Length; i++)
                                            {
                                                if (!String.IsNullOrWhiteSpace(result[i]))
                                                {
                                                    int number;
                                                    if (int.TryParse(result[i], out number))
                                                    {
                                                        NODATA_value = number;
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    #endregion ASC Details

                                    else
                                    {
                                        string[] result = line.Split(' ');
                                        for (int i = 0; i < result.Length; i++)
                                        {
                                            int number;
                                            if (int.TryParse(result[i], out number))
                                            {
                                                AsciiValues aspul = new AsciiValues()
                                                {
                                                    X     = xllcorner + (i * cellsize),
                                                    Y     = (yllcorner + (nrows * cellsize)) - (cellsize * (counter - 7)),
                                                    Value = number
                                                };
                                                AsciiValues aspur = new AsciiValues()
                                                {
                                                    X     = xllcorner + (i * cellsize) + cellsize,
                                                    Y     = (yllcorner + (nrows * cellsize)) - (cellsize * (counter - 7)),
                                                    Value = number
                                                };
                                                AsciiValues aspdl = new AsciiValues()
                                                {
                                                    X     = xllcorner + (i * cellsize),
                                                    Y     = (yllcorner + (nrows * cellsize)) - (cellsize * (counter - 7)) - cellsize,
                                                    Value = number
                                                };
                                                AsciiValues aspdr = new AsciiValues()
                                                {
                                                    X     = xllcorner + (i * cellsize) + cellsize,
                                                    Y     = (yllcorner + (nrows * cellsize)) - (cellsize * (counter - 7)) - cellsize,
                                                    Value = number
                                                };
                                                listasp.Add(aspul);
                                                listasp.Add(aspur);
                                                listasp.Add(aspdl);
                                                listasp.Add(aspdr);
                                            }
                                        }
                                    }
                                }
                            }
                            counter.ToString();
                        }
                    }

                    #endregion Read ascii

                    var points      = listasp.Where(x => x.Value <= Forecast && x.Value > 0);
                    var finalpoints = points.Select(x => new Point <double>()
                    {
                        X = x.X, Y = x.Y
                    }).ToList();
                    var ConvexHullresult = PointMath.ComputeConvexHull(finalpoints, true);
                    return(this.Json(ConvexHullresult, JsonRequestBehavior.AllowGet));
                }
            }
            else
            {
                return(this.Json(null, JsonRequestBehavior.AllowGet));
            }
        }