Ejemplo n.º 1
0
        public bool IsSelfInters(out InfoInters inters)
        {
            /*
             *        RETURN VALUE: true if Self-Intersecting; false otherwise
             */
            inters = null;
            Param parM;

            if (!IsSelfInters(out parM))
            {
                return(false);
            }
            if (parM.Val == Param.Infinity)
            {
                inters = new IntersD1(0, null, 1, null, this, true);
            }
            else if (parM > 1)
            {
                Param  paramStart  = 1.0 / (2.0 * parM.Val - 1.0);
                BCurve curveInters = this.SubCurve(paramStart, 1);
                if (curveInters == null)
                {
                    throw new ExceptionGMath("Bez2D", "IsSelfInters", "");
                }
                inters = new IntersD1(paramStart, null, 1.0, null, curveInters, true);
            }
            else if (parM < 0)
            {
                Param  paramEnd    = (-2.0 * parM.Val) / (1.0 - 2.0 * parM.Val);
                BCurve curveInters = this.SubCurve(0, paramEnd);
                if (curveInters == null)
                {
                    throw new ExceptionGMath("Bez2D", "IsSelfInters", "");
                }
                inters = new IntersD1(0.0, null, paramEnd, null, curveInters, true);
            }
            return(true);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
 public bool IsSelfInters(out InfoInters inters)
 {
     /*
      *        RETURN VALUE: true if Self-Intersecting; false otherwise
      */
     inters=null;
     Param parM;
     if (!IsSelfInters(out parM))
         return false;
     if (parM.Val==Param.Infinity)
     {
         inters=new IntersD1(0,null,1,null,this,true);
     }
     else if (parM>1)
     {
         Param paramStart=1.0/(2.0*parM.Val-1.0);
         BCurve curveInters=this.SubCurve(paramStart,1);
         if (curveInters==null)
         {
             throw new ExceptionGMath("Bez2D","IsSelfInters","");
         }
         inters=new IntersD1(paramStart,null,1.0,null,curveInters,true);
     }
     else if (parM<0)
     {
         Param paramEnd=(-2.0*parM.Val)/(1.0-2.0*parM.Val);
         BCurve curveInters=this.SubCurve(0,paramEnd);
         if (curveInters==null)
         {
             throw new ExceptionGMath("Bez2D","IsSelfInters","");
         }
         inters=new IntersD1(0.0,null,paramEnd,null,curveInters,true);
     }
     return true;
 }
Ejemplo n.º 4
0
        public static bool RefineIntersLLD1(LCurve lrsA, LCurve lrsB,
                                            out InfoInters inters)
        {
            inters = null;
            if ((lrsA is SegD) && (lrsB is SegD))
            {
                BCurve curveA = lrsA as BCurve;
                BCurve curveB = lrsB as BCurve;
                return(Inters.RefineIntersBBD1(curveA, curveB, out inters));
            }
            if (lrsA.LComplexity > lrsB.LComplexity)
            {
                bool res = Inters.RefineIntersLLD1(lrsB, lrsA, out inters);
                if (inters != null)
                {
                    inters.ParamSwap();
                }
                return(res);
            }
            VecD a0 = lrsA.Start;
            VecD a1 = lrsA.End;
            VecD b0 = lrsB.Start;
            VecD b1 = lrsB.End;

            Param paramBInvA0, paramBInvA1;
            bool  isOn;

            if ((!a0.InverseOn(lrsB, out isOn, out paramBInvA0)) || (!isOn))
            {
                return(false);
            }
            if ((!a1.InverseOn(lrsB, out isOn, out paramBInvA1)) || (!isOn))
            {
                return(false);
            }
            Param paramAInvB0, paramAInvB1;

            if ((!b0.InverseOn(lrsA, out isOn, out paramAInvB0)) || (!isOn))
            {
                return(false);
            }
            if ((!b1.InverseOn(lrsA, out isOn, out paramAInvB1)) || (!isOn))
            {
                return(false);
            }

            bool areCoDirected = (paramBInvA1.Val >= paramBInvA0.Val);

            if (!areCoDirected)
            {
                if (lrsA is LineD)
                {
                    if (lrsB is LineD)
                    {
                        paramAInvB0 = (areCoDirected)? -Param.Infinity: Param.Infinity;
                        paramAInvB1 = (areCoDirected)? Param.Infinity: -Param.Infinity;

                        inters = new IntersD1(paramAInvB0, -Param.Infinity,
                                              paramAInvB1, Param.Infinity, lrsB, false);
                        return(true);
                    }
                    if (lrsB is RayD)
                    {
                        paramAInvB1 = (areCoDirected)? Param.Infinity: -Param.Infinity;
                        inters      = new IntersD1(paramAInvB0, 0,
                                                   paramAInvB1, Param.Infinity, lrsB, false);
                        return(true);
                    }
                    if (lrsB is SegD)
                    {
                        inters = new IntersD1(paramAInvB0, 0,
                                              paramAInvB1, 1, lrsB, false);
                        return(true);
                    }
                }
                if (lrsA is RayD)
                {
                    if (lrsB is RayD)
                    {
                        if (areCoDirected)
                        {
                            if (paramAInvB0 > 0)
                            {
                                inters = new IntersD1(paramAInvB0, 0,
                                                      Param.Infinity, Param.Infinity, lrsB, false);
                                return(true);
                            }
                            else
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      Param.Infinity, Param.Infinity, lrsA, false);
                                return(true);
                            }
                        }
                        else
                        {
                            if (paramAInvB0 > 0)
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      paramAInvB0, 0, new SegD(a0, b0), false);
                                return(true);
                            }
                        }
                    }
                    if (lrsB is SegD)
                    {
                        // intersection is known to have dimension D1 !!!
                        if ((paramBInvA0 >= 1) || (paramBInvA0 <= 0))
                        {
                            inters = new IntersD1(paramAInvB0, 0,
                                                  paramAInvB1, 1, new SegD(b0, b1), false);
                            return(true);
                        }
                        if ((0 < paramBInvA0) && (paramBInvA1 < 1))
                        {
                            if (areCoDirected)
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      paramAInvB1, 1, new SegD(a0, b1), false);
                                return(true);
                            }
                            else
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      paramAInvB0, 0, new SegD(a0, b0), false);
                                return(true);
                            }
                        }
                    }
                }
            }
            throw new ExceptionGMath("Intersect", "RefineIntersLLD1", null);
            //return false;
        }
Ejemplo n.º 5
0
        /*
         *        REFINE INTERSECTION D1
         */


        public static bool RefineIntersBBD1(BCurve curveA, BCurve curveB,
                                            out InfoInters inters)
        {
            /*
             *        ASSUMPTIONS:
             *            -    curveA & curveB are MAXIMALLY REDUCED
             *            -    intersection is KNOWN to have dimension D1
             *            -    does not work in case of SI beziers
             *        =>    OR: both curveA & curveB are SEGMENTS
             *            OR:    both curveA & curveB are BEZIER
             */
            inters = null;
            InfoInters selfinters;

            if (curveA.IsSelfInters(out selfinters) || curveB.IsSelfInters(out selfinters))
            {
                throw new ExceptionGMath("Intersect", "RefineIntersBBD1", null);
                //return false;
            }
            VecD a0 = curveA.Start;
            VecD a1 = curveA.End;

            Param paramBInvA0, paramBInvA1;
            bool  isOn;

            if (!a0.InverseOn(curveB, out isOn, out paramBInvA0) || (!isOn))
            {
                return(false);
            }
            if (!a1.InverseOn(curveB, out isOn, out paramBInvA1) || (!isOn))
            {
                return(false);
            }
            paramBInvA0.Round(0, 1);
            paramBInvA1.Round(0, 1);
            bool areCoDirected = (paramBInvA1 >= paramBInvA0);

            if (!areCoDirected)
            {
                BCurve revB = curveB.Reversed as BCurve;
                if (!Inters.RefineIntersBBD1(curveA, revB, out inters))
                {
                    return(false);
                }
                if (inters != null)
                {
                    inters.ParamReverse(1, 1);
                }
                return(true);
            }
            VecD  b0 = curveB.Start;
            VecD  b1 = curveB.End;
            Param paramAInvB0, paramAInvB1;

            if (!b0.InverseOn(curveA, out isOn, out paramAInvB0) || (!isOn))
            {
                return(false);
            }
            if (!b1.InverseOn(curveA, out isOn, out paramAInvB1) || (!isOn))
            {
                return(false);
            }
            paramAInvB0.Round(0, 1);
            paramAInvB1.Round(0, 1);

            Param paramInA = null, paramInB = null, paramOutA = null, paramOutB = null;
            VecD  pntIn = null, pntOut = null;

            if (paramBInvA0 <= 0)    // before or start
            {
                paramInA = paramAInvB0;
                paramInB = 0;
                pntIn    = b0;
            }
            else if (paramBInvA0 < 1)    // inner
            {
                paramInA = 0;
                paramInB = paramBInvA0;
                pntIn    = a0;
            }

            if ((paramBInvA1 >= 0) && (paramBInvA1 <= 1)) // inner or end
            {
                paramOutA = 1;
                paramOutB = paramBInvA1;
                pntOut    = a1;
            }
            else if (paramBInvA1 > 1) // after
            {
                paramOutA = paramAInvB1;
                paramOutB = 1;
                pntOut    = b1;
            }
            if ((pntIn == null) || (pntOut == null))
            {
                throw new ExceptionGMath("Intersect", "RefineIntersBBD1", null);
                //return false;
            }

            Curve curveInters = curveA.SubCurve(paramInA, paramOutA);

            inters = new IntersD1(paramInA, paramInB,
                                  paramOutA, paramOutB, curveInters, false);
            return(true);
        }
Ejemplo n.º 6
0
            /*
             *        REFINE INTERSECTION D1
             */
                

        public static bool RefineIntersBBD1(BCurve curveA, BCurve curveB,
            out InfoInters inters)
        {
                /*
                 *        ASSUMPTIONS:
                 *            -    curveA & curveB are MAXIMALLY REDUCED
                 *            -    intersection is KNOWN to have dimension D1
                 *            -    does not work in case of SI beziers
                 *        =>    OR: both curveA & curveB are SEGMENTS
                 *            OR:    both curveA & curveB are BEZIER
                 */        
            inters=null;
            InfoInters selfinters;
            if (curveA.IsSelfInters(out selfinters)||curveB.IsSelfInters(out selfinters))
            {
                throw new ExceptionGMath("Intersect","RefineIntersBBD1",null);
                //return false;
            }
            VecD a0=curveA.Start;
            VecD a1=curveA.End;

            Param paramBInvA0, paramBInvA1;
            bool isOn;
            if (!a0.InverseOn(curveB, out isOn, out paramBInvA0)||(!isOn))
                return false;
            if (!a1.InverseOn(curveB, out isOn, out paramBInvA1)||(!isOn))
                return false;
            paramBInvA0.Round(0,1);
            paramBInvA1.Round(0,1);
            bool areCoDirected=(paramBInvA1>=paramBInvA0);
            if (!areCoDirected)
            {
                BCurve revB=curveB.Reversed as BCurve;
                if (!Inters.RefineIntersBBD1(curveA,revB,out inters))
                    return false;
                if (inters!=null)
                {
                    inters.ParamReverse(1,1);
                }
                return true;
            }
            VecD b0=curveB.Start;
            VecD b1=curveB.End;
            Param paramAInvB0, paramAInvB1;
            if (!b0.InverseOn(curveA, out isOn, out paramAInvB0)||(!isOn))
                return false;
            if (!b1.InverseOn(curveA, out isOn, out paramAInvB1)||(!isOn))
                return false;
            paramAInvB0.Round(0,1);
            paramAInvB1.Round(0,1);

            Param paramInA=null, paramInB=null, paramOutA=null, paramOutB=null;
            VecD pntIn=null, pntOut=null;
            if (paramBInvA0<=0)    // before or start
            {
                paramInA=paramAInvB0;
                paramInB=0;
                pntIn=b0;
            }
            else if (paramBInvA0<1)    // inner
            {
                paramInA=0;
                paramInB=paramBInvA0;
                pntIn=a0;
            }
            
            if ((paramBInvA1>=0)&&(paramBInvA1<=1)) // inner or end
            {
                paramOutA=1;
                paramOutB=paramBInvA1;
                pntOut=a1;
            }
            else if (paramBInvA1>1) // after
            {
                paramOutA=paramAInvB1;
                paramOutB=1;
                pntOut=b1;
            }
            if     ((pntIn==null)||(pntOut==null))
            {
                throw new ExceptionGMath("Intersect","RefineIntersBBD1",null);
                //return false;
            }

            Curve curveInters=curveA.SubCurve(paramInA,paramOutA);
            inters=new IntersD1(paramInA,paramInB,
                paramOutA,paramOutB,curveInters,false);
            return true;
        }
Ejemplo n.º 7
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;
        }
Ejemplo n.º 8
0
        public static bool RefineIntersLLD1(LCurve lrsA, LCurve lrsB,
            out InfoInters inters)
        {
            inters=null;
            if ((lrsA is SegD) && (lrsB is SegD))
            {
                BCurve curveA=lrsA as BCurve;
                BCurve curveB=lrsB as BCurve;
                return Inters.RefineIntersBBD1(curveA, curveB, out inters);
            }
            if (lrsA.LComplexity>lrsB.LComplexity)
            {
                bool res=Inters.RefineIntersLLD1(lrsB,lrsA,out inters);
                if (inters!=null)
                {
                    inters.ParamSwap();
                }
                return res;
            }
            VecD a0=lrsA.Start;
            VecD a1=lrsA.End;
            VecD b0=lrsB.Start;
            VecD b1=lrsB.End;

            Param paramBInvA0, paramBInvA1;
            bool isOn;
            if ((!a0.InverseOn(lrsB, out isOn, out paramBInvA0))||(!isOn))
                return false;
            if ((!a1.InverseOn(lrsB, out isOn, out paramBInvA1))||(!isOn))
                return false;
            Param paramAInvB0, paramAInvB1;
            if ((!b0.InverseOn(lrsA, out isOn, out paramAInvB0))||(!isOn))
                return false;
            if ((!b1.InverseOn(lrsA, out isOn, out paramAInvB1))||(!isOn))
                return false;

            bool areCoDirected=(paramBInvA1.Val>=paramBInvA0.Val);
            if (!areCoDirected)
            {
                if (lrsA is LineD)
                {
                    if (lrsB is LineD)
                    {
                        paramAInvB0=(areCoDirected)? -Param.Infinity: Param.Infinity;
                        paramAInvB1=(areCoDirected)? Param.Infinity: -Param.Infinity;
                        
                        inters=new IntersD1(paramAInvB0,-Param.Infinity, 
                            paramAInvB1,Param.Infinity,lrsB,false);
                        return true;
                    }
                    if (lrsB is RayD)
                    {
                        paramAInvB1=(areCoDirected)? Param.Infinity: -Param.Infinity;
                        inters=new IntersD1(paramAInvB0,0,
                            paramAInvB1,Param.Infinity,lrsB,false);
                        return true;
                    }
                    if (lrsB is SegD)
                    {
                        inters=new IntersD1(paramAInvB0,0,
                            paramAInvB1,1,lrsB,false);
                        return true;
                    }
                }
                if (lrsA is RayD)
                {
                    if (lrsB is RayD)
                    {
                        if (areCoDirected)
                        {
                            if (paramAInvB0>0)
                            {
                                inters=new IntersD1(paramAInvB0,0,
                                    Param.Infinity,Param.Infinity,lrsB,false);
                                return true;
                            }
                            else 
                            {
                                inters=new IntersD1(0,paramBInvA0,
                                    Param.Infinity,Param.Infinity,lrsA,false);
                                return true;
                            }
                        }
                        else
                        {
                            if (paramAInvB0>0)
                            {
                                inters=new IntersD1(0,paramBInvA0,
                                    paramAInvB0,0,new SegD(a0,b0),false);
                                return true;
                            }
                        }
                    }
                    if (lrsB is SegD)
                    {
                        // intersection is known to have dimension D1 !!!
                        if ((paramBInvA0>=1)||(paramBInvA0<=0))
                        {
                            inters=new IntersD1(paramAInvB0,0,
                                paramAInvB1,1,new SegD(b0,b1),false);
                            return true;
                        }
                        if ((0<paramBInvA0)&&(paramBInvA1<1))
                        {
                            if (areCoDirected)
                            {
                                inters=new IntersD1(0,paramBInvA0,
                                    paramAInvB1,1,new SegD(a0,b1),false);
                                return true;
                            }
                            else
                            {
                                inters=new IntersD1(0,paramBInvA0,
                                    paramAInvB0,0,new SegD(a0,b0),false);
                                return true;
                            }
                        }
                    }
                }
            }
            throw new ExceptionGMath("Intersect","RefineIntersLLD1",null);
            //return false;
        }