Esempio n. 1
0
        /// <summary>
        /// creates the concave hull based on the convex hull and an angle threshold
        /// </summary>
        /// <param name="pConvexEdges">edges of convex hull</param>
        /// <param name="pPoints">the point cloud data set</param>
        /// <param name="pMaxAngle">angle threshold</param>
        /// <returns>list of concave hull edges</returns>
        static List <tEdge> CreateConvaveHullFromConvexEdges(List <DefaultConvexFace <Vertex> > pConvexEdges, HashSet <Vertex> pPoints, double pMaxAngle)
        {
            //initialize arrays
            List <tEdge> convexHull = new List <tEdge>();

            foreach (var v in pConvexEdges)
            {
                convexHull.Add(new tEdge(v.Vertices[0], v.Vertices[1]));
            }
            List <tEdge> concaveHull = new List <tEdge>();

            //iterate through convex hull until concave hull is found
            while (convexHull.Count > 0)
            {
                //find longest edge in convex hull list
                tEdge longestEdge = convexHull.MaxBy(t => t.length);

                //remove longest edge from convex hull
                convexHull.Remove(longestEdge);

                //find nearest point
                List <tEdge> edges     = convexHull.Concat(concaveHull).ToList();
                tVector      nextPoint = FindPointWithSmallestAngle(pPoints, longestEdge, edges, pMaxAngle);
                if (nextPoint == null) //if no next point found
                {
                    concaveHull.Add(longestEdge);
                    continue;
                }

                //create edges based on nearest point
                tEdge e2 = new tEdge(longestEdge.v1, nextPoint.vector);
                tEdge e3 = new tEdge(longestEdge.v2, nextPoint.vector);

                //check if e2 and e3 intersect
                bool intersect = false;
                foreach (tEdge e1 in edges)
                {
                    if (Intersects(e2, e1) || Intersects(e3, e1))
                    {
                        intersect = true;
                        break;
                    }
                }

                //add e2 and e3 to List A again, if no intersection
                if (intersect == false)
                {
                    convexHull.Add(e2); convexHull.Add(e3); continue;
                }

                //if no concaviction found, add longest edge to concaveHull list
                concaveHull.Add(longestEdge);
            }

            return(concaveHull);
        }
Esempio n. 2
0
        /// <summary>
        /// finds the point with the smallest angle from a given dataset towards an edge
        /// </summary>
        /// <param name="pPoints">the dataset</param>
        /// <param name="pLine">the edge to calculate the angle towards</param>
        /// <param name="pBoundaries">boundaries</param>
        /// <param name="pMaxAngle">angle threshold</param>
        /// <returns></returns>
        static tVector FindPointWithSmallestAngle(HashSet <Vertex> pPoints, tEdge pLine, List <tEdge> pBoundaries, double pMaxAngle)
        {
            tVector bestFit    = null;
            Object  lockObject = new object();

            Parallel.ForEach(pPoints, v =>
            {
                //check if point is on concave hull
                if (!IsPointOnConcaveHull(v, pBoundaries))
                {
                    //calculate new potential edges
                    tEdge t1 = new tEdge(pLine.v1, v);
                    tEdge t2 = new tEdge(pLine.v2, v);

                    //check if local maximum < edge length
                    if (t1.length < pLine.length && t2.length < pLine.length)
                    {
                        //calculate the highest angle between lines and the new point
                        double maxAngle;
                        double angleA = Math.Abs(CalculateAngleBetweenTwoLines(pLine, t1));
                        double angleB = Math.Abs(CalculateAngleBetweenTwoLines(pLine, t2));
                        if (angleA > angleB)
                        {
                            maxAngle = angleA;
                        }
                        else
                        {
                            maxAngle = angleB;
                        }

                        //check if highest angle is smaller than threshold
                        if (maxAngle < pMaxAngle)
                        {
                            //check if bestFit has been initialized
                            tVector currentFit = new tVector(v, maxAngle);
                            lock (lockObject)
                                if (bestFit == null)
                                {
                                    bestFit = currentFit;
                                }

                            //check if current point has a better fit
                            lock (lockObject)
                                if (currentFit.maxAngle < bestFit.maxAngle)
                                {
                                    bestFit = currentFit;
                                }
                        }
                    }
                }
            });

            return(bestFit);
        }
Esempio n. 3
0
        public override IDerivation Visit(AlternativeSet aAlternativeSet, DerivationContext aContext)
        {
            for (int i = 0; i < aAlternativeSet.Count; i++)
            {
                IPhrase phr = aAlternativeSet.Phrases[i];
                if (OmmitTerminals && phr is Terminal)
                {
                    continue;
                }
                tEdge edge = addEdge(aContext, phr, aAlternativeSet.Parent);
                edge.CustomAttributes = phr.IsCyclic ? GrammarGraphEdgeAttrs.IsCyclic : GrammarGraphEdgeAttrs.None;

                phr.Accept(NewContext(aAlternativeSet, aContext));
            }
            return(null);
        }
Esempio n. 4
0
        public override IDerivation Visit(Seqence aSeqence, DerivationContext aContext)
        {
            for (int i = 0; i < aSeqence.Count; i++)
            {
                IPhrase phr = aSeqence.Phrases[i];
                if (OmmitTerminals && phr is Terminal)
                {
                    continue;
                }
                tEdge edge = addEdge(aContext, phr, aSeqence.Parent);
                edge.CustomAttributes = GrammarGraphEdgeAttrs.IsSequence
                                        | (phr.IsCyclic ? GrammarGraphEdgeAttrs.IsCyclic : GrammarGraphEdgeAttrs.None);

                phr.Accept(NewContext(aSeqence, aContext));
            }
            return(null);
        }
Esempio n. 5
0
        /// <summary>
        /// checks if two edges are intersecting
        /// </summary>
        /// <param name="AB">edge 1</param>
        /// <param name="CD">edge 2</param>
        /// <returns>true if intersects, false if not</returns>
        static bool Intersects(tEdge AB, tEdge CD)
        {
            //http://www.codeproject.com/Tips/862988/Find-the-Intersection-Point-of-Two-Line-Segments
            Vector ABs = new Vector(AB.v1.Position[0], AB.v1.Position[1]);
            Vector ABe = new Vector(AB.v2.Position[0], AB.v2.Position[1]);
            Vector CDs = new Vector(CD.v1.Position[0], CD.v1.Position[1]);
            Vector CDe = new Vector(CD.v2.Position[0], CD.v2.Position[1]);

            Vector intersection;
            bool   intersects = LineSegmentIntersection.LineSegementsIntersect(ABs, ABe, CDs, CDe, out intersection);

            if (intersects)
            {
                if (intersection.Equals(ABs) || intersection.Equals(ABe) || intersection.Equals(CDs) || intersection.Equals(CDe))
                {
                    return(false);
                }
            }
            return(intersects);
        }
Esempio n. 6
0
        public override IDerivation Visit(NonTerminal aSymbol, DerivationContext aContext)
        {
            tGraph graph = (aContext as BuildGraphContext).BuildingGraph;

            if ((aSymbol.CycicKind & CycicKind.CyclicOrigin) > 0)
            {
                graph.ensureExistsNode(aSymbol.CounterName, aSymbol.Text);
                graph.ensureExistsNode(aSymbol.CyclicToOccurence, aSymbol.Text);
                tEdge e = graph.addEdge(aSymbol.CounterName, aSymbol.CyclicToOccurence);
                if (e != null)
                {
                    e.CustomAttributes = GrammarGraphEdgeAttrs.IsPunktir;
                }
            }
            if (aSymbol.CycicKind == CycicKind.None ||
                aSymbol.CycicKind == CycicKind.CyclicPropagated)
            {
                aSymbol.FindItsRule().Expand(aContext);
            }
            return(null);
        }
Esempio n. 7
0
        /// <summary>
        /// calculates the angle between two lines
        /// </summary>
        /// <param name="l1">line 1</param>
        /// <param name="l2">line 2</param>
        /// <returns>the angle between line 1 and line 2</returns>
        static double CalculateAngleBetweenTwoLines(tEdge l1, tEdge l2)
        {
            //https://social.msdn.microsoft.com/Forums/vstudio/en-US/fa0cfeb6-70b7-4181-bc9b-fe625cd5e159/angle-between-two-lines
            //Double Angle = Math.Atan2(y2-y1, x2-x1) - Math.Atan2(y4-y3,x4-x3);
            return(Math.Atan2(l1.v2.Position[1] - l1.v1.Position[1], l1.v2.Position[0] - l1.v1.Position[0]) - Math.Atan2(l2.v2.Position[1] - l2.v1.Position[1], l2.v2.Position[0] - l2.v1.Position[0]));

            /*
             * //http://usb.unitedsb.de/topic/72776-java-winkel-zwischen-2-geraden-berechnen-wie/
             * //calculate new vectors // l1.v1 == l2.v1
             * Vertex P1P2 = new Vertex(l1.v2.Position[0] - l1.v1.Position[0], l1.v2.Position[1] - l1.v1.Position[1]);
             * Vertex P1P3 = new Vertex(l2.v2.Position[0] - l1.v1.Position[0], l2.v2.Position[1] - l1.v1.Position[1]);
             *
             * //calculate length of vectors
             * double norm1 = Math.Sqrt((P1P2.Position[0] * P1P2.Position[0]) + (P1P2.Position[1] * P1P2.Position[1]));
             * double norm2 = Math.Sqrt((P1P3.Position[0] * P1P3.Position[0]) + (P1P3.Position[1] * P1P3.Position[1]));
             *
             * //scalar product
             * double skpr = (P1P2.Position[0] * P1P3.Position[0]) + (P1P2.Position[1] * P1P3.Position[1]);
             *
             * //calc angle (radial, bogenmaß)
             * double alpha = Math.Acos(skpr / (norm1 * norm2));
             *
             * return ((180 / Math.PI) * alpha);*/
        }
Esempio n. 8
0
        private tEdge addEdge(DerivationContext aContext, IPhrase aPhr, IPhrase aParent)
        {
            tGraph graph    = (aContext as BuildGraphContext).BuildingGraph;
            string fromName = "unk";
            string toName   = "unk";

            // determine fromName
            if (aParent == null)
            {
                fromName = aContext.Grammar.MainSymbol.CounterName;
                graph.ensureExistsNode(fromName, aContext.Grammar.MainSymbol.Text);
            }
            else
            {
                NonTerminal parentNt = aParent as NonTerminal;
                if (parentNt != null)
                {
                    fromName = parentNt.CounterName;
                    graph.ensureExistsNode(parentNt.CounterName, parentNt.Text);
                }
                else
                {
                    fromName = (aContext as BuildGraphContext).GeneratedToName;
                    Debug.Assert(!string.IsNullOrEmpty(fromName), "Не должно быть");
                }
            }
            // determine toName
            NonTerminal nonTerminal = aPhr as NonTerminal;
            Terminal    terminal    = aPhr as Terminal;

            if (nonTerminal != null)
            {
                toName = nonTerminal.CounterName;
                string text = nonTerminal.Text;
                if ((nonTerminal.CycicKind & CycicKind.SkippedAsSeen) > 0)
                {
                    text += " *";
                }
                graph.ensureExistsNode(toName, text);
            }
            else if (terminal != null)
            {
                string text = string.IsNullOrEmpty(terminal.Text) ? "e" : terminal.Text;
                tNode  n    = graph.addNonUniqueNode(text);
                toName             = n.Name;
                n.CustomAttributes = "term";
            }
            else
            {
                toName = graph.addNonUniqueNode(aPhr.ToString()).Name;
                //надо запомнить это в контексте
                (aContext as BuildGraphContext).GeneratedToName = toName;
            }
            tEdge e = graph.addEdge(fromName, toName);

            if (e == null)
            {
                Debug.WriteLine("не создалась дуга, потому что нет вершин");
            }
            return(e);
        }