예제 #1
0
파일: Voronoi.cs 프로젝트: JackTing/PathCAM
        /// <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);
                }
            }
        }
예제 #2
0
        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>;
        }
예제 #3
0
        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>;
        }
예제 #4
0
        /// <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;
        }
예제 #5
0
파일: Mesh.cs 프로젝트: JackTing/PathCAM
        /// <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;
        }
예제 #6
0
        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;
            }
        }
예제 #7
0
        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);
                }
            }
        }
예제 #8
0
        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);
                }
            }
        }
예제 #9
0
 public QuadNode(BoundingBox box, QuadTree tree)
     : this(box, tree, false)
 {
 }