コード例 #1
0
ファイル: Voronoi.cs プロジェクト: craigge/dx11
        public Voronoi(List<Point> points, List<int> colors, Rectangle plotBounds) {
            _sitesIndexedByLocation = new Dictionary<Point, Site>();
            _triangles = new List<Triangle>();
            Edges = new List<Edge>();
            PlotBounds = plotBounds;

            AddSites(points, colors);
            FortunesAlgorithm();
        }
コード例 #2
0
ファイル: Site.cs プロジェクト: craigge/dx11
 public void RegionPrepare(Rectangle clippingBounds) {
     if (EdgeReordered) {
         return;
     }
     ReorderEdges();
     _region = ClipToBounds(clippingBounds);
     if (new Polygon(_region).Winding == WindingDirection.Clockwise) {
         _region.Reverse();
     }
 }
コード例 #3
0
ファイル: MainForm.cs プロジェクト: craigge/dx11
        private void MainForm_Load(object sender, EventArgs e) {
            var rand = new Random(0);
            var points = new List<Point>();
            var r = ClientRectangle;


            for (int i = 0; i < 100; i++) {
                points.Add(new Point(rand.Next(r.Width), rand.Next(r.Height)));
            }
            var rect = new Rectangle(r.X, r.Y, r.Width, r.Height);
            _voronoi = new Voronoi(points, null, rect);

            Invalidate();
        }
コード例 #4
0
ファイル: Site.cs プロジェクト: craigge/dx11
 public static Sides Check(Point p, Rectangle bounds) {
     var value = Sides.None;
     if (Math.Abs(p.X - bounds.Left) < float.Epsilon) {
         value |= Sides.Left;
     }
     if (Math.Abs(p.X - bounds.Right) < float.Epsilon) {
         value|=Sides.Right;
     }
     if (Math.Abs(p.Y - bounds.Top) < float.Epsilon) {
         value |= Sides.Top;
     }
     if (Math.Abs(p.Y - bounds.Bottom) < float.Epsilon) {
         value |= Sides.Bottom;
     }
     return value;
 }
コード例 #5
0
ファイル: Edge.cs プロジェクト: craigge/dx11
        public void ClipVertices(Rectangle bounds) {
            var xmin = bounds.X;
            var ymin = bounds.Y;
            var xmax = bounds.Right;
            var ymax = bounds.Bottom;

            Vertex vertex0, vertex1;
            float x0, x1, y0, y1;

            if (Math.Abs(A - 1.0) < Double.Epsilon && B >= 0.0) {
                vertex0 = RightVertex;
                vertex1 = LeftVertex;
            } else {
                vertex0 = LeftVertex;
                vertex1 = RightVertex;
            }

            if (Math.Abs(A - 1.0) < Double.Epsilon) {
                y0 = ymin;
                if (vertex0 != null && vertex0.Y > ymin)
                    y0 = vertex0.Y;
                if (y0 > ymax)
                    return;
                x0 = C - B * y0;

                y1 = ymax;
                if (vertex1 != null && vertex1.Y < ymax)
                    y1 = vertex1.Y;
                if (y1 < ymin)
                    return;
                x1 = C - B * y1;

                if ((x0 > xmax && x1 > xmax) || (x0 < xmin && x1 < xmin))
                    return;

                if (x0 > xmax) {
                    x0 = xmax;
                    y0 = (C - x0) / B;
                } else if (x0 < xmin) {
                    x0 = xmin;
                    y0 = (C - x0) / B;
                }

                if (x1 > xmax) {
                    x1 = xmax;
                    y1 = (C - x1) / B;
                } else if (x1 < xmin) {
                    x1 = xmin;
                    y1 = (C - x1) / B;
                }
            } else {
                x0 = xmin;
                if (vertex0 != null && vertex0.X > xmin)
                    x0 = vertex0.X;
                if (x0 > xmax)
                    return;
                y0 = C - A * x0;

                x1 = xmax;
                if (vertex1 != null && vertex1.X < xmax)
                    x1 = vertex1.X;
                if (x1 < xmin)
                    return;
                y1 = C - A * x1;

                if ((y0 > ymax && y1 > ymax) || (y0 < ymin && y1 < ymin))
                    return;

                if (y0 > ymax) {
                    y0 = ymax;
                    x0 = (C - y0) / A;
                } else if (y0 < ymin) {
                    y0 = ymin;
                    x0 = (C - y0) / A;
                }

                if (y1 > ymax) {
                    y1 = ymax;
                    x1 = (C - y1) / A;
                } else if (y1 < ymin) {
                    y1 = ymin;
                    x1 = (C - y1) / A;
                }
            }
            if (vertex0 == LeftVertex) {
                ClippedEnds[LR.Side.Left] = new Point(x0, y0);
                ClippedEnds[LR.Side.Right] = new Point(x1, y1);
            } else {
                ClippedEnds[LR.Side.Right] = new Point(x0, y0);
                ClippedEnds[LR.Side.Left] = new Point(x1, y1);
            }
            Console.WriteLine("cl {0} {1} {2} {3}", x0, y0, x1, y1);
        }
コード例 #6
0
ファイル: Site.cs プロジェクト: craigge/dx11
 public List<Point> Region(Rectangle clippingBounds) {
     if (Edges.Count == 0) {
         return new List<Point>();
     }
     RegionPrepare(clippingBounds);
     return _region;
 }
コード例 #7
0
ファイル: Site.cs プロジェクト: craigge/dx11
        private void Connect(List<Point> points, int j, Rectangle bounds, bool closingUp = false) {
            var rightPoint = points.Last();
            var newEdge = Edges[j];
            var newOrientation = EdgeOrientations[j];
            // the point that  must be connected to rightPoint:
            var newPoint = newEdge.ClippedEnds[newOrientation];
            if (!CloseEnough(rightPoint, newPoint)) {
                // The points do not coincide, so they must have been clipped at the bounds;
                // see if they are on the same border of the bounds:
                if (rightPoint.X != newPoint.X && rightPoint.Y != newPoint.Y) {
                    // They are on different borders of the bounds;
                    // insert one or two corners of bounds as needed to hook them up:
                    // (NOTE this will not be correct if the region should take up more than
                    // half of the bounds rect, for then we will have gone the wrong way
                    // around the bounds and included the smaller part rather than the larger)
                    var rightCheck = BoundsCheck.Check(rightPoint, bounds);
                    var newCheck = BoundsCheck.Check(newPoint, bounds);
                    float px, py;

                    // TODO: refactor origin lib copypasta
                    if (rightCheck.HasFlag(BoundsCheck.Sides.Right)) {
                        px = bounds.Right;
                        if (newCheck.HasFlag(BoundsCheck.Sides.Bottom)) {
                            py = bounds.Bottom;
                            points.Add(new Point(px,py));
                        } else if (newCheck.HasFlag(BoundsCheck.Sides.Top)) {
                            py = bounds.Top;
                            points.Add(new Point(px,py));
                        } else if (newCheck.HasFlag(BoundsCheck.Sides.Left)) {
                            if (rightPoint.Y - bounds.Y + newPoint.Y - bounds.Y < bounds.Height) {
                                py = bounds.Top;
                            } else {
                                py = bounds.Bottom;
                            }
                            points.Add(new Point(px,py));
                            points.Add(new Point(bounds.Left, py));
                        }
                    } else if (rightCheck.HasFlag(BoundsCheck.Sides.Left)) {
                        px = bounds.Left;
                        if (newCheck.HasFlag(BoundsCheck.Sides.Bottom)) {
                            py = bounds.Bottom;
                            points.Add(new Point(px, py));
                        } else if (newCheck.HasFlag(BoundsCheck.Sides.Top)) {
                            py = bounds.Top;
                            points.Add(new Point(px, py));
                        } else if (newCheck.HasFlag(BoundsCheck.Sides.Right)) {
                            if (rightPoint.Y - bounds.Y + newPoint.Y - bounds.Y < bounds.Height) {
                                py = bounds.Top;
                            } else {
                                py = bounds.Bottom;
                            }
                            points.Add(new Point(px, py));
                            points.Add(new Point(bounds.Right, py));
                        }
                    } else if (rightCheck.HasFlag(BoundsCheck.Sides.Top)) {
                        py = bounds.Top;
                        if (newCheck.HasFlag(BoundsCheck.Sides.Right)) {
                            px = bounds.Right;
                            points.Add(new Point(px, py));
                        } else if (newCheck.HasFlag(BoundsCheck.Sides.Left)) {
                            px = bounds.Left;
                            points.Add(new Point(px, py));
                        } else if (newCheck.HasFlag(BoundsCheck.Sides.Bottom)) {
                            if (rightPoint.X - bounds.X + newPoint.X - bounds.Y < bounds.Width) {
                                px = bounds.Left;
                            } else {
                                px = bounds.Right;
                            }
                            points.Add(new Point(px, py));
                            points.Add(new Point(bounds.Left, bounds.Bottom));
                        }
                    } else if (rightCheck.HasFlag(BoundsCheck.Sides.Bottom)) {
                        py = bounds.Bottom;
                        if (newCheck.HasFlag(BoundsCheck.Sides.Right)) {
                            px = bounds.Right;
                            points.Add(new Point(px, py));
                        } else if (newCheck.HasFlag(BoundsCheck.Sides.Left)) {
                            px = bounds.Left;
                            points.Add(new Point(px, py));
                        } else if (newCheck.HasFlag(BoundsCheck.Sides.Bottom)) {
                            if (rightPoint.X - bounds.X + newPoint.X - bounds.Y < bounds.Width) {
                                px = bounds.Left;
                            } else {
                                px = bounds.Right;
                            }
                            points.Add(new Point(px, py));
                            points.Add(new Point(bounds.Left, bounds.Top));
                        }
                    }
                }
                if (closingUp) {
                    // newEdge's ends have already been added
                    return;
                }
                points.Add(newPoint);
            }
            var newRightPoint = newEdge.ClippedEnds[LR.Other(newOrientation)];
            if (!CloseEnough(points.First(), newRightPoint)) {
                points.Add(newRightPoint);
            }
        }
コード例 #8
0
ファイル: Site.cs プロジェクト: craigge/dx11
 private List<Point> ClipToBounds(Rectangle bounds) {
     var points = new List<Point>();
     int i = -1;
     for (int j = 0; j < Edges.Count; j++) {
         var edge = Edges[j];
         if (edge == null || !edge.Visible) {
             continue;
         }
         if (i >= 0) {
             Connect(points, j, bounds);
         } else {
             i = j;
             var orientation = EdgeOrientations[j];
             points.Add(edge.ClippedEnds[orientation]);
             points.Add(edge.ClippedEnds[LR.Other(orientation)]);
         }
     }
     if (i >= 0) {
         Connect(points, i, bounds, true);
     }
     return points;
 }
コード例 #9
0
ファイル: SiteList.cs プロジェクト: craigge/dx11
 public void RegionsPrepare(Rectangle bounds) {
     foreach (var site in _sites) {
         site.RegionPrepare(bounds);
     }
 }
コード例 #10
0
ファイル: SiteList.cs プロジェクト: craigge/dx11
 public List<List<Point>> Regions(Rectangle bounds) {
     return _sites.Select(site => site.Region(bounds)).ToList();
 }