예제 #1
0
        public bool ProjectGeneral(Bez2D bez, out Param[] pars, out VecD pnt)
        {
            /*
             *        MEANING:    parameter (or parameters) of the nearest point
             *                    in range [0,1]
             * 
             *        ASSUMPTIONS:    bezier can be non-reduced
             *                        bezier can be self-intersecting
             * 
             */


            pars=null;
            pnt=null;
            Param parM;
            if (!bez.IsSelfInters(out parM))
            {
                Param par;
                if (!this.Project(bez,out par,out  pnt))
                    return false;
                if (par!=null)
                {
                    pars=new Param[1];
                    pars[0]=par;
                }
                return true;
            }

            double valM=parM.Val;
            if (parM<0)
            {
                Bez2D bezRev=new Bez2D(bez);
                bezRev.Reverse();
                if (!this.ProjectGeneral(bezRev,out pars,out pnt))
                    return false;
                if (pars!=null)
                {
                    for (int iPar=0; iPar<pars.Length; iPar++)
                    {
                        pars[iPar].Reverse(1);
                    }
                }
                return true;
            }
            SegD support=bez.SupportFlat();
            Param parSupport;
            if (!this.Project(support,out parSupport, out pnt))
                return false;
            if (!bez.ParamFromSupport(parSupport,out pars))
                return false;
            return true;
        }
예제 #2
0
        public bool ParamFromSupport(Param parSupport, out Param[] parsBez)
        {
            parsBez = null;
            parSupport.Round(0, 1);
            if ((parSupport.Val < 0) || (parSupport.Val > 1))
            {
                throw new ExceptionGMath("Bez2D", "ParamFromSupport", "Outside [0,1]");
                //return false;
            }

            Param parM;

            if (!this.IsSelfInters(out parM))
            {
                parsBez    = new Param[1];
                parsBez[0] = parSupport.Copy();
                this.ParamFromSeg(parsBez[0]);
                return(true);
            }

            // self-intersecting Bezier
            double valM = parM.Val;

            if (valM == Param.Infinity)
            {
                double tau = 0.5 * parSupport.Val; // parameter with respect to [Cp(0),Cp(1)]
                parsBez    = new Param[2];
                parsBez[0] = new Param(0.5 * (1 - Math.Sqrt(1 - 2 * tau)));
                parsBez[1] = new Param(0.5 * (1 + Math.Sqrt(1 - 2 * tau)));
                return(true);
            }
            else if (valM > 1)
            {
                double tau = ((valM * valM) / (1 - 2 * valM)) * parSupport.Val;
                double D   = valM * valM + tau * (1 - 2 * valM);
                if (Math.Abs(D) < MConsts.EPS_DEC)
                {
                    D = 0;
                }
                if (D < 0)
                {
                    throw new ExceptionGMath("BezD", "ParamFromSegGeneral", null);
                    //return false;
                }
                if (tau < 1)
                {
                    parsBez    = new Param[1];
                    parsBez[0] = new Param((valM - Math.Sqrt(D)) / (1 - 2 * valM));
                }
                else // 1<=tau<=(valM*valM)/(1-2*valM)
                {
                    parsBez    = new Param[2];
                    parsBez[0] = new Param((valM - Math.Sqrt(D)) / (1 - 2 * valM));
                    parsBez[1] = new Param((valM + Math.Sqrt(D)) / (1 - 2 * valM));
                }
                return(true);
            }
            else
            {
                // valM<=1
                Bez2D bezRev = this.Reversed as Bez2D;
                if (!bezRev.ParamFromSupport(1 - parSupport.Val, out parsBez))
                {
                    return(false);
                }
                if (parsBez == null)
                {
                    return(true);
                }
                for (int iParBez = 0; iParBez < parsBez.Length; iParBez++)
                {
                    parsBez[iParBez].Reverse(1);
                }
                return(true);
            }
            throw new ExceptionGMath("Bez2D", "ParamFromSupport", "NOT IMPLEMENTED");
            //return false;
        }
예제 #3
0
        public bool ProjectGeneral(Bez2D bez, out Param[] pars, out VecD pnt)
        {
            /*
             *        MEANING:    parameter (or parameters) of the nearest point
             *                    in range [0,1]
             *
             *        ASSUMPTIONS:    bezier can be non-reduced
             *                        bezier can be self-intersecting
             *
             */


            pars = null;
            pnt  = null;
            Param parM;

            if (!bez.IsSelfInters(out parM))
            {
                Param par;
                if (!this.Project(bez, out par, out pnt))
                {
                    return(false);
                }
                if (par != null)
                {
                    pars    = new Param[1];
                    pars[0] = par;
                }
                return(true);
            }

            double valM = parM.Val;

            if (parM < 0)
            {
                Bez2D bezRev = new Bez2D(bez);
                bezRev.Reverse();
                if (!this.ProjectGeneral(bezRev, out pars, out pnt))
                {
                    return(false);
                }
                if (pars != null)
                {
                    for (int iPar = 0; iPar < pars.Length; iPar++)
                    {
                        pars[iPar].Reverse(1);
                    }
                }
                return(true);
            }
            SegD  support = bez.SupportFlat();
            Param parSupport;

            if (!this.Project(support, out parSupport, out pnt))
            {
                return(false);
            }
            if (!bez.ParamFromSupport(parSupport, out pars))
            {
                return(false);
            }
            return(true);
        }