/// <summary> /// Gets the Voronoi diagram as raw output data. /// </summary> /// <param name="mesh"></param> /// <returns></returns> /// <remarks> /// The Voronoi diagram is the geometric dual of the Delaunay triangulation. /// Hence, the Voronoi vertices are listed by traversing the Delaunay /// triangles, and the Voronoi edges are listed by traversing the Delaunay /// edges. ///</remarks> private void Generate() { mesh.Renumber(); mesh.MakeVertexMap(); // Allocate space for voronoi diagram this.points = new Point[mesh.triangles.Count + mesh.hullsize]; this.regions = new List<VoronoiRegion>(mesh.vertices.Count); rayPoints = new Dictionary<int, Point>(); rayIndex = 0; bounds = new BoundingBox(); // Compute triangles circumcenters and setup bounding box ComputeCircumCenters(); // Loop over the mesh vertices (Voronoi generators). foreach (var item in mesh.vertices.Values) { //if (item.Boundary == 0) { ConstructVoronoiRegion(item); } } }
public static IBuffer<float> CreateVertexBuffer(ICollection<Point> points, ref BoundingBox bounds) { var buffer = new VertexBuffer(2 * points.Count); bounds.Reset(); var data = buffer.Data; float x, y; int i = 0; foreach (var p in points) { x = (float)p.X; y = (float)p.Y; data[2 * i] = x; data[2 * i + 1] = y; bounds.Update(x, y); i++; } return buffer as IBuffer<float>; }
public static IBuffer<float> CreateVertexBuffer(double[] points, ref BoundingBox bounds) { int length = points.Length; var buffer = new VertexBuffer(length); bounds.Reset(); var data = buffer.Data; float x, y; length = length >> 1; for (int i = 0; i < length; i++) { x = (float)points[2 * i]; y = (float)points[2 * i + 1]; data[2 * i] = x; data[2 * i + 1] = y; bounds.Update(x, y); } return buffer as IBuffer<float>; }
/// <summary> /// Initializes a new instance of the <see cref="InputGeometry" /> class. /// The point list will be initialized with a given capacity. /// </summary> /// <param name="capacity">Point list capacity.</param> public InputGeometry(int capacity) { points = new List<Vertex>(capacity); segments = new List<Edge>(); holes = new List<Point>(); regions = new List<RegionPointer>(); bounds = new BoundingBox(); pointAttributes = -1; }
/// <summary> /// Read the vertices from memory. /// </summary> /// <param name="data">The input data.</param> private void TransferNodes(InputGeometry data) { List<Vertex> points = data.points; this.invertices = points.Count; this.mesh_dim = 2; if (this.invertices < 3) { logger.Error("Input must have at least three input vertices.", "MeshReader.TransferNodes()"); throw new Exception("Input must have at least three input vertices."); } this.nextras = points[0].attributes == null ? 0 : points[0].attributes.Length; foreach (Vertex vertex in points) { vertex.hash = this.hash_vtx++; vertex.id = vertex.hash; this.vertices.Add(vertex.hash, vertex); } this.bounds = data.Bounds; }
private void UpdateMetrics(BoundingBox bounds) { x_max = bounds.Xmax; x_min = bounds.Xmin; y_max = bounds.Ymax; y_min = bounds.Ymin; // Enlarge width 5% on each side x_scale = x_max - x_min; x_max = x_max + 0.05 * x_scale; x_min = x_min - 0.05 * x_scale; x_scale = x_max - x_min; // Enlarge height 5% on each side y_scale = y_max - y_min; y_max = y_max + 0.05 * y_scale; y_min = y_min - 0.05 * y_scale; y_scale = y_max - y_min; if (x_scale < y_scale) { int delta = (int)Math.Round((x_ps_max - x_ps_min) * (y_scale - x_scale) / (2.0 * y_scale)); x_ps_max = x_ps_max - delta; x_ps_min = x_ps_min + delta; x_ps_max_clip = x_ps_max_clip - delta; x_ps_min_clip = x_ps_min_clip + delta; x_scale = y_scale; } else { int delta = (int)Math.Round((y_ps_max - y_ps_min) * (x_scale - y_scale) / (2.0 * x_scale)); y_ps_max = y_ps_max - delta; y_ps_min = y_ps_min + delta; y_ps_max_clip = y_ps_max_clip - delta; y_ps_min_clip = y_ps_min_clip + delta; y_scale = x_scale; } }
public void CreateSubRegion(int currentDepth) { // The four sub regions of the quad tree // +--------------+ // | nw | ne | // |------+pivot--| // | sw | se | // +--------------+ BoundingBox box; // 1. region south west box = new BoundingBox(bounds.Xmin, bounds.Ymin, pivot.X, pivot.Y); regions[0] = new QuadNode(box, tree); // 2. region south east box = new BoundingBox(pivot.X, bounds.Ymin, bounds.Xmax, pivot.Y); regions[1] = new QuadNode(box, tree); // 3. region north west box = new BoundingBox(bounds.Xmin, pivot.Y, pivot.X, bounds.Ymax); regions[2] = new QuadNode(box, tree); // 4. region north east box = new BoundingBox(pivot.X, pivot.Y, bounds.Xmax, bounds.Ymax); regions[3] = new QuadNode(box, tree); Point[] triangle = new Point[3]; // Find region for every triangle vertex foreach (var index in triangles) { ITriangle tri = tree.triangles[index]; triangle[0] = tri.GetVertex(0); triangle[1] = tri.GetVertex(1); triangle[2] = tri.GetVertex(2); AddTriangleToRegion(triangle, tri.ID); } for (int i = 0; i < 4; i++) { if (regions[i].triangles.Count > tree.sizeBound && currentDepth < tree.maxDepth) { regions[i].CreateSubRegion(currentDepth + 1); } } }
public QuadNode(BoundingBox box, QuadTree tree, bool init) { this.tree = tree; this.bounds = new BoundingBox(box.Xmin, box.Ymin, box.Xmax, box.Ymax); this.pivot = new Point((box.Xmin + box.Xmax) / 2, (box.Ymin + box.Ymax) / 2); this.bitRegions = 0; this.regions = new QuadNode[4]; this.triangles = new List<int>(); if (init) { // Allocate memory upfront triangles.Capacity = tree.triangles.Length; foreach (var tri in tree.triangles) { triangles.Add(tri.ID); } } }
public QuadNode(BoundingBox box, QuadTree tree) : this(box, tree, false) { }