private void AddFootOfPerp()
            {
                int addedBaseSegCount = 0;

                for (int i = 0; i < itSegments.Count(); i++)
                {
                    List <InitialPt> fopInit = new List <InitialPt>();

                    //set
                    Line     baseSeg         = itSegments[i].Line;
                    Vector3d perpFromSegment = baseSeg.UnitTangent;
                    perpFromSegment.Rotate(Math.PI / 2, Vector3d.ZAxis);

                    //seive: count
                    if (addedBaseSegCount > 5)
                    {
                        break;
                    }

                    //seive: minimum length
                    if (baseSeg.Length < minLength)
                    {
                        continue;
                    }


                    for (int j = 0; j < atVertices.Count(); j++)
                    {
                        AngleTagVertex currentV = atVertices[j];

                        Vector3d testVec       = currentV.Pt - baseSeg.PointAt(0);
                        bool     isDexter      = perpFromSegment * testVec > 0;
                        bool     isUndecidable = Math.Abs(perpFromSegment * testVec) < 0.005;
                        if (isDexter && !isUndecidable)
                        {
                            initialPts.AddRange(FindFootOfPerp(baseSeg, -perpFromSegment, currentV, false));
                        }

                        else if (!isUndecidable)
                        {
                            initialPts.AddRange(FindFootOfPerp(baseSeg, perpFromSegment, currentV, true));
                        }
                    }

                    addedBaseSegCount++;
                }
            }
            private void AddLongObtuseEdgePt()
            {
                List <InitialPt> obtuseInit = new List <InitialPt>();

                int loopBreaker = 0;

                for (int i = 0; i < itSegments.Count(); i++)
                {
                    if (loopBreaker > 3)
                    {
                        break;
                    }

                    IndexTagSegment current  = itSegments[i];
                    AngleTagVertex  fromVrtx = atVertices[current.FromIndex];
                    AngleTagVertex  toVrtx   = atVertices[current.ToIndex % atVertices.Count];

                    if (fromVrtx.AngleType == AngleType.Obtuse)
                    {
                        Vector3d maxAlignVec = fromVrtx.PostVec;
                        Vector3d maxPerpVec  = maxAlignVec;
                        maxPerpVec.Rotate(Math.PI / 2, Vector3d.ZAxis);

                        initialPts.Add(new InitialPt(fromVrtx.Pt, maxAlignVec, maxPerpVec));
                    }

                    if (toVrtx.AngleType == AngleType.Obtuse)
                    {
                        Vector3d maxAlignVec = toVrtx.PreVec;
                        Vector3d maxPerpVec  = maxAlignVec;
                        maxPerpVec.Rotate(-Math.PI / 2, Vector3d.ZAxis);

                        initialPts.Add(new InitialPt(toVrtx.Pt, maxAlignVec, maxPerpVec));
                    }

                    loopBreaker++;
                }

                initialPts.AddRange(obtuseInit);
            }
            private List <InitialPt> FindFootOfPerp(Line perpBase, Vector3d perpDirection, AngleTagVertex perpStart, bool perpInvert)
            {
                List <InitialPt> footOfPerps = new List <InitialPt>();

                if (!VectorTools.IsBetweenVector(perpStart.PreVec, perpStart.PostVec, perpDirection))
                {
                    return(footOfPerps);
                }

                Line    crossLay    = new Line(perpStart.Pt, perpStart.Pt + perpDirection);
                Point3d crossOnBase = CCXTools.GetCrossPt(perpBase, crossLay);

                if (crossOnBase == Point3d.Unset || boundCrv.Contains(crossOnBase) == PointContainment.Outside)
                {
                    return(footOfPerps);
                }

                Polyline perpLinePoly = new Polyline {
                    crossOnBase, perpStart.Pt
                };

                Vector3d perpVec = perpStart.Pt - crossOnBase;

                if (perpInvert)
                {
                    perpVec = -perpVec;
                }

                if (!CCXTools.IsIntersectCrv(perpLinePoly, boundary, false))
                {
                    footOfPerps.Add(new InitialPt(crossOnBase, perpBase.UnitTangent, perpVec));
                }

                return(footOfPerps);
            }