Ejemplo n.º 1
0
        public static List <Line> setConcaveHull(double concavity, int scaleFactor)
        {
            /* Run setConvHull before!
             * Concavity is a value used to restrict the concave angles
             * It can go from -1 (no concavity) to 1 (extreme concavity)
             * Avoid concavity == 1 if you don't want 0º angles
             * */
            bool aLineWasDividedInTheIteration;

            hull_concave_edges.AddRange(hull_edges);
            do
            {
                aLineWasDividedInTheIteration = false;
                for (int linePositionInHull = 0; linePositionInHull < hull_concave_edges.Count && !aLineWasDividedInTheIteration; linePositionInHull++)
                {
                    Line        line         = hull_concave_edges[linePositionInHull];
                    List <Node> nearbyPoints = HullFunctions.getNearbyPoints(line, unused_nodes, scaleFactor);
                    List <Line> dividedLine  = HullFunctions.getDividedLine(line, nearbyPoints, hull_concave_edges, concavity);
                    if (dividedLine.Count > 0)   // Line divided!
                    {
                        aLineWasDividedInTheIteration = true;
                        unused_nodes.Remove(unused_nodes.Where(n => n.id == dividedLine[0].nodes[1].id).FirstOrDefault()); // Middlepoint no longer free
                        hull_concave_edges.AddRange(dividedLine);
                        hull_concave_edges.RemoveAt(linePositionInHull);                                                   // Divided line no longer exists
                    }
                }

                hull_concave_edges = hull_concave_edges.OrderByDescending(a => Line.getLength(a.nodes[0], a.nodes[1])).ToList();
            } while (aLineWasDividedInTheIteration);

            return(hull_concave_edges);
        }
Ejemplo n.º 2
0
        public static void setConcaveHull(decimal concavity, int scaleFactor, bool isSquareGrid)
        {
            /* Run setConvHull before!
             * Concavity is a value used to restrict the concave angles
             * it can go from -1 to 1 (it wont crash if you go further)
             * */
            Hull.scaleFactor   = scaleFactor;
            hull_concave_edges = new List <Line>(hull_edges.OrderByDescending(a => Line.getLength(a.nodes[0], a.nodes[1])).ToList());
            Line        selected_edge;
            List <Line> aux = new List <Line>();;
            int         list_original_size;
            int         count          = 0;
            bool        listIsModified = false;

            do
            {
                listIsModified     = false;
                count              = 0;
                list_original_size = hull_concave_edges.Count;
                while (count < list_original_size)
                {
                    selected_edge = hull_concave_edges[0];
                    hull_concave_edges.RemoveAt(0);
                    aux = new List <Line>();
                    if (!selected_edge.isChecked)
                    {
                        List <Node> nearby_points = HullFunctions.getNearbyPoints(selected_edge, unused_nodes, Hull.scaleFactor);
                        aux.AddRange(HullFunctions.setConcave(selected_edge, nearby_points, hull_concave_edges, concavity, isSquareGrid));
                        listIsModified = listIsModified || (aux.Count > 1);

                        if (aux.Count > 1)
                        {
                            foreach (Node node in aux[0].nodes)
                            {
                                if (unused_nodes.Find(a => a.id == node.id) != null)
                                {
                                    unused_nodes.Remove(unused_nodes.Where(a => a.id == node.id).First());
                                }
                            }
                        }
                        else
                        {
                            aux[0].isChecked = true;
                        }
                    }
                    else
                    {
                        aux.Add(selected_edge);
                    }
                    hull_concave_edges.AddRange(aux);
                    count++;
                }
                hull_concave_edges = hull_concave_edges.OrderByDescending(a => Line.getLength(a.nodes[0], a.nodes[1])).ToList();
                list_original_size = hull_concave_edges.Count;
            } while (listIsModified);
        }
        public static bool tangentToHull(Line line_treated, Node node, decimal cos1, decimal cos2, List <Line> concave_hull)
        {
            /* A new middlepoint could (rarely) make a segment that's tangent to the hull.
             * This method detects these situations
             * I suggest turning this method of if you are not using square grids or if you have a high dot density
             * */
            bool       isTangent = false;
            decimal    current_cos1;
            decimal    current_cos2;
            double     edge_length;
            List <int> nodes_searched = new List <int>();
            Line       line;
            Node       node_in_hull;
            int        count_line = 0;
            int        count_node = 0;

            edge_length = Line.getLength(node, line_treated.nodes[0]) + Line.getLength(node, line_treated.nodes[1]);


            while (!isTangent && count_line < concave_hull.Count)
            {
                line = concave_hull[count_line];
                while (!isTangent && count_node < 2)
                {
                    node_in_hull = line.nodes[count_node];
                    if (!nodes_searched.Contains(node_in_hull.id))
                    {
                        if (node_in_hull.id != line_treated.nodes[0].id && node_in_hull.id != line_treated.nodes[1].id)
                        {
                            current_cos1 = getCos(node_in_hull, line_treated.nodes[0], line_treated.nodes[1]);
                            current_cos2 = getCos(node_in_hull, line_treated.nodes[1], line_treated.nodes[0]);
                            if (current_cos1 == cos1 || current_cos2 == cos2)
                            {
                                isTangent = (Line.getLength(node_in_hull, line_treated.nodes[0]) + Line.getLength(node_in_hull, line_treated.nodes[1]) < edge_length);
                            }
                        }
                    }
                    nodes_searched.Add(node_in_hull.id);
                    count_node++;
                }
                count_node = 0;
                count_line++;
            }
            return(isTangent);
        }