Example #1
0
 public void ParamFromReduced(BCurve bcurve, int indCurve)
 {
     if (this.param[indCurve]!=null)
     {
         this.param[indCurve].FromReduced(bcurve);    
     }
 }
Example #2
0
        public static bool IntersectBL(BCurve bcurve, LCurve lrs, ListInfoInters linters)
        {
            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("Intersect", "IntersectBL", null);
                //return false;
            }

            BCurve bred            = bcurve.Reduced;
            int    numIntersBefore = linters.Count;

            object[]   pars       = { bred, lrs, linters };
            Type[]     types      = { pars[0].GetType(), typeof(LCurve), typeof(ListInfoInters) };
            MethodInfo infoMethod = typeof(Inters).GetMethod("AuxIntersectBL", types);
            bool       res;

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

            if ((object)bred != (object)bcurve)
            {
                linters.ParamFromReduced(bcurve, 0, numIntersBefore);
            }
            return(res);
        }
Example #3
0
 public void ParamFromReduced(BCurve bcurve, int indCurve)
 {
     if (this.param[indCurve] != null)
     {
         this.param[indCurve].FromReduced(bcurve);
     }
 }
Example #4
0
 public void ParamFromReduced(BCurve bcurve, int indCurve, int pozStart)
 {
     for (int poz = pozStart; poz < this.linters.Count; poz++)
     {
         InfoInters inters = linters[poz] as InfoInters;
         inters.ParamFromReduced(bcurve, indCurve);
     }
 }
Example #5
0
        /*
         *        METHODS: MISORIENTED
         */

        public bool RayAlmostNormal(out RayD ray, out CParam parStartRay)
        {
            ray         = null;
            parStartRay = null;

            bool isCurveOK   = false;
            int  numTrialMax = 100; // TODO: make constant
            int  numTrialCur = 0;

            while ((!isCurveOK) && (numTrialCur < numTrialMax))
            {
                numTrialCur++;
                try
                {
                    int pozKnotStart = rand.Next(this.NumKnot);

                    BCurve curveStart = this.CurveByPoz(pozKnotStart);
                    if (curveStart == null)
                    {
                        pozKnotStart = this.PozNext(pozKnotStart);
                        curveStart   = this.CurveByPoz(pozKnotStart);
                        if (curveStart == null)
                        {
                            //Debug.Assert(false, "Contour: RayAlmostNormal");
                            continue;
                        }
                    }
                    InfoInters inters;
                    if ((!curveStart.IsDegen) && (curveStart.BBox.Diag >= 1 - MConsts.EPS_DEC_WEAK) &&
                        (!curveStart.IsSelfInters(out inters)))
                    {
                        double parVal = 0.25 * rand.Next(1, 4);

                        VecD pntStart = curveStart.Evaluate(parVal);
                        VecD dirNorm  = curveStart.DirNorm(parVal);
                        if ((pntStart == null) || (dirNorm == null))
                        {
                            //Debug.Assert(false, "Contour: RayAlmostNormal");
                            continue;
                        }
                        double angleRot = (rand.NextDouble() - 0.5) * (Math.PI / 5.0);
                        double scale    = 100.0;   // TODO: make constant
                        VecD   dirRay   = new VecD(scale * (Math.Cos(angleRot) * dirNorm.X - Math.Sin(angleRot) * dirNorm.Y),
                                                   scale * (Math.Sin(angleRot) * dirNorm.X + Math.Cos(angleRot) * dirNorm.Y));
                        bool isChanged;
                        dirRay.FURound(out isChanged);
                        ray         = new RayD(pntStart, pntStart + dirRay);
                        parStartRay = new CParam(parVal, this.KnotByPoz(pozKnotStart));
                        isCurveOK   = true;
                    }
                }
                catch (ExceptionGMath)
                {
                }
            }
            return(isCurveOK);
        }
Example #6
0
        public bool Intersect(ListInfoInters linters)
        {
            bool res = true;

            for (int pozA = 0; pozA < this.NumKnot - 1; pozA++)
            {
                BCurve curveA = this.CurveByPoz(pozA);
                if (curveA != null)
                {
                    Knot       knA = this.KnotByPoz(pozA);
                    InfoInters inters;
                    if (curveA.IsSelfInters(out inters))
                    {
                        inters.ParamToCParam(knA, null);
                        linters.Add(inters);
                    }
                    bool isDegenA = curveA.IsDegen;
                    for (int pozB = pozA + 1; pozB < this.NumKnot; pozB++)
                    {
                        BCurve curveB = this.CurveByPoz(pozB);
                        if (curveB != null)
                        {
                            bool isDegenB = curveB.IsDegen;
                            if (isDegenA || isDegenB)
                            {
                                bool areConjAB, areConjBA;
                                if ((!this.AreConjByPozPoz(pozA, pozB, out areConjAB)) ||
                                    (!this.AreConjByPozPoz(pozB, pozA, out areConjBA)))
                                {
                                    res = false;
                                    continue;
                                }
                                if (areConjAB || areConjBA)
                                {
                                    continue;
                                }
                            }
                            InfoConnect icAB, icBA;
                            if ((!this.InfoConnectByPozPoz(pozA, pozB, out icAB)) ||
                                (!this.InfoConnectByPozPoz(pozB, pozA, out icBA)))
                            {
                                res = false;
                                continue;
                            }
                            int  numIntersBefore = linters.Count;
                            Knot knB             = this.KnotByPoz(pozB);

                            Inters.IntersectBB(curveA, curveB, icAB, icBA, linters);
                            linters.ParamToCParam(knA, knB, numIntersBefore);
                        }
                    }
                }
            }
            return(res);
        }
Example #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;
     }
     curveS = new DegenD(this.cp);
     curveE = new DegenD(this.cp);
 }
Example #8
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]);
        }
Example #9
0
        public bool Intersect(Contour cont, ListInfoInters linters)
        {
            Contour contA = this;
            Contour contB = cont;

            if (contA == contB)
            {
                return(this.Intersect(linters));
            }
            BoxD bboxContA = contA.BBox;
            BoxD bboxContB = contB.BBox;

            if (!bboxContA.HasInters(bboxContB))
            {
                return(true);
            }

            for (int pozA = 0; pozA < contA.NumKnot; pozA++)
            {
                Knot   knA    = contA.KnotByPoz(pozA);
                BCurve curveA = contA.CurveByPoz(pozA);
                if (curveA != null)
                {
                    BoxD bboxCurveA = curveA.BBox;
                    if (bboxCurveA.HasInters(bboxContB))
                    {
                        for (int pozB = 0; pozB < contB.NumKnot; pozB++)
                        {
                            BCurve curveB = contB.CurveByPoz(pozB);
                            if (curveB != null)
                            {
                                int numIntersBefore = linters.Count;
                                Inters.IntersectBB(curveA, curveB, null, null, linters);
                                Knot knB = contB.KnotByPoz(pozB);
                                linters.ParamToCParam(knA, knB, numIntersBefore);
                            }
                        }
                    }
                }
            }

            contA = null;
            contB = null;
            return(true);
        }
Example #10
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 pnt01 = (1 - par.Val) * this.cp[0] + par.Val * this.cp[1];
            VecD pnt12 = (1 - par.Val) * this.cp[1] + par.Val * this.cp[2];
            VecD pnt   = (1 - par.Val) * pnt01 + par.Val * pnt12;

            curveS = new Bez2D(this.cp[0], pnt01, pnt);
            curveE = new Bez2D(pnt, pnt12, this.cp[2]);
        }
Example #11
0
 public void FromReduced(BCurve bcurve)
 {
     // parameter of the (reduced)curve may be invalidated if
     // the curve intersects the self-intersecting Bezier
     if (this.val == Param.Invalid)
     {
         return;
     }
     if (bcurve.IsDegen)
     {
         return;
     }
     if (bcurve is Bez2D)
     {
         Bez2D bez = bcurve as Bez2D;
         Param parM;
         if (bez.IsSeg(out parM))
         {
             bez.ParamFromSeg(this);
         }
     }
 }
Example #12
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);
        }
Example #13
0
        /*
         *        METHODS:    I_DRAWABLE
         */

        public void Draw(I_Draw i_draw, DrawParam dp)
        {
            // for debug only - begin

            /*
             * if (this.rayTmp!=null)
             * {
             *  DrawParamCurve dpCurve=new DrawParamCurve("Cyan",1,false,null);
             *  this.rayTmp.Draw(i_draw, dpCurve);
             * }
             */
            // for debug only - end
            DrawParamContour dpContour = dp as DrawParamContour;

            if (dpContour != null)
            {
                DrawParamKnot dpKnot = dpContour.DPKnot;
                if (dpKnot != null)
                {
                    foreach (Knot knot in this.knots)
                    {
                        knot.Draw(i_draw, dpKnot);
                    }
                }
                DrawParamCurve dpCurve = dpContour.DPCurve;
                if (dpCurve != null)
                {
                    for (int poz = 0; poz < this.NumKnot; poz++)
                    {
                        BCurve curve = this.CurveByPoz(poz);
                        if (curve != null)
                        {
                            curve.Draw(i_draw, dpCurve);
                        }
                    }
                }
            }
        }
Example #14
0
 virtual public void ParamFromReduced(BCurve bcurve, int indCurve)
 {
     throw new ExceptionGMath("InfoInters", "ParamFromReduced", "Pure virtual function");
 }
Example #15
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;


        }
Example #16
0
        public static bool IntersectBL(BCurve bcurve, LCurve lrs, ListInfoInters linters)
        {
            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("Intersect","IntersectBL",null);
                //return false;
            }

            BCurve bred = bcurve.Reduced;
            int numIntersBefore=linters.Count;

            object[] pars={bred,lrs,linters};
            Type[] types={pars[0].GetType(),typeof(LCurve),typeof(ListInfoInters)};
            MethodInfo infoMethod=typeof(Inters).GetMethod("AuxIntersectBL",types);
            bool res;
            try
            {
                res=(bool)infoMethod.Invoke(null,pars);
            }
            catch(System.Reflection.TargetInvocationException TIException)
            {
                throw TIException.InnerException;
            }

            if ((object)bred!=(object)bcurve)
            {
                linters.ParamFromReduced(bcurve,0,numIntersBefore);
            }
            return res;
        }
Example #17
0
 override public void ParamFromReduced(BCurve bcurve, int indCurve)
 {
     this.ipis[0].ParamFromReduced(bcurve,indCurve);
     this.ipis[1].ParamFromReduced(bcurve,indCurve);
 }
Example #18
0
 public void FromReduced(BCurve bcurve)
 {
     // parameter of the (reduced)curve may be invalidated if
     // the curve intersects the self-intersecting Bezier
     if (this.val==Param.Invalid)
         return;
     if (bcurve.IsDegen)
     {
         return;
     }
     if (bcurve is Bez2D)
     {
         Bez2D bez=bcurve as Bez2D;
         Param parM;
         if (bez.IsSeg(out parM))
         {
             bez.ParamFromSeg(this);
         }
     }
 }
Example #19
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;
     curveS=new DegenD(this.cp);
     curveE=new DegenD(this.cp);
 }
Example #20
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;
        }
Example #21
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);
        }
Example #22
0
        public static bool AuxIntersectBB(Bez2D bezA, Bez2D bezB,
                                          InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            // bezA and bezB are irreducable !!!

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

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

            Param parM;
            bool  isSelfIntersA = bezA.IsSelfInters(out parM);
            bool  isSelfIntersB = bezB.IsSelfInters(out parM);

            if (isSelfIntersA || isSelfIntersB)
            {
                BCurve curveA = bezA;
                if (isSelfIntersA)
                {
                    curveA = bezA.SupportFlat();
                }
                BCurve curveB = bezB;
                if (isSelfIntersB)
                {
                    curveB = bezB.SupportFlat();
                }
                int numIntersBefore = linters.Count;
                Inters.IntersectBB(curveA, curveB, null, null, linters);

                /*
                 *    CLEAN END-POINT if the curve does not return to it
                 */
                if ((connectAB) && (!connectBA))
                {
                    bool coversA1 = false;
                    bool coversB0 = false;
                    if (isSelfIntersA)
                    {
                        coversA1 = bezA.CoversEndPoint(false);
                    }
                    if (isSelfIntersB)
                    {
                        coversB0 = bezB.CoversEndPoint(true);
                    }
                    if ((!coversA1) && (!coversB0))
                    {
                        linters.CleanEndPointBezSI(bezA.End, numIntersBefore);
                    }
                }
                linters.ParamInvalidateBezSI(numIntersBefore);
                return(true);
            }

            // test for 1-dimensional intersection of supports
            bool  isB0OnA, isB2OnA;
            Param paramAInvB0, paramAInvB2;

            if (!bezB.Cp(0).InverseOn(bezA, out isB0OnA, out paramAInvB0))
            {
                return(false);
            }
            if (!bezB.Cp(2).InverseOn(bezA, out isB2OnA, out paramAInvB2))
            {
                return(false);
            }
            if ((isB0OnA) && (isB2OnA))
            {
                bool  areCoincide = true;
                Param par;
                for (int i = 1; i <= 3; i++)
                {
                    //    evaluate bezB at paramaters 1/4, 1/2, 3/4 and check
                    //    whether the points lie on bezA [-Infinity,Infinity]
                    VecD pnt = bezB.Evaluate(0.25 * i);
                    if (!pnt.InverseOn(bezA, out areCoincide, out par))
                    {
                        return(false);
                    }
                    if (!areCoincide)
                    {
                        break;
                    }
                }
                if (areCoincide)
                {
                    Param.TypeParam typeB0 = bezA.ParamClassify(paramAInvB0);
                    Param.TypeParam typeB2 = bezA.ParamClassify(paramAInvB2);
                    int             mult   = (int)typeB0 * (int)typeB2;

                    if (mult == 4)
                    {
                        return(true); // no intersections
                    }
                    else if (mult == 1)
                    {
                        // bezB is degenerated
                        throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null);
                        //return false;
                    }
                    else if (mult == 2)
                    {
                        // 0-dimentional connection at the end point
                        if ((typeB0 == Param.TypeParam.Start) &&
                            (typeB2 == Param.TypeParam.Before))
                        {
                            if (connect)
                            {
                                throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null);
                                //return false;
                            }
                            IntersD0 inters = new IntersD0(0, 0, bezB.Start, false);
                            linters.Add(inters);
                            return(true);
                        }
                        if ((typeB0 == Param.TypeParam.Before) &&
                            (typeB2 == Param.TypeParam.Start))
                        {
                            if (connect)
                            {
                                throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null);
                                //return false;
                            }
                            IntersD0 inters = new IntersD0(1, 0, bezB.End, false);
                            linters.Add(inters);
                            return(true);
                        }
                        if ((typeB0 == Param.TypeParam.End) &&
                            (typeB2 == Param.TypeParam.After))
                        {
                            if (!connect)
                            {
                                IntersD0 inters = new IntersD0(0, 1, bezB.Start, false);
                                linters.Add(inters);
                                return(true);
                            }
                            return(true);
                        }
                        if ((typeB0 == Param.TypeParam.After) &&
                            (typeB2 == Param.TypeParam.End))
                        {
                            if (connect)
                            {
                                throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null);
                                //return false;
                            }
                            IntersD0 inters = new IntersD0(1, 1, bezB.End, false);
                            linters.Add(inters);
                            return(true);
                        }
                    }
                    else if (mult <= 0)
                    {
                        InfoInters inters;
                        Inters.RefineIntersBBD1(bezA, bezB, out inters);
                        linters.Add(inters);
                        return(true);
                    }
                    throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null);
                    //return false;
                }
            }

            /*
             *        INTERSECTION IS 0-DIMENTIONAL AT MOST
             */
            VecD[] cfA, cfB;
            bezA.PowerCoeff(out cfA);
            bezB.PowerCoeff(out cfB);

            Param parA, parB;
            int   numRootB;

            double[] rootsB;
            double   kappa = cfA[2].Cross(cfA[1]);

            // bezA and bezB are non-degenerated and consequent
            if (connectAB)
            {
                if (bezA.End != bezB.Start)
                {
                    throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null);
                    //return false;
                }

                if (connectBA)
                {
                    // both ends are connected
                    if (bezA.Start != bezB.End)
                    {
                        throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null);
                        //return false;
                    }

                    if (icAB.IsTangent || icBA.IsTangent)
                    {
                        // tangent connection - no additional intersections
                        return(true);
                    }

                    double   crossA2B2 = cfA[2].Cross(cfB[2]);
                    double[] cfEqn     = { kappa *(kappa + 2 * crossA2B2 + cfA[1].Cross(cfB[2])),
                                           -crossA2B2 * (2 * kappa + crossA2B2),
                                           crossA2B2 *crossA2B2 };
                    Equation.RootsReal(cfEqn[2], cfEqn[1], cfEqn[0],
                                       out numRootB, out rootsB);
                    if (numRootB == Equation.NumRootInfinite)
                    {
                        throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null);
                        //return false;
                    }
                    if (rootsB != null)
                    {
                        for (int iRoot = 0; iRoot < numRootB; iRoot++)
                        {
                            parB = rootsB[iRoot];
                            if (bezB.IsEvaluableStrict(parB))
                            {
                                parA = 1.0 +
                                       parB.Val * (cfA[2].Cross(cfB[2]) * parB.Val +
                                                   cfA[2].Cross(cfB[1])) / kappa;
                                if (bezA.IsEvaluableStrict(parA) /*&& (parA!=1.)*/)
                                {
                                    IntersD0 inters = new IntersD0(parA, parB,
                                                                   0.5 * (bezA.Evaluate(parA) + bezB.Evaluate(parB)),
                                                                   false);
                                    linters.Add(inters);
                                }
                            }
                        }
                    }

                    return(true);
                }

                // consequent Bezier with one connection
                if (icAB.IsTangent)
                {
                    // tangent connection - at most 2 additional intersections
                    double[] cfEqn = { kappa *(kappa - cfB[2].Cross(cfB[1])),
                                       2 * cfA[2].Cross(cfB[2]) * kappa,
                                       cfA[2].Cross(cfB[2]) * cfA[2].Cross(cfB[2]) };
                    Equation.RootsReal(cfEqn[2], cfEqn[1], cfEqn[0],
                                       out numRootB, out rootsB);
                    if (numRootB == Equation.NumRootInfinite)
                    {
                        throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null);
                        //return false;
                    }
                    if (rootsB != null)
                    {
                        for (int iRoot = 0; iRoot < numRootB; iRoot++)
                        {
                            parB = rootsB[iRoot];
                            if (bezB.IsEvaluableStrict(parB))
                            {
                                parA = 1 +
                                       parB.Val * (cfA[2].Cross(cfB[2]) * parB.Val +
                                                   cfA[2].Cross(cfB[1])) / kappa;
                                if (bezA.IsEvaluableStrict(parA) /*&&(parA!=1)*/)
                                {
                                    IntersD0 inters = new IntersD0(parA, parB,
                                                                   0.5 * (bezA.Evaluate(parA) + bezB.Evaluate(parB)),
                                                                   false);
                                    linters.Add(inters);
                                }
                            }
                        }
                    }
                    return(true);
                }
                else
                {
                    // non-tangent connection - at most 3 additional intersections
                    double[] cfEqn = { kappa *(2 * cfA[2].Cross(cfB[1]) + cfA[1].Cross(cfB[1])),
                                       cfA[2].Cross(cfB[1]) * cfA[2].Cross(cfB[1]) +
                                       kappa * (2 * cfA[2].Cross(cfB[2]) + cfA[1].Cross(cfB[2])),
                                       2 * cfA[2].Cross(cfB[2]) * cfA[2].Cross(cfB[1]),
                                       cfA[2].Cross(cfB[2]) * cfA[2].Cross(cfB[2]) };
                    Equation.RootsReal(cfEqn[3], cfEqn[2], cfEqn[1], cfEqn[0],
                                       out numRootB, out rootsB);
                    if (numRootB == Equation.NumRootInfinite)
                    {
                        throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null);
                        //return false;
                    }
                    if (rootsB != null)
                    {
                        for (int iRoot = 0; iRoot < numRootB; iRoot++)
                        {
                            parB = rootsB[iRoot];
                            if (bezB.IsEvaluableStrict(parB))
                            {
                                parA = 1 +
                                       parB.Val * (cfA[2].Cross(cfB[2]) * parB +
                                                   cfA[2].Cross(cfB[1])) / kappa;
                                if (bezA.IsEvaluableStrict(parA) /*&&(parA!=1)*/)
                                {
                                    IntersD0 inters = new IntersD0(parA, parB,
                                                                   0.5 * (bezA.Evaluate(parA) + bezB.Evaluate(parB)),
                                                                   false);
                                    linters.Add(inters);
                                }
                            }
                        }
                    }
                    return(true);
                }
            }

            // bezA and bezB are non-degenerated, non-consequent curves
            bool isSwappedAB = false;

            if (Math.Abs(cfA[2].Cross(cfA[1])) < Math.Abs(cfB[2].Cross(cfB[1])))
            {
                kappa       = cfB[2].Cross(cfB[1]);
                isSwappedAB = true;
                VecD tmp;
                for (int i = 0; i < 3; i++)
                {
                    tmp = cfA[i]; cfA[i] = cfB[i]; cfB[i] = tmp;
                }
            }
            double[] e = { cfA[2].Cross(cfB[0] - cfA[0]),
                           cfA[2].Cross(cfB[1]),
                           cfA[2].Cross(cfB[2]) };
            double[] f = { (cfB[0] - cfA[0]).Cross(cfA[1]),
                           cfB[1].Cross(cfA[1]),
                           cfB[2].Cross(cfA[1]) };
            Equation.RootsReal(e[2] * e[2],
                               2 * e[2] * e[1],
                               e[1] * e[1] + 2 * e[2] * e[0] - kappa * f[2],
                               2 * e[1] * e[0] - kappa * f[1],
                               e[0] * e[0] - kappa * f[0],
                               out numRootB, out rootsB);

            if (numRootB == Equation.NumRootInfinite)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null);
                //return false;
            }
            if (rootsB != null)
            {
                for (int iRoot = 0; iRoot < numRootB; iRoot++)
                {
                    parB = rootsB[iRoot];
                    parA = Equation.Evaluate(parB.Val, e[2], e[1], e[0]) / kappa;
                    if (isSwappedAB)
                    {
                        Param parTmp;
                        parTmp = parA;
                        parA   = parB;
                        parB   = parTmp;
                    }
                    if (bezA.IsEvaluableStrict(parA) && bezB.IsEvaluableStrict(parB))
                    {
                        IntersD0 inters = new IntersD0(parA, parB,
                                                       0.5 * (bezA.Evaluate(parA) + bezB.Evaluate(parB)),
                                                       false);
                        linters.Add(inters);
                    }
                }
            }
            return(true);
        }
Example #23
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);
        }
Example #24
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]);
 }
Example #25
0
 override public void ParamFromReduced(BCurve bcurve, int indCurve)
 {
     this.ipis[0].ParamFromReduced(bcurve, indCurve);
     this.ipis[1].ParamFromReduced(bcurve, indCurve);
 }
Example #26
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 pnt01=(1-par.Val)*this.cp[0]+par.Val*this.cp[1];
     VecD pnt12=(1-par.Val)*this.cp[1]+par.Val*this.cp[2];
     VecD pnt = (1-par.Val)*pnt01+par.Val*pnt12;
     curveS=new Bez2D(this.cp[0],pnt01,pnt);
     curveE=new Bez2D(pnt,pnt12,this.cp[2]);
 }
Example #27
0
        public bool RayParity(RayD ray, CParam parStartRay,
                              out MConsts.TypeParity typeParity)
        {
            /*
             *        ASSUMPTIONS
             *        INPUT:
             *            -    (parStartRay==null) is the ray does not start at
             *                the contour
             *        RETURN VALUE;
             *            -    (false) in case of real failure;
             *                (true)+(typeParity==Undef) in unclear cases
             *
             */
            typeParity = MConsts.TypeParity.Undef;
            ListInfoInters linters = new ListInfoInters();

            bool isStartIntersFound = false;

            for (int pozKnot = 0; pozKnot < this.NumKnot; pozKnot++)
            {
                BCurve curve = this.CurveByPoz(pozKnot);
                if (curve != null)
                {
                    Knot knot            = this.KnotByPoz(pozKnot);
                    int  numIntersBefore = linters.Count;
                    if (!Inters.IntersectBL(curve, ray, linters))
                    {
                        linters.ClearDestroy();
                        return(false);
                    }
                    int numIntersAfter = linters.Count;
                    if (numIntersAfter != numIntersBefore)
                    {
                        InfoInters inters;
                        if ((curve.IsDegen) || (curve.IsSelfInters(out inters)))
                        {
                            linters.ClearDestroy();
                            return(true);
                        }
                    }
                    bool isRayStartOnCurve = ((parStartRay != null) &&
                                              (parStartRay.IndKnot == knot.IndexKnot));

                    for (int iInters = numIntersBefore; iInters < numIntersAfter; iInters++)
                    {
                        InfoInters inters = linters[iInters] as InfoInters;
                        if (inters.Dim == InfoInters.TypeDim.Dim1)
                        {
                            linters.ClearDestroy();
                            return(true);
                        }
                        IntersD0 intersD0    = inters as IntersD0;
                        double   parValCurve = intersD0.Ipi.Par(0).Val;
                        double   parValRay   = intersD0.Ipi.Par(1).Val;
                        if (Math.Abs(parValRay) < MConsts.EPS_DEC)
                        {
                            if ((!isRayStartOnCurve) || (isRayStartOnCurve && isStartIntersFound))
                            {
                                linters.ClearDestroy();
                                return(true);
                            }
                            isStartIntersFound = true;
                        }
                        if ((Math.Abs(parValCurve) < MConsts.EPS_DEC_WEAK) ||
                            (Math.Abs(1.0 - parValCurve) < MConsts.EPS_DEC_WEAK))
                        {
                            linters.ClearDestroy();
                            return(true);
                        }

                        VecD dirTangCurve = curve.DirTang(parValCurve);
                        VecD dirTangRay   = (ray as LCurve).DirTang;
                        if ((dirTangCurve == null) || (dirTangRay == null))
                        {
                            linters.ClearDestroy();
                            return(true);
                        }
                        if (Math.Abs(dirTangRay.Cross(dirTangCurve)) < MConsts.EPS_DEC_WEAK)
                        {
                            linters.ClearDestroy();
                            return(true);
                        }
                    }
                    if ((isRayStartOnCurve) && (!isStartIntersFound))
                    {
                        linters.ClearDestroy();
                        return(true);
                    }
                }
            }
            int numIntersAll = (isStartIntersFound)? linters.Count - 1: linters.Count;

            typeParity = (numIntersAll % 2 == 0)? MConsts.TypeParity.Even: MConsts.TypeParity.Odd;
            linters.ClearDestroy();
            return(true);
        }
Example #28
0
 virtual public void ParamFromReduced(BCurve bcurve, int indCurve)
 {
     throw new ExceptionGMath("InfoInters","ParamFromReduced","Pure virtual function");
 }
Example #29
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;
        }
Example #30
0
 public void ParamFromReduced(BCurve bcurve, int indCurve, int pozStart)
 {
     for (int poz=pozStart; poz<this.linters.Count; poz++)
     {
         InfoInters inters=linters[poz] as InfoInters;
         inters.ParamFromReduced(bcurve,indCurve);
     }        
 }