Esempio n. 1
0
        public SegD SupportFlat()
        {
            Param parM;

            if ((this.IsDegen) || (this.IsSeg(out parM)))
            {
                return(new SegD(this.Start, this.End));
            }
            if (this.IsSelfInters(out parM))
            {
                double valM = parM.Val;
                if (valM == Param.Infinity)
                {
                    return(new SegD(this.Start, 0.5 * (this.Start + this.Cp(1))));
                }
                if (valM > 1)
                {
                    return(new SegD(this.Start, this.Start + ((valM * valM) / (2 * valM - 1)) * (this.End - this.Start)));
                }
                if (parM.Val < 0)
                {
                    Bez2D bezRev     = this.Reversed as Bez2D;
                    SegD  supportRev = bezRev.SupportFlat();
                    return(supportRev.Reversed as SegD);
                }
            }
            return(null);
        }
Esempio n. 2
0
 public bool Project(LCurve lcurve, out Param param, out VecD pnt)
 {
     /*
      *        MEANING:    the NEAREST point in the PARAMETRIC RANGE
      *                    of the curve
      *
      *        ASSUMPTIONS:    the curve may be not reduced
      */
     param = null;
     pnt   = null;
     if (lcurve.IsDegen)
     {
         SegD seg = lcurve as SegD;
         if (seg == null)
         {
             throw new ExceptionGMath("VecD", "Project", null);
             //return false;
         }
         param = new Param(Param.Degen);
         pnt   = seg.Middle;
         return(true);
     }
     this.Perp(lcurve, out param);
     param.Clip(lcurve.ParamStart, lcurve.ParamEnd);
     pnt = lcurve.Evaluate(param);
     return(true);
 }
Esempio n. 3
0
        public static bool AuxIntersectBB(DegenD degen, SegD seg,
                                          InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            if (linters == null)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBB(degen,seg)", "Null argument");
            }

            // no reduction
            bool connectAB = ((icAB != null) && (icAB.IsConnect));

            if (connectAB)
            {
                return(true);
            }
            Param param;
            VecD  pnt;

            degen.Cp.Project(seg, out param, out pnt);
            if (degen.Cp.Dist(pnt) < MConsts.EPS_DEC)
            {
                IntersD0 inters = new IntersD0(Param.Degen, param, pnt, false);
                linters.Add(inters);
            }
            return(true);
        }
Esempio n. 4
0
        public bool IsSelfInters(out Param parM)
        {
            /*
             *        RETURN VALUE: true if Self-Intersecting; false otherwise
             */
            parM = null;
            if (this.IsDegen)
            {
                return(false);
            }
            Param parSeg;

            if (this.IsSeg(out parSeg))
            {
                return(false);
            }
            SegD seg = new SegD(this.cp[0], this.cp[2]);

            if (seg.IsDegen)
            {
                parM = Param.Infinity;
                return(true);
            }
            LineD line = new LineD(seg);
            VecD  pnt;

            this.cp[1].Project(line, out parM, out pnt);
            if (this.cp[1].Dist(pnt) > MConsts.EPS_DEC)
            {
                return(false);
            }
            return(true);
        }
Esempio n. 5
0
        public VecD DirTang(Param par)
        {
            if (this.IsDegen)
            {
                return(null);
            }
            Param parM;

            if (this.IsSeg(out parM))
            {
                SegD seg = new SegD(this.cp[0], this.cp[2]);
                return((seg as LCurve).DirTang);
            }
            if (this.IsSelfInters(out parM))
            {
                SegD support = this.SupportFlat();
                return((support as LCurve).DirTang);
            }

            VecD tan = 2.0 * (1.0 - par.Val) * (this.cp[1] - this.cp[0]) +
                       2.0 * par.Val * (this.cp[2] - this.cp[1]);

            if (tan.Norm < MConsts.EPS_COMP)
            {
                return(null);
            }
            return((1.0 / tan.Norm) * tan);
        }
Esempio n. 6
0
        public bool Project(Bez2D bez, out Param par, out VecD pnt)
        {
            /*
             *        MEANING:    the NEAREST point in the RANGE [0,1]
             *        ASSUMPTION:    -    bezier can be non-reduced
             *                    -    bezier is NOT self-intersecting
             */
            par = null;
            pnt = null;
            Param parM;

            if (bez.IsSelfInters(out parM))
            {
                throw new ExceptionGMath("VecD", "Project(bez)", null);
                //return false;
            }
            if (bez.IsDegen)
            {
                par = new Param(Param.Degen);
                pnt = bez.Middle;
                return(true);
            }
            if (bez.IsSeg(out parM))
            {
                SegD seg = bez.Reduced as SegD;
                this.Project(seg, out par, out pnt);
                bez.ParamFromSeg(par);
                return(true);
            }
            // case of non-flat Bezier
            Param[] parsPerp;
            if (!this.Perp(bez, out parsPerp))
            {
                return(false);
            }
            double distS   = this.Dist(bez.Start);
            double distE   = this.Dist(bez.End);
            double distMin = Math.Min(distS, distE);
            double parMin  = (distS <= distE)? 0.0: 1.0;

            if (parsPerp != null)
            {
                for (int iPerp = 0; iPerp < parsPerp.Length; iPerp++)
                {
                    if (bez.IsEvaluableStrict(parsPerp[iPerp]))
                    {
                        double distPerp = this.Dist(bez.Evaluate(parsPerp[iPerp]));
                        if (distPerp < distMin)
                        {
                            distMin = distPerp;
                            parMin  = parsPerp[iPerp];
                        }
                    }
                }
            }
            par = parMin;
            pnt = bez.Evaluate(parMin);
            return(true);
        }
Esempio n. 7
0
        public void Subdivide(Param par, out BCurve curveS, out BCurve curveE)
        {
            /*
             *        ASSUMPTION: par should be in the range [0,1]
             */
            curveS = null;
            curveE = null;
            if (!this.IsEvaluableStrict(par))
            {
                return;
            }
            VecD pnt = this.Evaluate(par);

            curveS = new SegD(this.cp[0], pnt);
            curveE = new SegD(pnt, this.cp[1]);
        }
Esempio n. 8
0
        /*
         *        METHODS
         */
        public bool IsSeg(out Param parM)
        {
            /*
             *        MEANING: NON_DEGENERATED, PARAMETRIC segment
             *                 (implies, that the Bezier is not
             *                 self-intersecting)
             */
            parM = null;
            if (this.IsDegen)
            {
                return(false);
            }
            if (this.cp[0] == this.cp[2])
            {
                return(false); // S/I bezier
            }
            if (this.cp[0] == this.cp[1])
            {
                parM = new Param(0);
                return(true);
            }
            if (this.cp[1] == this.cp[2])
            {
                parM = new Param(1);
                return(true);
            }
            SegD  seg  = new SegD(this.cp[0], this.cp[2]);
            LineD line = new LineD(seg);
            VecD  pnt;
            Param par;

            this.cp[1].Project(line, out par, out pnt);
            if (this.cp[1].Dist(pnt) > MConsts.EPS_DEC)
            {
                return(false);
            }
            if (!seg.IsEvaluableStrict(par))
            {
                return(false);
            }
            parM = par;
            if (Math.Abs(parM.Val - 0.5) < MConsts.EPS_DEC)
            {
                parM.Val = 0.5;
            }
            return(true);
        }
Esempio n. 9
0
 /*
  *        METHODS
  */
 public bool IsSeg(out Param parM)
 {    
     /*
      *        MEANING: NON_DEGENERATED, PARAMETRIC segment
      *                 (implies, that the Bezier is not 
      *                 self-intersecting)
      */
     parM=null;
     if (this.IsDegen)
         return false;
     if (this.cp[0]==this.cp[2])
         return false; // S/I bezier
     if (this.cp[0]==this.cp[1])
     {
         parM=new Param(0);
         return true;
     }
     if (this.cp[1]==this.cp[2])
     {
         parM=new Param(1);
         return true;
     }
     SegD seg=new SegD(this.cp[0], this.cp[2]);
     LineD line=new LineD(seg);
     VecD pnt;
     Param par;
     this.cp[1].Project(line,out par,out pnt);
     if (this.cp[1].Dist(pnt)>MConsts.EPS_DEC) 
         return false;
     if (!seg.IsEvaluableStrict(par))
         return false;
     parM=par;
     if (Math.Abs(parM.Val-0.5)<MConsts.EPS_DEC)
     {
         parM.Val=0.5;
     }
     return true;
 }
Esempio n. 10
0
        public static bool AuxIntersectBB(SegD segA, SegD segB,
                                          InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            bool connectAB = ((icAB != null) && (icAB.IsConnect));
            bool connectBA = ((icBA != null) && (icBA.IsConnect));
            bool connect   = connectAB || connectBA;


            InfoInters inters;

            if (!Inters.IntersectLL(segA, segB, out inters))
            {
                return(false);
            }
            if (inters != null)
            {
                if ((!connect) ||
                    ((connect) && (inters.Dim == InfoInters.TypeDim.Dim1)))
                {
                    linters.Add(inters);
                }
            }
            return(true);
        }
Esempio n. 11
0
 public static bool AuxIntersectBB(DegenD degen, SegD seg,
     InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
 {
     if (linters==null)
     {
         throw new ExceptionGMath("Intersect","AuxIntersectBB(degen,seg)","Null argument");
     }
 
     // no reduction
     bool connectAB = ((icAB!=null)&&(icAB.IsConnect));
     if (connectAB)
     {
         return true;
     }
     Param param;
     VecD pnt;
     degen.Cp.Project(seg,out param, out pnt);
     if (degen.Cp.Dist(pnt)<MConsts.EPS_DEC)
     {
         IntersD0 inters=new IntersD0(Param.Degen,param,pnt,false);
         linters.Add(inters);
     }
     return true;
 }
Esempio n. 12
0
        public static bool AuxIntersectBL(SegD seg, LCurve lrs, ListInfoInters linters)
        {
            // segment is irreducable !!!
            if (linters == null)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(seg,lrs)", "Null argument");
            }
            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(seg,lrs)", null);
            }

            InfoInters inters;

            if (!Inters.IntersectLL(seg, lrs, out inters))
            {
                return(false);
            }
            if (inters != null)
            {
                linters.Add(inters);
            }
            return(true);
        }
Esempio n. 13
0
        /*
         *        METHODS:    I_DRAWABLE
         */
        override public void Draw(I_Draw i_draw, DrawParam dp)
        {
            if (((object)this.bboxCP==null)||((object)this.bboxOutl==null))
                return;
            double xMinCP=this.bboxCP.VecMin.X;
            double yMinCP=this.bboxCP.VecMin.Y;
            double xMaxCP=this.bboxCP.VecMax.X;
            double yMaxCP=this.bboxCP.VecMax.Y;
            double xMinOutl=this.bboxOutl.VecMin.X;
            double yMinOutl=this.bboxOutl.VecMin.Y;
            double xMaxOutl=this.bboxOutl.VecMax.X;
            double yMaxOutl=this.bboxOutl.VecMax.Y;

            SegD seg;
            DrawParamCurve dpCurve;
            if (xMinCP<xMinOutl)
            {
                seg=new SegD(new VecD(xMinOutl,yMinCP),
                    new VecD(xMinOutl,yMaxCP));
                dpCurve=new DrawParamCurve("Orange",1.5F,false,null);
                seg.Draw(i_draw,dpCurve);
            }
            if (yMinCP<yMinOutl)
            {
                seg=new SegD(new VecD(xMinCP,yMinOutl),
                    new VecD(xMaxCP,yMinOutl));
                dpCurve=new DrawParamCurve("Orange",1.5F,false,null);
                seg.Draw(i_draw,dpCurve);
            }
            if (xMaxCP>xMaxOutl)
            {
                seg=new SegD(new VecD(xMaxOutl,yMinCP),
                    new VecD(xMaxOutl,yMaxCP));
                dpCurve=new DrawParamCurve("Orange",1.5F,false,null);
                seg.Draw(i_draw,dpCurve);
            }
            if (yMaxCP>yMaxOutl)
            {
                seg=new SegD(new VecD(xMinCP,yMaxOutl),
                    new VecD(xMaxCP,yMaxOutl));
                dpCurve=new DrawParamCurve("Orange",1.5F,false,null);
                seg.Draw(i_draw,dpCurve);
            }
        }
Esempio n. 14
0
        public VecD DirTang(Param par)
        {
            if (this.IsDegen)
                return null;
            Param parM;
            if (this.IsSeg(out parM))
            {
                SegD seg=new SegD(this.cp[0],this.cp[2]);
                return ((seg as LCurve).DirTang);
            }
            if (this.IsSelfInters(out parM))
            {
                SegD support=this.SupportFlat();
                return ((support as LCurve).DirTang);
            }

            VecD tan=2.0*(1.0-par.Val)*(this.cp[1]-this.cp[0])+
                2.0*par.Val*(this.cp[2]-this.cp[1]);
            if (tan.Norm<MConsts.EPS_COMP)
                return null;
            return ((1.0/tan.Norm)*tan);
        }
Esempio n. 15
0
 public bool IsSelfInters(out Param parM)
 {    
     /*
      *        RETURN VALUE: true if Self-Intersecting; false otherwise
      */
     parM=null;
     if (this.IsDegen)
         return false;
     Param parSeg;
     if (this.IsSeg(out parSeg))
         return false;
     SegD seg=new SegD(this.cp[0], this.cp[2]);
     if (seg.IsDegen)
     {
         parM=Param.Infinity;
         return true;
     }
     LineD line=new LineD(seg);
     VecD pnt;
     this.cp[1].Project(line,out parM,out pnt);
     if (this.cp[1].Dist(pnt)>MConsts.EPS_DEC) 
         return false;
     return true;
 }        
Esempio n. 16
0
        public static bool AuxIntersectBL(Bez2D bez, LCurve lrs, ListInfoInters linters)
        {
            // bezier is irreducable !!!
            if (linters == null)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(bez,lrs)", "Null argument");
            }
            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(bez,lrs)", null);
            }

            Param parM;

            if (bez.IsSelfInters(out parM))
            {
                if (parM.Val < 0)
                {
                    Bez2D bezRev          = bez.Reversed as Bez2D;
                    int   numIntersBefore = linters.Count;
                    if (!Inters.AuxIntersectBL(bezRev, lrs, linters))
                    {
                        return(false);
                    }
                    linters.ParamReverse(1, 0, numIntersBefore);
                    return(true);
                }
                SegD       support = bez.SupportFlat();
                InfoInters intersSup;
                if (!Inters.IntersectLL(support, lrs, out intersSup))
                {
                    return(false);
                }
                if (intersSup == null)
                {
                    return(true);
                }

                /*
                 *  convert parameters from support to Bezier
                 */
                // invalidate in case of D1 intersection
                if (intersSup.Dim == InfoInters.TypeDim.Dim1)
                {
                    (intersSup as IntersD1).ParamInvalidateBezSI();
                    linters.Add(intersSup);
                    return(true);
                }

                // write as 1 or 2 intersections with different parameters
                // in case of D0 intersections
                InfoInters[] intersBez;
                if (!bez.IntersFromSupport(intersSup, 0, out intersBez))
                {
                    return(false);
                }
                for (int iIntersBez = 0; iIntersBez < intersBez.Length; iIntersBez++)
                {
                    linters.Add(intersBez[iIntersBez]);
                }
                return(true);
            }

            // bezier is NOT self/intersecting
            VecD[] cfLrs, cfBez;
            lrs.PowerCoeff(out cfLrs);
            bez.PowerCoeff(out cfBez);
            VecD norm = lrs.DirNorm;
            VecD tang = lrs.DirTang;

            double[] roots;
            int      numRootBez;

            Equation.RootsReal(cfBez[2].Dot(norm),
                               cfBez[1].Dot(norm), (cfBez[0] - cfLrs[0]).Dot(norm),
                               out numRootBez, out roots);
            if (numRootBez == Equation.NumRootInfinite)
            {
                // bezier is irreducable,=> only D0 intersections are possible
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(bez,lrs)", null);
                //return false;
            }
            for (int iRoot = 0; iRoot < numRootBez; iRoot++)
            {
                Param parBez = roots[iRoot];
                if (bez.IsEvaluableStrict(parBez))
                {
                    Param parLrs = Equation.Evaluate(parBez.Val,
                                                     cfBez[2].Dot(tang), cfBez[1].Dot(tang),
                                                     (cfBez[0] - cfLrs[0]).Dot(tang)) / (cfLrs[1].Dot(tang));
                    if (lrs.IsEvaluableStrict(parLrs))
                    {
                        IntersD0 inters = new IntersD0(parBez, parLrs,
                                                       0.5 * (lrs.Evaluate(parLrs.Val) + bez.Evaluate(parBez.Val)),
                                                       false);
                        linters.Add(inters);
                    }
                }
            }
            return(true);
        }
Esempio n. 17
0
        public static bool AuxIntersectBL(SegD seg, LCurve lrs, ListInfoInters linters)
        {    
            // segment is irreducable !!!
            if (linters==null)
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBL(seg,lrs)","Null argument");
            }
            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBL(seg,lrs)",null);
            }

            InfoInters inters;
            if (!Inters.IntersectLL(seg, lrs, out inters))
                return false;
            if (inters!=null)
                linters.Add(inters);
            return true;
        }
Esempio n. 18
0
        public static bool AuxIntersectBB(SegD seg, Bez2D bez,
            InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            // both seg & bez are irreducable !!!
            if (linters==null)
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBB(seg,bez)","Null argument");
            }
            
            bool connectAB = ((icAB!=null)&&(icAB.IsConnect));
            bool connectBA = ((icBA!=null)&&(icBA.IsConnect));
            if ((connectBA)&&(!connectAB)) 
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBB(seg,bez)",null);
                //return false;
            }
            bool connect=connectAB||connectBA;

            if (!connect)
            {
                int numIntersBefore=linters.Count;
                if (!Inters.AuxIntersectBL(bez,seg,linters))
                    return false;
                linters.ParamSwap(numIntersBefore);
                return true;
            }

            // bez and seg are connected, => connectAB=true
            Param parM;
            if (bez.IsSelfInters(out parM))
            {
                if (connectBA) // both ends are connected
                {
                    // parM!=Infinity - otherwise the seg is degenerated
                    double valM=parM.Val;
                    IntersD1 inters;
                    if (valM>1)
                    {
                        inters=new IntersD1(0,1,
                            1,1/(2*valM-1),seg,true);
                    }
                    else
                    {
                        inters=new IntersD1(0,1,
                            1,(2*valM)/(2*valM-1),seg,true);
                    }
                    linters.Add(inters);
                    return true;
                }
                if (icAB.IsTangent)
                {
                    return true; // no additional intersections
                }
                else
                {
                    SegD segSupp=bez.SupportFlat();
                    InfoInters inters;
                    if (!Inters.IntersectLL(seg,segSupp,out inters))
                        return false;
                    if (inters==null)
                        return true;
                    inters.ParamInvalidateBezSI();
                    int numIntersBefore=linters.Count;
                    linters.Add(inters);
                    /*
                     *    CLEAN END-POINT if the Bezier does not return to it
                     */
                    bool coversBezStart=bez.CoversEndPoint(true);
                    if (!coversBezStart)
                    {
                        linters.CleanEndPointBezSI(bez.Start,numIntersBefore);
                    }
                    return true;
                }
            }
            
            //    bezier is NOT self-intersecting
            if (connectBA)    
                return true;    // no additional intersections
            if (icAB.IsTangent)
                return true;    // no additional intersections
            
            //    seg & bez are connected and not-tangent,=>
            //    at most one additional point of intersection
            VecD[] cfSeg, cfBez; 
            seg.PowerCoeff(out cfSeg); 
            bez.PowerCoeff(out cfBez);
            VecD tang=(seg as LCurve).DirTang;
            VecD norm=(seg as LCurve).DirNorm;

            // connected but not-tangent: one
            double[] rootsBez;
            int numRootBez;
            Equation.RootsReal(cfBez[2].Dot(norm),cfBez[1].Dot(norm),
                    out numRootBez, out rootsBez); 
            if (numRootBez==Equation.NumRootInfinite)
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBB(seg,bez)",null);
                //return false;
            }
            if (rootsBez==null)
                return true;
            Param parBez=rootsBez[0];
            if (bez.IsEvaluableStrict(parBez))
            {
                double valBez=parBez.Val;
                Param parSeg=1+valBez*(cfBez[2].Dot(tang)*valBez+cfBez[1].Dot(tang))/cfSeg[1].Dot(tang);
                if (seg.IsEvaluableStrict(parSeg)) // ??? && (parSeg!=1)
                {
                    IntersD0 inters=new IntersD0(parSeg,parBez,
                        0.5*(seg.Evaluate(parSeg)+bez.Evaluate(parBez)),false);
                    linters.Add(inters);
                }
            }
            return true;
        }
Esempio n. 19
0
        public bool ProjectGeneral(Bez2D bez, out Param[] pars, out VecD pnt)
        {
            /*
             *        MEANING:    parameter (or parameters) of the nearest point
             *                    in range [0,1]
             *
             *        ASSUMPTIONS:    bezier can be non-reduced
             *                        bezier can be self-intersecting
             *
             */


            pars = null;
            pnt  = null;
            Param parM;

            if (!bez.IsSelfInters(out parM))
            {
                Param par;
                if (!this.Project(bez, out par, out pnt))
                {
                    return(false);
                }
                if (par != null)
                {
                    pars    = new Param[1];
                    pars[0] = par;
                }
                return(true);
            }

            double valM = parM.Val;

            if (parM < 0)
            {
                Bez2D bezRev = new Bez2D(bez);
                bezRev.Reverse();
                if (!this.ProjectGeneral(bezRev, out pars, out pnt))
                {
                    return(false);
                }
                if (pars != null)
                {
                    for (int iPar = 0; iPar < pars.Length; iPar++)
                    {
                        pars[iPar].Reverse(1);
                    }
                }
                return(true);
            }
            SegD  support = bez.SupportFlat();
            Param parSupport;

            if (!this.Project(support, out parSupport, out pnt))
            {
                return(false);
            }
            if (!bez.ParamFromSupport(parSupport, out pars))
            {
                return(false);
            }
            return(true);
        }
Esempio n. 20
0
 public SegD(SegD seg) : this()
 {
     this.cp[0]=new VecD(seg.Cp(0));
     this.cp[1]=new VecD(seg.Cp(1));
 }
Esempio n. 21
0
 public void Subdivide(Param par, out BCurve curveS, out BCurve curveE)
 {
     /*
      *        ASSUMPTION: par should be in the range [0,1]
      */
     curveS=null;
     curveE=null;
     if (!this.IsEvaluableStrict(par))
         return;
     VecD pnt=this.Evaluate(par);
     curveS=new SegD(this.cp[0],pnt);
     curveE=new SegD(pnt,this.cp[1]);
 }
Esempio n. 22
0
 public SegD(SegD seg) : this()
 {
     this.cp[0] = new VecD(seg.Cp(0));
     this.cp[1] = new VecD(seg.Cp(1));
 }
Esempio n. 23
0
        public static bool AuxIntersectBB(SegD seg, Bez2D bez,
                                          InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            // both seg & bez are irreducable !!!
            if (linters == null)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBB(seg,bez)", "Null argument");
            }

            bool connectAB = ((icAB != null) && (icAB.IsConnect));
            bool connectBA = ((icBA != null) && (icBA.IsConnect));

            if ((connectBA) && (!connectAB))
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBB(seg,bez)", null);
                //return false;
            }
            bool connect = connectAB || connectBA;

            if (!connect)
            {
                int numIntersBefore = linters.Count;
                if (!Inters.AuxIntersectBL(bez, seg, linters))
                {
                    return(false);
                }
                linters.ParamSwap(numIntersBefore);
                return(true);
            }

            // bez and seg are connected, => connectAB=true
            Param parM;

            if (bez.IsSelfInters(out parM))
            {
                if (connectBA) // both ends are connected
                {
                    // parM!=Infinity - otherwise the seg is degenerated
                    double   valM = parM.Val;
                    IntersD1 inters;
                    if (valM > 1)
                    {
                        inters = new IntersD1(0, 1,
                                              1, 1 / (2 * valM - 1), seg, true);
                    }
                    else
                    {
                        inters = new IntersD1(0, 1,
                                              1, (2 * valM) / (2 * valM - 1), seg, true);
                    }
                    linters.Add(inters);
                    return(true);
                }
                if (icAB.IsTangent)
                {
                    return(true); // no additional intersections
                }
                else
                {
                    SegD       segSupp = bez.SupportFlat();
                    InfoInters inters;
                    if (!Inters.IntersectLL(seg, segSupp, out inters))
                    {
                        return(false);
                    }
                    if (inters == null)
                    {
                        return(true);
                    }
                    inters.ParamInvalidateBezSI();
                    int numIntersBefore = linters.Count;
                    linters.Add(inters);

                    /*
                     *    CLEAN END-POINT if the Bezier does not return to it
                     */
                    bool coversBezStart = bez.CoversEndPoint(true);
                    if (!coversBezStart)
                    {
                        linters.CleanEndPointBezSI(bez.Start, numIntersBefore);
                    }
                    return(true);
                }
            }

            //    bezier is NOT self-intersecting
            if (connectBA)
            {
                return(true);    // no additional intersections
            }
            if (icAB.IsTangent)
            {
                return(true);    // no additional intersections
            }
            //    seg & bez are connected and not-tangent,=>
            //    at most one additional point of intersection
            VecD[] cfSeg, cfBez;
            seg.PowerCoeff(out cfSeg);
            bez.PowerCoeff(out cfBez);
            VecD tang = (seg as LCurve).DirTang;
            VecD norm = (seg as LCurve).DirNorm;

            // connected but not-tangent: one
            double[] rootsBez;
            int      numRootBez;

            Equation.RootsReal(cfBez[2].Dot(norm), cfBez[1].Dot(norm),
                               out numRootBez, out rootsBez);
            if (numRootBez == Equation.NumRootInfinite)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBB(seg,bez)", null);
                //return false;
            }
            if (rootsBez == null)
            {
                return(true);
            }
            Param parBez = rootsBez[0];

            if (bez.IsEvaluableStrict(parBez))
            {
                double valBez = parBez.Val;
                Param  parSeg = 1 + valBez * (cfBez[2].Dot(tang) * valBez + cfBez[1].Dot(tang)) / cfSeg[1].Dot(tang);
                if (seg.IsEvaluableStrict(parSeg)) // ??? && (parSeg!=1)
                {
                    IntersD0 inters = new IntersD0(parSeg, parBez,
                                                   0.5 * (seg.Evaluate(parSeg) + bez.Evaluate(parBez)), false);
                    linters.Add(inters);
                }
            }
            return(true);
        }
Esempio n. 24
0
        public static bool AuxIntersectBB(SegD segA, SegD segB,
            InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            bool connectAB = ((icAB!=null)&&(icAB.IsConnect));
            bool connectBA = ((icBA!=null)&&(icBA.IsConnect));            
            bool connect=connectAB||connectBA;
            

            InfoInters inters;
            if (!Inters.IntersectLL(segA,segB,out inters))
                return false;
            if (inters!=null)
            {
                if ((!connect)||
                    ((connect)&&(inters.Dim==InfoInters.TypeDim.Dim1)))
                {
                    linters.Add(inters);
                }
            }
            return true;
        }