Пример #1
0
        /// <summary>
        /// Populate the Subdivision member with a spatial hierarchical structure that helps locate an extreme vertex in 
        /// log(Vertices_Number) steps
        /// 
        /// The arguments that start the recursion should be (0 ,total_vertices) and correspond to polygon edge normals
        /// that define a sub-piece of the unit disc
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private Polygon_Tree_Node Subdivide(int start, int end)
        {
            bool is_subdivision_direction = true;

            //this is what will be returned upwards the recursion
            var node = new Polygon_Tree_Node(this);

            //this predicate means we've reached a node that is just supposed to add 2 vertex leaf nodes and return
            if (end - start == 1)
            {
                node.code = start;
                var left_vertex_node = new Polygon_Tree_Node(this);
                left_vertex_node.code = this.Vertex(end);
                node.link_l = left_vertex_node;
                var right_vertex_node = new Polygon_Tree_Node(this);
                right_vertex_node.code = this.Vertex(start);
                node.link_r = right_vertex_node;

                return node;
            }

            //in the recursion's main case we just find the middle normal in this subpiece of the unit disc
            // (the middle in the sense of the sequence defined by the polygon edges outwards normals starting
            // at the vertex 0 - vertex 1 edge and going ccw)
            // then recursively call the function on the 2 sub pieces defined by start,middle   middle, end
            var middle = Helper.Middle(start, end);
            node.left_part_start_normal = start;
            node.left_part_end_normal = middle;
            node.right_part_end_normal = end;
            node.code = middle;
            node.link_l = Subdivide(start, middle);
            node.link_r = Subdivide(middle, end);
            node.division_direction = is_subdivision_direction;
            return node;
        }
Пример #2
0
        /// <summary>
        /// Uses the specified points to initialize the polygon's data
        /// </summary>
        /// <param name="points_inserted"></param>
        public void Set(List<Vector3> points_inserted)
        {
            vertices_no = points_inserted.Count;
            if (points_inserted.Count < 3) throw new Exception("not enough points to make a polygon");
            var winding = Vector3.Cross(points_inserted[0], points_inserted[1]).Z;
            if (winding < 0)
                for (int i = 0; i < points_inserted.Count; i++) points_inserted[i] = new Vector3(-points_inserted[i].X, points_inserted[i].Y, 0);
            Points.Clear();
            Normals.Clear();
            Angles.Clear();
            for (int i = 0; i < points_inserted.Count; i++)
            {
                Points.Add(points_inserted[i]);
            }
            for (int i = 0; i < Points.Count - 1; i++)
            {
                var point1 = Points[i];
                var point2 = Points[i + 1];
                var vec = point2 - point1;
                var normal = Vector3.Cross(vec, Vector3.Backward);
                normal.Normalize();
                Normals.Add(normal);
            }
            var point1_ = Points[Points.Count - 1];
            var point2_ = Points[0];
            var vec_ = point2_ - point1_;
            var normal_ = Vector3.Cross(vec_, Vector3.Backward);
            normal_.Normalize();
            Normals.Add(normal_);
            var TwoPi = (float)(2 * Math.PI);
            var begin_angle = Helper.Get_Zero_Two_Pi_Angle(Normals[0]);
            Beginning_Normal_Angle = begin_angle;
            for (int i = 0; i < Normals.Count; i++)
            {
                var angle = Helper.Get_Zero_Two_Pi_Angle(Normals[i]);
                angle = Helper.Fix_Angle(angle, begin_angle);
                angle -= begin_angle;
                Angles.Add(angle);
            }
            Angles.Add(TwoPi);

            var res = Subdivide(0, vertices_no);
            this.Subdivision = res;
        }