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; }
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; }
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); }