Ejemplo n.º 1
0
        public static bool AuxIntersectBB(DegenD degen, SegD seg,
                                          InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            if (linters == null)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBB(degen,seg)", "Null argument");
            }

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

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

            degen.Cp.Project(seg, out param, out pnt);
            if (degen.Cp.Dist(pnt) < MConsts.EPS_DEC)
            {
                IntersD0 inters = new IntersD0(Param.Degen, param, pnt, false);
                linters.Add(inters);
            }
            return(true);
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 3
0
        /*
         *        INTERSECTIONS: (BCurve,LCurve)
         *            - lcurve is required non-degenerated
         *
         *        NOTES:        -    Curves are maximally reduced in AuxIntersectBL
         *                    -    Self/intersecting Bezier is NOT a reduction
         *                        from bezier
         */

        public static bool AuxIntersectBL(DegenD degen, LCurve lrs, ListInfoInters linters)
        {
            //    IMPORTANT (TODO):
            //    such intersection is NOT VALID for computation of ray's parity
            if (linters == null)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(degen,lrs)", "Null argument");
            }
            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(degen,lrs)", null);
            }
            if (lrs is SegD)
            {
                return(Inters.AuxIntersectBB(degen, lrs as SegD, null, null, linters));
            }

            LineD line = new LineD(lrs);
            Param param;
            VecD  pnt;

            if (!degen.Cp.Project(line, out param, out pnt))
            {
                return(false);
            }
            if (degen.Cp.Dist(pnt) < MConsts.EPS_DEC)
            {
                if (lrs.IsEvaluableStrict(param))
                {
                    IntersD0 inters = new IntersD0(Param.Degen, param, pnt, false);
                    linters.Add(inters);
                }
            }
            return(true);
        }
Ejemplo n.º 4
0
        public bool IntersectComponents(Component componentA,
                                        Component componentB,
                                        ListInfoInters linters)
        {
            if ((componentA == null) || (componentB == null))
            {
                throw new ExceptionGMath("Outline", "IntersectComponents", null);
                //return false;
            }

            if (componentA == componentB)
            {
                return(true);
            }
            bool res = true;

            for (int pozContA = componentA.PozContStart;
                 pozContA < componentA.PozContStart + componentA.NumCont;
                 pozContA++)
            {
                Contour contA = this.ContourByPoz(pozContA);
                for (int pozContB = componentB.PozContStart;
                     pozContB < componentB.PozContStart + componentB.NumCont;
                     pozContB++)
                {
                    Contour contB = this.ContourByPoz(pozContB);
                    if (!contA.Intersect(contB, linters))
                    {
                        res = false;
                    }
                }
            }
            return(res);
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
        public static bool AuxIntersectBB(DegenD degen, Bez2D bez,
                                          InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            if (linters == null)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBB(degen,bez)", "Null argument");
            }

            // no reduction !!

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

            if (connect)
            {
                return(true);
            }

            // bbox check
            if (!bez.BBox.Contains(degen.Cp))
            {
                return(true);
            }

            Param[] pars;
            VecD    pnt;

            if (!degen.Cp.ProjectGeneral(bez, out pars, out pnt))
            {
                return(false);
            }
            if (degen.Cp.Dist(pnt) < MConsts.EPS_DEC)
            {
                Param parM;
                bool  isSelfInters = bez.IsSelfInters(out parM);
                for (int iPar = 0; iPar < pars.Length; iPar++)
                {
                    IntersD0 inters = new IntersD0(Param.Degen, pars[iPar], pnt, isSelfInters);
                    linters.Add(inters);
                }
            }
            return(true);
        }
Ejemplo n.º 8
0
        public bool Intersect(ListInfoInters linters)
        {
            bool res = true;

            foreach (Contour cont in this.conts)
            {
                bool isWrapped;
                if (!cont.IsWrapped(out isWrapped))
                {
                    res = false;
                }
                else
                {
                    if (!isWrapped)
                    {
                        cont.Intersect(linters);
                    }
                }
            }
            for (int pozA = 0; pozA < this.NumCont - 1; pozA++)
            {
                Contour contA = this.ContourByPoz(pozA);
                for (int pozB = pozA + 1; pozB < this.NumCont; pozB++)
                {
                    Contour contB = this.ContourByPoz(pozB);
                    bool    isDuplicated;
                    if (!contA.AreDuplicated(contB, out isDuplicated))
                    {
                        res = false;
                    }
                    else
                    {
                        if (!isDuplicated)
                        {
                            if (!contA.Intersect(contB, linters))
                            {
                                res = false;
                            }
                        }
                    }
                }
            }
            return(res);
        }
Ejemplo n.º 9
0
 /*
  *        INTERSECTIONS: (BCurve,BCurve)
  *            - ORDER is IMPORTANT 
  *                order:    if infoConnect are not nulls, => 
  *                        it is supposed that curveA(1)=curveB(0)
  *
  *        NOTES:        -    InfoConnect are supposed to be CORRECT
  *                    -    Curves are maximally reduced in AuxIntersectBB
  *                    -    Self/intersecting Bezier is NOT a reduction
  *                        from bezier
  */
  
 
 public static bool AuxIntersectBB(DegenD degenA, DegenD degenB, 
     InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
 {
     if (linters==null)
     {
         throw new ExceptionGMath("Intersect","AuxIntersectBB(degen,degen)","Null argument");
     }
     bool connectAB = ((icAB!=null)&&(icAB.IsConnect));
     bool connectBA = ((icBA!=null)&&(icBA.IsConnect));
     bool connect = connectAB||connectBA;
     if (connect)  // connect,=> no "real" intersections
     {
         return true;
     }
     if (degenA.Cp==degenB.Cp) // coincide but are not known to be connected
     {
         IntersD0 inters=new IntersD0(Param.Degen,Param.Degen,
             0.5*(degenA.Cp+degenB.Cp),false);
         linters.Add(inters);
     }
     return true;
 }
Ejemplo n.º 10
0
        public static bool AuxIntersectBB(DegenD degen, Bez2D bez,
            InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            if (linters==null)
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBB(degen,bez)","Null argument");
            }
            
            // no reduction !!
            
            bool connectAB = ((icAB!=null)&&(icAB.IsConnect));
            bool connectBA = ((icBA!=null)&&(icBA.IsConnect));
            bool connect=connectAB||connectBA;
            if (connect)
            {
                return true;
            }

            // bbox check
            if (!bez.BBox.Contains(degen.Cp))
                return true;

            Param[] pars;
            VecD pnt;
            if (!degen.Cp.ProjectGeneral(bez,out pars, out pnt))
                return false;
            if (degen.Cp.Dist(pnt)<MConsts.EPS_DEC)
            {
                Param parM;
                bool isSelfInters=bez.IsSelfInters(out parM);
                for (int iPar=0; iPar<pars.Length; iPar++)
                {
                    IntersD0 inters=new IntersD0(Param.Degen,pars[iPar],pnt,isSelfInters);
                    linters.Add(inters);
                }
            }
            return true;
        }
Ejemplo n.º 11
0
        /*
         *        INTERSECTIONS: (BCurve,BCurve)
         *            - ORDER is IMPORTANT
         *                order:    if infoConnect are not nulls, =>
         *                        it is supposed that curveA(1)=curveB(0)
         *
         *        NOTES:        -    InfoConnect are supposed to be CORRECT
         *                    -    Curves are maximally reduced in AuxIntersectBB
         *                    -    Self/intersecting Bezier is NOT a reduction
         *                        from bezier
         */


        public static bool AuxIntersectBB(DegenD degenA, DegenD degenB,
                                          InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            if (linters == null)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBB(degen,degen)", "Null argument");
            }
            bool connectAB = ((icAB != null) && (icAB.IsConnect));
            bool connectBA = ((icBA != null) && (icBA.IsConnect));
            bool connect   = connectAB || connectBA;

            if (connect)  // connect,=> no "real" intersections
            {
                return(true);
            }
            if (degenA.Cp == degenB.Cp) // coincide but are not known to be connected
            {
                IntersD0 inters = new IntersD0(Param.Degen, Param.Degen,
                                               0.5 * (degenA.Cp + degenB.Cp), false);
                linters.Add(inters);
            }
            return(true);
        }
Ejemplo n.º 12
0
 public static bool AuxIntersectBB(DegenD degen, SegD seg,
     InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
 {
     if (linters==null)
     {
         throw new ExceptionGMath("Intersect","AuxIntersectBB(degen,seg)","Null argument");
     }
 
     // no reduction
     bool connectAB = ((icAB!=null)&&(icAB.IsConnect));
     if (connectAB)
     {
         return true;
     }
     Param param;
     VecD pnt;
     degen.Cp.Project(seg,out param, out pnt);
     if (degen.Cp.Dist(pnt)<MConsts.EPS_DEC)
     {
         IntersD0 inters=new IntersD0(Param.Degen,param,pnt,false);
         linters.Add(inters);
     }
     return true;
 }
Ejemplo n.º 13
0
        public static bool AuxIntersectBB(SegD segA, SegD segB,
                                          InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            bool connectAB = ((icAB != null) && (icAB.IsConnect));
            bool connectBA = ((icBA != null) && (icBA.IsConnect));
            bool connect   = connectAB || connectBA;


            InfoInters inters;

            if (!Inters.IntersectLL(segA, segB, out inters))
            {
                return(false);
            }
            if (inters != null)
            {
                if ((!connect) ||
                    ((connect) && (inters.Dim == InfoInters.TypeDim.Dim1)))
                {
                    linters.Add(inters);
                }
            }
            return(true);
        }
Ejemplo n.º 14
0
        public static bool AuxIntersectBL(SegD seg, LCurve lrs, ListInfoInters linters)
        {
            // segment is irreducable !!!
            if (linters == null)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(seg,lrs)", "Null argument");
            }
            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(seg,lrs)", null);
            }

            InfoInters inters;

            if (!Inters.IntersectLL(seg, lrs, out inters))
            {
                return(false);
            }
            if (inters != null)
            {
                linters.Add(inters);
            }
            return(true);
        }
Ejemplo n.º 15
0
        public GErrContInters(int indGlyphOwner, ListInfoInters linters)
        {
            // ValInfoBasic
            base.TypeBasic = ValInfoType.Error;
            base.Name = "GERR_CONT_INTERS";
            base.ValueUser = null;
            base.NameFileErrs = GErrConsts.FILE_RES_GERR_STRINGS;
            base.NameAsmFileErrs = GErrConsts.ASM_RES_GERR_STRINGS;
            base.TagPrincipal = "glyf";
    
            // GErr
            base.indexGlyphOwner = indGlyphOwner;
            base.typeGlyph = GConsts.TypeGlyph.Simple;
            base.severity = GErr.TypeGErrSeverity.High;
            base.SetScope(GScope.TypeGScope._GGO_);

            // this
            this.linters = linters;
        }
Ejemplo n.º 16
0
 internal StatusGV.TypeStatusExec ValidateCompComponentInters(GErrList gerrlist)
 {
     ArrayList arrLinters=new ArrayList();
     if ((this.comp==null)||(this.outl==null))
     {
         //throw new ExceptionGlyph("Glyph","ValidateCompComponentInters",null);
         return StatusGV.TypeStatusExec.Aborted;
     }
     int numComponent=this.comp.NumComponent;
     for (int pozComponentA=0; pozComponentA<numComponent-1; pozComponentA++)
     {
         Component componentA=this.comp.ComponentByPoz(pozComponentA);
         for (int pozComponentB=pozComponentA+1; pozComponentB<numComponent; pozComponentB++)
         {
             ListInfoInters linters=new ListInfoInters();
             Component componentB=this.comp.ComponentByPoz(pozComponentB);
             bool areDuplicated;
             this.outl.AreDuplicatedComponents(componentA,componentB,out areDuplicated);
             if (areDuplicated)
                 continue;
             this.outl.IntersectComponents(componentA, componentB, linters);
     
             if (linters.Count!=0)
             {
                 linters.SetIndGlyphComponent(componentA.IndexGlyphComponent,
                     componentB.IndexGlyphComponent);
                 arrLinters.Add(linters);
             }
         }
     }
     if (arrLinters.Count!=0)
     {
         GErr gerr=new GErrComponentInters(this.index, arrLinters);
         gerrlist.Add(gerr);
     }
     return StatusGV.TypeStatusExec.Completed;
 }
Ejemplo n.º 17
0
        public static bool AuxIntersectBL(Bez2D bez, LCurve lrs, ListInfoInters linters)
        {
            // bezier is irreducable !!!
            if (linters == null)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(bez,lrs)", "Null argument");
            }
            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(bez,lrs)", null);
            }

            Param parM;

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

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

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

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

            double[] roots;
            int      numRootBez;

            Equation.RootsReal(cfBez[2].Dot(norm),
                               cfBez[1].Dot(norm), (cfBez[0] - cfLrs[0]).Dot(norm),
                               out numRootBez, out roots);
            if (numRootBez == Equation.NumRootInfinite)
            {
                // bezier is irreducable,=> only D0 intersections are possible
                throw new ExceptionGMath("Intersect", "AuxIntersectBL(bez,lrs)", null);
                //return false;
            }
            for (int iRoot = 0; iRoot < numRootBez; iRoot++)
            {
                Param parBez = roots[iRoot];
                if (bez.IsEvaluableStrict(parBez))
                {
                    Param parLrs = Equation.Evaluate(parBez.Val,
                                                     cfBez[2].Dot(tang), cfBez[1].Dot(tang),
                                                     (cfBez[0] - cfLrs[0]).Dot(tang)) / (cfLrs[1].Dot(tang));
                    if (lrs.IsEvaluableStrict(parLrs))
                    {
                        IntersD0 inters = new IntersD0(parBez, parLrs,
                                                       0.5 * (lrs.Evaluate(parLrs.Val) + bez.Evaluate(parBez.Val)),
                                                       false);
                        linters.Add(inters);
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 18
0
 internal StatusGV.TypeStatusExec ValidateSimpContInters(GErrList gerrlist)
 {
     /*
      *        MEANING:    finds ALL intersections: 
      *                    including D0, D1 and S/I bezier
      */
     ListInfoInters linters = new ListInfoInters();
     if (this.outl==null)
     {
         //throw new ExceptionGlyph("Glyph","ValidateSimpContInters",null);
         return StatusGV.TypeStatusExec.Aborted;
     }
     if (!this.outl.Intersect(linters))
     {
         //throw new ExceptionGlyph("Glyph","ValidateSimpContInters",null);
         return StatusGV.TypeStatusExec.Aborted;
     }
     if (linters.Count>0)
     {
         GErr gerr=new GErrContInters(this.index, linters);
         gerrlist.Add(gerr);
         //this.isOrientDefined=false;
     }
     return StatusGV.TypeStatusExec.Completed;
 }
Ejemplo n.º 19
0
        public static bool AuxIntersectBL(Bez2D bez, LCurve lrs, ListInfoInters linters)
        {
            // bezier is irreducable !!!
            if (linters==null)
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBL(bez,lrs)","Null argument");
            }
            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBL(bez,lrs)",null);
            }
        
            Param parM;
            if (bez.IsSelfInters(out parM))
            {
                if (parM.Val<0)
                {
                    Bez2D bezRev=bez.Reversed as Bez2D;
                    int numIntersBefore=linters.Count;
                    if (!Inters.AuxIntersectBL(bezRev,lrs,linters))
                        return false;
                    linters.ParamReverse(1,0,numIntersBefore);
                    return true;
                }
                SegD support=bez.SupportFlat();
                InfoInters intersSup;
                if (!Inters.IntersectLL(support, lrs, out intersSup))
                    return false;
                if (intersSup==null)
                    return true;
                /*
                 *  convert parameters from support to Bezier
                 */
                // invalidate in case of D1 intersection
                if (intersSup.Dim==InfoInters.TypeDim.Dim1)
                {
                    (intersSup as IntersD1).ParamInvalidateBezSI();
                    linters.Add(intersSup);
                    return true;
                }

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

            // bezier is NOT self/intersecting
            VecD[] cfLrs, cfBez; 
            lrs.PowerCoeff(out cfLrs);
            bez.PowerCoeff(out cfBez);
            VecD norm=lrs.DirNorm;
            VecD tang=lrs.DirTang;
                
            double[] roots;
            int numRootBez;
            Equation.RootsReal(cfBez[2].Dot(norm), 
                cfBez[1].Dot(norm),(cfBez[0]-cfLrs[0]).Dot(norm),
                out numRootBez, out roots);
            if (numRootBez==Equation.NumRootInfinite)
            {
                // bezier is irreducable,=> only D0 intersections are possible
                throw new ExceptionGMath("Intersect","AuxIntersectBL(bez,lrs)",null);
                //return false;
            }
            for (int iRoot=0; iRoot<numRootBez; iRoot++)
            {
                Param parBez=roots[iRoot];
                if (bez.IsEvaluableStrict(parBez))
                {
                    Param parLrs=Equation.Evaluate(parBez.Val,
                        cfBez[2].Dot(tang), cfBez[1].Dot(tang),
                        (cfBez[0]-cfLrs[0]).Dot(tang))/(cfLrs[1].Dot(tang));
                    if (lrs.IsEvaluableStrict(parLrs))
                    {
                        IntersD0 inters=new IntersD0(parBez,parLrs,
                            0.5*(lrs.Evaluate(parLrs.Val)+bez.Evaluate(parBez.Val)),
                            false);
                        linters.Add(inters);
                    }
                }
            }
            return true;
        }
Ejemplo n.º 20
0
 public bool Intersect(ListInfoInters linters)
 {
     bool res=true;
     foreach (Contour cont in this.conts)
     {
         bool isWrapped;
         if (!cont.IsWrapped(out isWrapped))
         {
             res=false;
         }
         else
         {
             if (!isWrapped)
             {
                 cont.Intersect(linters);
             }
         }
     }
     for (int pozA=0; pozA<this.NumCont-1; pozA++)
     {
         Contour contA=this.ContourByPoz(pozA);
         for (int pozB=pozA+1; pozB<this.NumCont; pozB++)
         {
             Contour contB=this.ContourByPoz(pozB);
             bool isDuplicated;    
             if (!contA.AreDuplicated(contB, out isDuplicated))
             {
                 res=false;
             }
             else
             {
                 if (!isDuplicated)
                 {
                     if (!contA.Intersect(contB, linters))
                     {
                         res=false;
                     }
                 }
             }
         }
     }
     return res;
 }
Ejemplo n.º 21
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);
        }
Ejemplo n.º 22
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.º 23
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);
        }
Ejemplo n.º 24
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;
        }
Ejemplo n.º 25
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;


        }
Ejemplo n.º 26
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;
        }
Ejemplo n.º 27
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;
        }
Ejemplo n.º 28
0
        /*
         *        INTERSECTIONS: (BCurve,LCurve)
         *            - lcurve is required non-degenerated
         *
         *        NOTES:        -    Curves are maximally reduced in AuxIntersectBL
         *                    -    Self/intersecting Bezier is NOT a reduction
         *                        from bezier
         */
    
        public static bool AuxIntersectBL(DegenD degen, LCurve lrs, ListInfoInters linters)
        {
            //    IMPORTANT (TODO): 
            //    such intersection is NOT VALID for computation of ray's parity
            if (linters==null)
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBL(degen,lrs)","Null argument");
            }
            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBL(degen,lrs)",null);
            }
            if (lrs is SegD)
            {
                return Inters.AuxIntersectBB(degen, lrs as SegD, null, null, linters);
            }

            LineD line=new LineD(lrs);
            Param param;
            VecD  pnt;
            if (!degen.Cp.Project(line,out param,out pnt))
                return false;
            if (degen.Cp.Dist(pnt)<MConsts.EPS_DEC) 
            {
                if (lrs.IsEvaluableStrict(param))
                {
                    IntersD0 inters=new IntersD0(Param.Degen, param, pnt, false);
                    linters.Add(inters);
                }
            }
            return true;
        }
Ejemplo n.º 29
0
 protected override void ClearFunc()
 {
     this.linters.ClearDestroy();
     this.linters=null;
 }
Ejemplo n.º 30
0
 internal StatusGV.TypeStatusExec ValidateCompComponentDupl(GErrList gerrlist)
 {
     ListPairInt pairsIndComponentDupl=new ListPairInt();
 
     if ((this.comp==null)||(this.outl==null))
     {
         //throw new ExceptionGlyph("Glyph","ValidateCompComponentDupl",null);
         return StatusGV.TypeStatusExec.Aborted;
     }
     int numComponent=this.comp.NumComponent;
     for (int pozComponentA=0; pozComponentA<numComponent-1; pozComponentA++)
     {
         Component componentA=this.comp.ComponentByPoz(pozComponentA);
         for (int pozComponentB=pozComponentA+1; pozComponentB<numComponent; pozComponentB++)
         {
             ListInfoInters linters=new ListInfoInters();
             Component componentB=this.comp.ComponentByPoz(pozComponentB);
             bool areDuplicated;
             this.outl.AreDuplicatedComponents(componentA,componentB,out areDuplicated);
             if (areDuplicated)
             {
                 pairsIndComponentDupl.Add(componentA.IndexGlyphComponent,
                     componentB.IndexGlyphComponent);
             }
         }
     }
     if (pairsIndComponentDupl.Count!=0)
     {
         GErr gerr=new GErrComponentDupl(this.index, pairsIndComponentDupl);
         gerrlist.Add(gerr);
     }
     return StatusGV.TypeStatusExec.Completed;
 }
Ejemplo n.º 31
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);
        }
Ejemplo n.º 32
0
        public bool IntersectComponents(Component componentA,
            Component componentB,
            ListInfoInters linters)
        {
            if ((componentA==null)||(componentB==null))
            {
                throw new ExceptionGMath("Outline","IntersectComponents",null);
                //return false;
            }

            if (componentA==componentB)
                return true;
            bool res=true;

            for (int pozContA=componentA.PozContStart; 
                pozContA<componentA.PozContStart+componentA.NumCont; 
                pozContA++)
            {
                Contour contA=this.ContourByPoz(pozContA);
                for (int pozContB=componentB.PozContStart; 
                    pozContB<componentB.PozContStart+componentB.NumCont; 
                    pozContB++)
                {
                    Contour contB=this.ContourByPoz(pozContB);
                    if (!contA.Intersect(contB, linters))
                        res=false;
                }
            }
            return res;
        }
Ejemplo n.º 33
0
        public static bool AuxIntersectBB(SegD segA, SegD segB,
            InfoConnect icAB, InfoConnect icBA, ListInfoInters linters)
        {
            bool connectAB = ((icAB!=null)&&(icAB.IsConnect));
            bool connectBA = ((icBA!=null)&&(icBA.IsConnect));            
            bool connect=connectAB||connectBA;
            

            InfoInters inters;
            if (!Inters.IntersectLL(segA,segB,out inters))
                return false;
            if (inters!=null)
            {
                if ((!connect)||
                    ((connect)&&(inters.Dim==InfoInters.TypeDim.Dim1)))
                {
                    linters.Add(inters);
                }
            }
            return true;
        }
Ejemplo n.º 34
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;            
 }
Ejemplo n.º 35
0
        public static bool AuxIntersectBL(SegD seg, LCurve lrs, ListInfoInters linters)
        {    
            // segment is irreducable !!!
            if (linters==null)
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBL(seg,lrs)","Null argument");
            }
            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("Intersect","AuxIntersectBL(seg,lrs)",null);
            }

            InfoInters inters;
            if (!Inters.IntersectLL(seg, lrs, out inters))
                return false;
            if (inters!=null)
                linters.Add(inters);
            return true;
        }
Ejemplo n.º 36
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;
 }
Ejemplo n.º 37
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);
        }