コード例 #1
0
ファイル: VecD.cs プロジェクト: sjvudp/Font-Validator
        bool InverseOn(LCurve lrs, out bool isOn, out Param par)
        {
            /*
             *        MEANING:    inverse point which is known to lie on the
             *                    lrs in range [-Infinity, Infinity]
             *
             *        ASSUMPTIONS:    lrs is non-degenerated
             *
             */

            isOn = false;
            par  = null;

            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("VecD", "InverseOn(lrs)", null);
                //return false;
            }
            this.Inverse(lrs, out par);
            if (this.Dist(lrs.Evaluate(par)) < MConsts.EPS_DEC)
            {
                isOn = true;
            }
            else
            {
                par = null;
            }
            return(true);
        }
コード例 #2
0
ファイル: Intersect.cs プロジェクト: sjvudp/Font-Validator
        /*
         *        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);
        }
コード例 #3
0
ファイル: VecD.cs プロジェクト: sjvudp/Font-Validator
 public bool Project(LCurve lcurve, out Param param, out VecD pnt)
 {
     /*
      *        MEANING:    the NEAREST point in the PARAMETRIC RANGE
      *                    of the curve
      *
      *        ASSUMPTIONS:    the curve may be not reduced
      */
     param = null;
     pnt   = null;
     if (lcurve.IsDegen)
     {
         SegD seg = lcurve as SegD;
         if (seg == null)
         {
             throw new ExceptionGMath("VecD", "Project", null);
             //return false;
         }
         param = new Param(Param.Degen);
         pnt   = seg.Middle;
         return(true);
     }
     this.Perp(lcurve, out param);
     param.Clip(lcurve.ParamStart, lcurve.ParamEnd);
     pnt = lcurve.Evaluate(param);
     return(true);
 }
コード例 #4
0
ファイル: Intersect.cs プロジェクト: sjvudp/Font-Validator
        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);
        }
コード例 #5
0
ファイル: VecD.cs プロジェクト: sjvudp/Font-Validator
 public bool Inverse(LCurve lrs, out Param par)
 {
     /*
      *        MEANING:
      *            -    Parameter of the nearest point in range
      *                [-Infinity, Infinity]
      *        ASSUMPTIONS:
      *            -    LRS is NON-DEGENERSTED
      */
     return(this.Perp(lrs, out par));
 }
コード例 #6
0
ファイル: VecD.cs プロジェクト: sjvudp/Font-Validator
        bool Perp(LCurve lrs, out Param param)
        {
            /*
             *        MEANING:    perpendicular to the parametric range
             *                    [-Infinity, Infinity]
             */
            param = null;

            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("VecD", "Perp", null);
                //return false;
            }
            VecD   start  = lrs.Start;
            VecD   end    = lrs.End;
            double length = (end - start).Norm;
            VecD   tang   = lrs.DirTang;

            param = new Param(((this - start).Dot(tang)) / ((end - start).Dot(tang)));
            return(true);
        }
コード例 #7
0
ファイル: Intersect.cs プロジェクト: sjvudp/Font-Validator
        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);
        }
コード例 #8
0
ファイル: Intersect.cs プロジェクト: sjvudp/Font-Validator
        public static bool RefineIntersLLD1(LCurve lrsA, LCurve lrsB,
                                            out InfoInters inters)
        {
            inters = null;
            if ((lrsA is SegD) && (lrsB is SegD))
            {
                BCurve curveA = lrsA as BCurve;
                BCurve curveB = lrsB as BCurve;
                return(Inters.RefineIntersBBD1(curveA, curveB, out inters));
            }
            if (lrsA.LComplexity > lrsB.LComplexity)
            {
                bool res = Inters.RefineIntersLLD1(lrsB, lrsA, out inters);
                if (inters != null)
                {
                    inters.ParamSwap();
                }
                return(res);
            }
            VecD a0 = lrsA.Start;
            VecD a1 = lrsA.End;
            VecD b0 = lrsB.Start;
            VecD b1 = lrsB.End;

            Param paramBInvA0, paramBInvA1;
            bool  isOn;

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

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

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

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

                        inters = new IntersD1(paramAInvB0, -Param.Infinity,
                                              paramAInvB1, Param.Infinity, lrsB, false);
                        return(true);
                    }
                    if (lrsB is RayD)
                    {
                        paramAInvB1 = (areCoDirected)? Param.Infinity: -Param.Infinity;
                        inters      = new IntersD1(paramAInvB0, 0,
                                                   paramAInvB1, Param.Infinity, lrsB, false);
                        return(true);
                    }
                    if (lrsB is SegD)
                    {
                        inters = new IntersD1(paramAInvB0, 0,
                                              paramAInvB1, 1, lrsB, false);
                        return(true);
                    }
                }
                if (lrsA is RayD)
                {
                    if (lrsB is RayD)
                    {
                        if (areCoDirected)
                        {
                            if (paramAInvB0 > 0)
                            {
                                inters = new IntersD1(paramAInvB0, 0,
                                                      Param.Infinity, Param.Infinity, lrsB, false);
                                return(true);
                            }
                            else
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      Param.Infinity, Param.Infinity, lrsA, false);
                                return(true);
                            }
                        }
                        else
                        {
                            if (paramAInvB0 > 0)
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      paramAInvB0, 0, new SegD(a0, b0), false);
                                return(true);
                            }
                        }
                    }
                    if (lrsB is SegD)
                    {
                        // intersection is known to have dimension D1 !!!
                        if ((paramBInvA0 >= 1) || (paramBInvA0 <= 0))
                        {
                            inters = new IntersD1(paramAInvB0, 0,
                                                  paramAInvB1, 1, new SegD(b0, b1), false);
                            return(true);
                        }
                        if ((0 < paramBInvA0) && (paramBInvA1 < 1))
                        {
                            if (areCoDirected)
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      paramAInvB1, 1, new SegD(a0, b1), false);
                                return(true);
                            }
                            else
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      paramAInvB0, 0, new SegD(a0, b0), false);
                                return(true);
                            }
                        }
                    }
                }
            }
            throw new ExceptionGMath("Intersect", "RefineIntersLLD1", null);
            //return false;
        }
コード例 #9
0
ファイル: LineD.cs プロジェクト: sjvudp/Font-Validator
 public LineD(LCurve lcurve) : this()
 {
     this.cp[0] = new VecD(lcurve.Start);
     this.cp[1] = new VecD(lcurve.End);
 }
コード例 #10
0
ファイル: VecD.cs プロジェクト: bitforks/Font-Validator
 public bool Inverse(LCurve lrs, out Param par)
 {
     /*
      *        MEANING:
      *            -    Parameter of the nearest point in range 
      *                [-Infinity, Infinity]
      *        ASSUMPTIONS:
      *            -    LRS is NON-DEGENERSTED
      */
     return (this.Perp(lrs,out par));
 }
コード例 #11
0
ファイル: VecD.cs プロジェクト: bitforks/Font-Validator
        bool InverseOn(LCurve lrs, out bool isOn, out Param par)
        {
            /*
             *        MEANING:    inverse point which is known to lie on the
             *                    lrs in range [-Infinity, Infinity]
             * 
             *        ASSUMPTIONS:    lrs is non-degenerated 
             * 
             */    
        
            isOn=false;
            par=null;

            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("VecD","InverseOn(lrs)",null);
                //return false;
            }
            this.Inverse(lrs, out par);
            if (this.Dist(lrs.Evaluate(par))<MConsts.EPS_DEC)
            {
                isOn=true;
            }
            else
            {
                par=null;
            }
            return true;
        }
コード例 #12
0
ファイル: VecD.cs プロジェクト: bitforks/Font-Validator
 public bool Project(LCurve lcurve, out Param param, out VecD pnt)
 {
     /*
      *        MEANING:    the NEAREST point in the PARAMETRIC RANGE
      *                    of the curve
      * 
      *        ASSUMPTIONS:    the curve may be not reduced
      */
     param=null;
     pnt=null;
     if (lcurve.IsDegen)
     {
         SegD seg=lcurve as SegD;
         if (seg==null)
         {
             throw new ExceptionGMath("VecD","Project",null);
             //return false;
         }
         param=new Param(Param.Degen);
         pnt=seg.Middle;
         return true;
     }
     this.Perp(lcurve, out param);
     param.Clip(lcurve.ParamStart,lcurve.ParamEnd);
     pnt=lcurve.Evaluate(param);
     return true;
 }
コード例 #13
0
ファイル: Intersect.cs プロジェクト: bitforks/Font-Validator
        /*
         *        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;
        }
コード例 #14
0
ファイル: LineD.cs プロジェクト: bitforks/Font-Validator
 public LineD(LCurve lcurve) : this()
 {
     this.cp[0]=new VecD(lcurve.Start);
     this.cp[1]=new VecD(lcurve.End);
 }
コード例 #15
0
ファイル: Intersect.cs プロジェクト: bitforks/Font-Validator
        /*
         *        INTERSECT: (LCurve, LCurve)
         *                - both curves are supposed to be NON-DEGENERATED
         */
        
        public static bool IntersectLL(LCurve lrsA, LCurve lrsB,
            out InfoInters inters)
        {
            inters=null;
            if ((lrsA.IsDegen)||(lrsB.IsDegen))
            {
                throw new ExceptionGMath("Intersect","IntersectLL(lrs,lrs)",null);
            }

            VecD a0=lrsA.Start;
            VecD a1=lrsA.End;
            VecD b0=lrsB.Start;
            VecD b1=lrsB.End;
            VecD dirA=lrsA.DirTang;
            VecD dirB=lrsB.DirTang;
            double det = dirA.Cross(dirB);

            // lrsA and lrsB are not parallel
            if (Math.Abs(det)>MConsts.EPS_DEC) 
            {
                double lenA = (a1-a0).Norm;
                double lenB = (b1-b0).Norm;
                VecD diff = b0-a0;
                Param parA = (diff.Cross(dirB))/(det*lenA);
                Param parB = (diff.Cross(dirA))/(det*lenB);
                if (lrsA.IsEvaluableStrict(parA)&&lrsB.IsEvaluableStrict(parB))
                {
                    VecD pnt = 0.5*(lrsA.Evaluate(parA)+lrsB.Evaluate(parB));
                    inters=new IntersD0(parA,parB,pnt,false);
                }
                return true;
            }

            // lrsA and lrsB are parallel
            LineD lineB=new LineD(lrsB);
            Param paramBInvA0, paramBInvA1;
            VecD pntProjA0, pntProjA1;
            a0.Project(lineB, out paramBInvA0, out pntProjA0);
            a1.Project(lineB, out paramBInvA1, out pntProjA1);
            double distA0=a0.Dist(pntProjA0);
            double distA1=a1.Dist(pntProjA1);

            if ((distA0<MConsts.EPS_DEC)||(distA1<MConsts.EPS_DEC))
            {
                // lrsA and lrsB are colinear
                Param.TypeParam typeA0=lrsB.ParamClassify(paramBInvA0);
                Param.TypeParam typeA1=lrsB.ParamClassify(paramBInvA1);
                int mult=(int)typeA0*(int)typeA1;

                if (mult==4)
                {
                    return true;
                }
                else if (mult==1) 
                {
                    throw new ExceptionGMath("Intersect","IntersectLL(lrs,lrs)",null); // lrsA is degenerated
                    //return false;
                }
                else if (mult==2)
                {
                    if ((typeA0==Param.TypeParam.Start)&&
                        (typeA1==Param.TypeParam.Before))
                    {
                        inters=new IntersD0(0,0,a0,false);
                    }
                    if ((typeA0==Param.TypeParam.Before)&&
                        (typeA1==Param.TypeParam.Start)) 
                    {
                        inters=new IntersD0(1,0,a1,false);
                    }
                    if ((typeA0==Param.TypeParam.End)&&
                        (typeA1==Param.TypeParam.After)) 
                    {
                        inters=new IntersD0(0,1,a0,false);
                    }
                    if ((typeA0==Param.TypeParam.After)&&
                        (typeA1==Param.TypeParam.End))
                    {
                        inters=new IntersD0(1,1,a1,false);
                    }
                    return true;
                }
                else if (mult<=0)
                {
                    return (Inters.RefineIntersLLD1(lrsA,lrsB,out inters));
                }
            }
            
            return true;
        }
コード例 #16
0
ファイル: Intersect.cs プロジェクト: bitforks/Font-Validator
        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;
        }
コード例 #17
0
ファイル: Intersect.cs プロジェクト: bitforks/Font-Validator
        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;
        }
コード例 #18
0
ファイル: Intersect.cs プロジェクト: bitforks/Font-Validator
        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;
        }
コード例 #19
0
ファイル: Intersect.cs プロジェクト: sjvudp/Font-Validator
        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);
        }
コード例 #20
0
ファイル: VecD.cs プロジェクト: bitforks/Font-Validator
        bool Perp(LCurve lrs, out Param param)
        {
            /*
             *        MEANING:    perpendicular to the parametric range
             *                    [-Infinity, Infinity]
             */
            param=null;

            if (lrs.IsDegen)
            {
                throw new ExceptionGMath("VecD","Perp",null);
                //return false;
            }
            VecD start=lrs.Start;
            VecD end=lrs.End;
            double length=(end-start).Norm;
            VecD tang=lrs.DirTang;
    
            param = new Param(((this-start).Dot(tang))/((end-start).Dot(tang)));
            return true;        
        }
コード例 #21
0
ファイル: Intersect.cs プロジェクト: sjvudp/Font-Validator
        /*
         *        INTERSECT: (LCurve, LCurve)
         *                - both curves are supposed to be NON-DEGENERATED
         */

        public static bool IntersectLL(LCurve lrsA, LCurve lrsB,
                                       out InfoInters inters)
        {
            inters = null;
            if ((lrsA.IsDegen) || (lrsB.IsDegen))
            {
                throw new ExceptionGMath("Intersect", "IntersectLL(lrs,lrs)", null);
            }

            VecD   a0   = lrsA.Start;
            VecD   a1   = lrsA.End;
            VecD   b0   = lrsB.Start;
            VecD   b1   = lrsB.End;
            VecD   dirA = lrsA.DirTang;
            VecD   dirB = lrsB.DirTang;
            double det  = dirA.Cross(dirB);

            // lrsA and lrsB are not parallel
            if (Math.Abs(det) > MConsts.EPS_DEC)
            {
                double lenA = (a1 - a0).Norm;
                double lenB = (b1 - b0).Norm;
                VecD   diff = b0 - a0;
                Param  parA = (diff.Cross(dirB)) / (det * lenA);
                Param  parB = (diff.Cross(dirA)) / (det * lenB);
                if (lrsA.IsEvaluableStrict(parA) && lrsB.IsEvaluableStrict(parB))
                {
                    VecD pnt = 0.5 * (lrsA.Evaluate(parA) + lrsB.Evaluate(parB));
                    inters = new IntersD0(parA, parB, pnt, false);
                }
                return(true);
            }

            // lrsA and lrsB are parallel
            LineD lineB = new LineD(lrsB);
            Param paramBInvA0, paramBInvA1;
            VecD  pntProjA0, pntProjA1;

            a0.Project(lineB, out paramBInvA0, out pntProjA0);
            a1.Project(lineB, out paramBInvA1, out pntProjA1);
            double distA0 = a0.Dist(pntProjA0);
            double distA1 = a1.Dist(pntProjA1);

            if ((distA0 < MConsts.EPS_DEC) || (distA1 < MConsts.EPS_DEC))
            {
                // lrsA and lrsB are colinear
                Param.TypeParam typeA0 = lrsB.ParamClassify(paramBInvA0);
                Param.TypeParam typeA1 = lrsB.ParamClassify(paramBInvA1);
                int             mult   = (int)typeA0 * (int)typeA1;

                if (mult == 4)
                {
                    return(true);
                }
                else if (mult == 1)
                {
                    throw new ExceptionGMath("Intersect", "IntersectLL(lrs,lrs)", null); // lrsA is degenerated
                    //return false;
                }
                else if (mult == 2)
                {
                    if ((typeA0 == Param.TypeParam.Start) &&
                        (typeA1 == Param.TypeParam.Before))
                    {
                        inters = new IntersD0(0, 0, a0, false);
                    }
                    if ((typeA0 == Param.TypeParam.Before) &&
                        (typeA1 == Param.TypeParam.Start))
                    {
                        inters = new IntersD0(1, 0, a1, false);
                    }
                    if ((typeA0 == Param.TypeParam.End) &&
                        (typeA1 == Param.TypeParam.After))
                    {
                        inters = new IntersD0(0, 1, a0, false);
                    }
                    if ((typeA0 == Param.TypeParam.After) &&
                        (typeA1 == Param.TypeParam.End))
                    {
                        inters = new IntersD0(1, 1, a1, false);
                    }
                    return(true);
                }
                else if (mult <= 0)
                {
                    return(Inters.RefineIntersLLD1(lrsA, lrsB, out inters));
                }
            }

            return(true);
        }
コード例 #22
0
ファイル: Intersect.cs プロジェクト: bitforks/Font-Validator
        public static bool RefineIntersLLD1(LCurve lrsA, LCurve lrsB,
            out InfoInters inters)
        {
            inters=null;
            if ((lrsA is SegD) && (lrsB is SegD))
            {
                BCurve curveA=lrsA as BCurve;
                BCurve curveB=lrsB as BCurve;
                return Inters.RefineIntersBBD1(curveA, curveB, out inters);
            }
            if (lrsA.LComplexity>lrsB.LComplexity)
            {
                bool res=Inters.RefineIntersLLD1(lrsB,lrsA,out inters);
                if (inters!=null)
                {
                    inters.ParamSwap();
                }
                return res;
            }
            VecD a0=lrsA.Start;
            VecD a1=lrsA.End;
            VecD b0=lrsB.Start;
            VecD b1=lrsB.End;

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

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