Esempio n. 1
0
        public double OpeningAngleDeg(int iVertex)
        {
            Vector2d e0 = Vector2d.Zero, e1 = Vector2d.Zero;

            NeighboursV(iVertex, ref e0, ref e1, true);
            return(Vector2d.AngleD(e0, e1));
        }
Esempio n. 2
0
        /// <summary>
        /// Compute opening angle at vertex vID.
        /// If not a vertex, or valence != 2, returns invalidValue argument.
        /// If either edge is degenerate, returns invalidValue argument.
        /// </summary>
        public double OpeningAngle(int vID, double invalidValue = double.MaxValue)
        {
            if (vertices_refcount.isValid(vID) == false)
            {
                return(invalidValue);
            }
            List <int> vedges = vertex_edges[vID];

            if (vedges.Count != 2)
            {
                return(invalidValue);
            }

            int nbra = edge_other_v(vedges[0], vID);
            int nbrb = edge_other_v(vedges[1], vID);

            Vector2d v = new Vector2d(vertices[2 * vID], vertices[2 * vID + 1]);
            Vector2d a = new Vector2d(vertices[2 * nbra], vertices[2 * nbra + 1]);
            Vector2d b = new Vector2d(vertices[2 * nbrb], vertices[2 * nbrb + 1]);

            a -= v;
            if (a.Normalize() == 0)
            {
                return(invalidValue);
            }
            b -= v;
            if (b.Normalize() == 0)
            {
                return(invalidValue);
            }
            return(Vector2d.AngleD(a, b));
        }
Esempio n. 3
0
        /// <summary>
        /// Find and remove any junction (ie valence>2) vertices of the graph.
        /// At a junction, the pair of best-aligned (ie straightest) edges are left
        /// connected, and all the other edges are disconnected
        ///
        /// [TODO] currently there is no DGraph2.SetEdge(), so the 'other' edges
        /// are deleted and new edges inserted. Hence, edge IDs are not preserved.
        /// </summary>
        public static int DisconnectJunctions(DGraph2 graph)
        {
            var junctions = new List <int>();

            // find all junctions
            foreach (int vid in graph.VertexIndices())
            {
                if (graph.IsJunctionVertex(vid))
                {
                    junctions.Add(vid);
                }
            }


            foreach (int vid in junctions)
            {
                Vector2d v         = graph.GetVertex(vid);
                int[]    nbr_verts = graph.VtxVerticesItr(vid).ToArray();

                // find best-aligned pair of edges connected to vid
                Index2i best_aligned = Index2i.Max; double max_angle = 0;
                for (int i = 0; i < nbr_verts.Length; ++i)
                {
                    for (int j = i + 1; j < nbr_verts.Length; ++j)
                    {
                        double angle = Vector2d.AngleD(
                            (graph.GetVertex(nbr_verts[i]) - v).Normalized,
                            (graph.GetVertex(nbr_verts[j]) - v).Normalized);
                        angle = Math.Abs(angle);
                        if (angle > max_angle)
                        {
                            max_angle    = angle;
                            best_aligned = new Index2i(nbr_verts[i], nbr_verts[j]);
                        }
                    }
                }

                // for nbr verts that are not part of the best_aligned edges,
                // we remove those edges and add a new one connected to a new vertex
                for (int k = 0; k < nbr_verts.Length; ++k)
                {
                    if (nbr_verts[k] == best_aligned.a || nbr_verts[k] == best_aligned.b)
                    {
                        continue;
                    }

                    int eid = graph.FindEdge(vid, nbr_verts[k]);
                    graph.RemoveEdge(eid, true);
                    if (graph.IsVertex(nbr_verts[k]))
                    {
                        var newpos = Vector2d.Lerp(graph.GetVertex(nbr_verts[k]), v, 0.99);
                        int newv   = graph.AppendVertex(newpos);
                        graph.AppendEdge(nbr_verts[k], newv);
                    }
                }
            }

            return(junctions.Count);
        }
Esempio n. 4
0
        public static double PlaneAngleSignedD(Vector2d vFrom, Vector2d vTo)
        {
            vFrom.Normalize();
            vTo.Normalize();
            double fSign  = Math.Sign(vFrom.Cross(vTo));
            double fAngle = fSign * Vector2d.AngleD(vFrom, vTo);

            return(fAngle);
        }
Esempio n. 5
0
        public void Chamfer(double chamfer_dist, double minConvexAngleDeg = 30, double minConcaveAngleDeg = 30)
        {
            if (IsClockwise)
            {
                throw new Exception("must be ccw?");
            }

            List <Vector2d> NewV = new List <Vector2d>();
            int             N    = Vertices.Count;

            int iCur = 0;

            do
            {
                Vector2d center = Vertices[iCur];

                int      iPrev = (iCur == 0) ? N - 1 : iCur - 1;
                Vector2d prev  = Vertices[iPrev];
                int      iNext = (iCur + 1) % N;
                Vector2d next  = Vertices[iNext];

                Vector2d cp     = prev - center;
                double   cpdist = cp.Normalize();
                Vector2d cn     = next - center;
                double   cndist = cn.Normalize();

                // if degenerate, skip this vert
                if (cpdist < MathUtil.ZeroTolerancef || cndist < MathUtil.ZeroTolerancef)
                {
                    iCur = iNext;
                    continue;
                }

                double angle = Vector2d.AngleD(cp, cn);
                // TODO document what this means sign-wise
                double sign     = cp.Perp.Dot(cn);
                bool   bConcave = (sign > 0);

                double thresh = (bConcave) ? minConcaveAngleDeg : minConvexAngleDeg;

                // ok not too sharp
                if (angle > thresh)
                {
                    NewV.Add(center);
                    iCur = iNext;
                    continue;
                }


                double   prev_cut_dist = Math.Min(chamfer_dist, cpdist * 0.5);
                Vector2d prev_cut      = center + prev_cut_dist * cp;
                double   next_cut_dist = Math.Min(chamfer_dist, cndist * 0.5);
                Vector2d next_cut      = center + next_cut_dist * cn;

                NewV.Add(prev_cut);
                NewV.Add(next_cut);
                iCur = iNext;
            } while (iCur != 0);

            vertices = NewV;
            Timestamp++;
        }