public static void contour(double step)
        {
            PyDraw.clear();
            //PyDraw.fill(128, 255, 128);
            //PyDraw.stroke(96, 255, 96);
            //PyDraw.thickness(1);
            //PyDraw.alpha(48);

            var gridCells = ValueBuffer.GetGrid();
            var values    = Functional.Seq.range(0, gridCells.Max(x => x.Value), step).ToArray();
            var cityLoops = new List <List <Geometry.Point2D> >();

            foreach (var value in values)
            {
                var binarizedPixels = ValueBuffer.GetBinarizedPixels(gridCells.Cast <GridCell>().ToList(), x => x.Value >= value);
                var pb    = new Geometry.PixelBound(binarizedPixels);
                var loops = pb.Trace();
                foreach (var loop in loops)
                {
                    var loopPoints = loop.Select(x => (ValueBuffer.GetGridCell(gridCells, x.X, x.Y) as GridCell).Position).ToList();
                    loopPoints = Geometry.PixelBound.Align(loopPoints, 5);

                    //PyDraw.cityspline(loopPoints.ToArray(), true);
                    //loopPoints.ForEach(p => PyDraw.cityellipse(p.x, p.y, 1, 1));
                    cityLoops.Add(loopPoints);
                }
            }
            ViewerTool tool = new ViewerTool
            {
                PaintAction = () =>
                {
                    cityLoops.ForEach(loop =>
                    {
                        var pts = loop.Select(p => display.CanvasCoordinateF(p)).ToList();
                        pts.ForEach(p => display.g.FillEllipse(new SolidBrush(Color.Black), p.X, p.Y, 3, 3));
                    });
                }
            };

            viewer.SetTool(tool);
        }
        public static void voronoi(int level = 5)
        {
            PyDraw.clear();
            PyDraw.fill(128, 128, 128);
            PyDraw.thickness(3);
            PyDraw.alpha(128);

            var coverRangeCells = ValueBuffer.GetCoverRangeGrid();
            var values          = coverRangeCells.Select(x => x.Value).Distinct().ToArray();

            foreach (var value in values)
            {
                var binarizedPixels = ValueBuffer.GetBinarizedPixels(coverRangeCells.Cast <GridCell>().ToList(), x => x.Value == value);
                var pb         = new Geometry.PixelBound(binarizedPixels);
                var loop       = pb.Trace()[0];
                var loopPoints = loop.Select(x => (ValueBuffer.GetGridCell(coverRangeCells, x.X, x.Y) as GridCell).Position).ToList();
                loopPoints = Geometry.PixelBound.Align(loopPoints, level);

                PyDraw.cityspline(loopPoints.ToArray(), true);
            }
        }