Exemple #1
0
        public static bool IntersectBB(BCurve curveA, BCurve curveB,
                                       InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            BoxD bboxA = curveA.BBox;
            BoxD bboxB = curveB.BBox;

            if (!bboxA.HasInters(bboxB))
            {
                return(true);
            }

            int numIntersBefore = linters.Count;

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

            if (toReverseByConnection)
            {
                if (!Inters.IntersectBB(curveB, curveA, icBA, icAB, linters))
                {
                    return(false);
                }
                linters.ParamSwap(numIntersBefore);
                return(false);
            }

            BCurve redA = curveA.Reduced;
            BCurve redB = curveB.Reduced;
            bool   toReverseByComplexity = (redA.BComplexity > redB.BComplexity);

            object[] pars = { redA, redB, icAB, icBA, linters };
            if (toReverseByComplexity)
            {
                // TODO: check !!!
                // TODO: what happens with connection info ???
                pars[0] = redB.Reversed;
                pars[1] = redA.Reversed;
            }

            Type[]     types = { pars[0].GetType(), pars[1].GetType(),
                                 typeof(InfoConnect),   typeof(InfoConnect), typeof(ListInfoInters) };
            MethodInfo infoMethod = typeof(Inters).GetMethod("AuxIntersectBB", types);
            bool       res;

            try
            {
                res = (bool)infoMethod.Invoke(null, pars);
            }
            catch (System.Reflection.TargetInvocationException TIException)
            {
                throw TIException.InnerException;
            }

            if (toReverseByComplexity)
            {
                linters.ParamReverse(1, 0, numIntersBefore);
                linters.ParamReverse(1, 1, numIntersBefore);
                linters.ParamSwap(numIntersBefore);
            }
            if ((object)redA != (object)curveA)
            {
                linters.ParamFromReduced(curveA, 0, numIntersBefore);
            }
            if ((object)redB != (object)curveB)
            {
                linters.ParamFromReduced(curveB, 1, numIntersBefore);
            }

            // clean-up end-point intersections
            linters.CleanEndPointInters(connectAB, connectBA, numIntersBefore);
            return(res);
        }
Exemple #2
0
        public static bool IntersectBB(BCurve curveA, BCurve curveB, 
            InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            BoxD bboxA=curveA.BBox;
            BoxD bboxB=curveB.BBox;
            if (!bboxA.HasInters(bboxB))
                return true;

            int numIntersBefore=linters.Count;

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

            if (toReverseByConnection)
            {
                if (!Inters.IntersectBB(curveB,curveA,icBA,icAB,linters))
                    return false;
                linters.ParamSwap(numIntersBefore);
                return false;
            }
        
            BCurve redA = curveA.Reduced;
            BCurve redB = curveB.Reduced;
            bool toReverseByComplexity=(redA.BComplexity>redB.BComplexity);

            object[] pars={redA,redB,icAB,icBA,linters};
            if (toReverseByComplexity)
            {
                // TODO: check !!!
                // TODO: what happens with connection info ???
                pars[0]=redB.Reversed;
                pars[1]=redA.Reversed;
            }
            
            Type[] types={pars[0].GetType(),pars[1].GetType(),
                             typeof(InfoConnect),typeof(InfoConnect),typeof(ListInfoInters)};
            MethodInfo infoMethod=typeof(Inters).GetMethod("AuxIntersectBB",types);
            bool res;
            try
            {
                res=(bool)infoMethod.Invoke(null,pars);
            }
            catch(System.Reflection.TargetInvocationException TIException)
            {
                throw TIException.InnerException;
            }
            
            if (toReverseByComplexity)
            {
                linters.ParamReverse(1,0,numIntersBefore); 
                linters.ParamReverse(1,1,numIntersBefore);
                linters.ParamSwap(numIntersBefore);
            }
            if ((object)redA!=(object)curveA)
            {
                linters.ParamFromReduced(curveA,0,numIntersBefore);
            }
            if ((object)redB!=(object)curveB)
            {
                linters.ParamFromReduced(curveB,1,numIntersBefore);
            }

            // clean-up end-point intersections
            linters.CleanEndPointInters(connectAB,connectBA,numIntersBefore);    
            return res;


        }
Exemple #3
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);
        }
Exemple #4
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;
        }