public bool Project(Bez2D bez, out Param par, out VecD pnt) { /* * MEANING: the NEAREST point in the RANGE [0,1] * ASSUMPTION: - bezier can be non-reduced * - bezier is NOT self-intersecting */ par = null; pnt = null; Param parM; if (bez.IsSelfInters(out parM)) { throw new ExceptionGMath("VecD", "Project(bez)", null); //return false; } if (bez.IsDegen) { par = new Param(Param.Degen); pnt = bez.Middle; return(true); } if (bez.IsSeg(out parM)) { SegD seg = bez.Reduced as SegD; this.Project(seg, out par, out pnt); bez.ParamFromSeg(par); return(true); } // case of non-flat Bezier Param[] parsPerp; if (!this.Perp(bez, out parsPerp)) { return(false); } double distS = this.Dist(bez.Start); double distE = this.Dist(bez.End); double distMin = Math.Min(distS, distE); double parMin = (distS <= distE)? 0.0: 1.0; if (parsPerp != null) { for (int iPerp = 0; iPerp < parsPerp.Length; iPerp++) { if (bez.IsEvaluableStrict(parsPerp[iPerp])) { double distPerp = this.Dist(bez.Evaluate(parsPerp[iPerp])); if (distPerp < distMin) { distMin = distPerp; parMin = parsPerp[iPerp]; } } } } par = parMin; pnt = bez.Evaluate(parMin); return(true); }
public void FromReduced(BCurve bcurve) { // parameter of the (reduced)curve may be invalidated if // the curve intersects the self-intersecting Bezier if (this.val == Param.Invalid) { return; } if (bcurve.IsDegen) { return; } if (bcurve is Bez2D) { Bez2D bez = bcurve as Bez2D; Param parM; if (bez.IsSeg(out parM)) { bez.ParamFromSeg(this); } } }
bool InverseOn(Bez2D bez, out bool isOn, out Param par) { /* * MEANING: inverse point which is known to lie on the * bezier in range [-Infinity, Infinity] * * ASSUMPTIONS: bez is IRREDUCABLE && NOT S/I * */ isOn = false; par = null; Param parM; if ((bez.IsDegen) || (bez.IsSeg(out parM)) || (bez.IsSelfInters(out parM))) { throw new ExceptionGMath("VecD", "InverseOn(bez)", null); //return false; } VecD[] cfBez; bez.PowerCoeff(out cfBez); double dev = (cfBez[2].Cross(this - cfBez[0])) * (cfBez[2].Cross(this - cfBez[0])) - (cfBez[2].Cross(cfBez[1])) * ((this - cfBez[0]).Cross(cfBez[1])); if (Math.Abs(dev) < MConsts.EPS_DEC) { isOn = true; par = (cfBez[2].Cross(this - cfBez[0])) / (cfBez[2].Cross(cfBez[1])); } return(true); }
bool Perp(Bez2D bez, out Param[] pars) { /* * MEANING: perpendicular to the parametric range * [-Infinity, Infinity] for NON-DEGENERATED, * NON-FLAT bezier */ pars = null; Param parM; if (bez.IsDegen) { throw new ExceptionGMath("VecD", "Perp", null); //return false; } if (bez.IsSeg(out parM) || bez.IsSelfInters(out parM)) { throw new ExceptionGMath("VecD", "Perp", null); //return false; } VecD[] pcf; bez.PowerCoeff(out pcf); double a = 2 * (pcf[2].Dot(pcf[2])); double b = 3 * (pcf[2].Dot(pcf[1])); double c = pcf[1].Dot(pcf[1]) + 2 * ((pcf[0] - (this)).Dot(pcf[2])); double d = (pcf[0] - (this)).Dot(pcf[1]); int numRootReal; double[] root; Equation.RootsReal(a, b, c, d, out numRootReal, out root); pars = new Param[root.Length]; for (int iRoot = 0; iRoot < root.Length; iRoot++) { pars[iRoot] = new Param(root[iRoot]); } return(true); }
bool InverseOn(Bez2D bez, out bool isOn, out Param par) { /* * MEANING: inverse point which is known to lie on the * bezier in range [-Infinity, Infinity] * * ASSUMPTIONS: bez is IRREDUCABLE && NOT S/I * */ isOn=false; par=null; Param parM; if ((bez.IsDegen)||(bez.IsSeg(out parM))||(bez.IsSelfInters(out parM))) { throw new ExceptionGMath("VecD","InverseOn(bez)",null); //return false; } VecD[] cfBez; bez.PowerCoeff(out cfBez); double dev=(cfBez[2].Cross(this-cfBez[0]))* (cfBez[2].Cross(this-cfBez[0]))- (cfBez[2].Cross(cfBez[1]))* ((this-cfBez[0]).Cross(cfBez[1])); if (Math.Abs(dev)<MConsts.EPS_DEC) { isOn=true; par=(cfBez[2].Cross(this-cfBez[0]))/(cfBez[2].Cross(cfBez[1])); } return true; }
public bool Project(Bez2D bez, out Param par, out VecD pnt) { /* * MEANING: the NEAREST point in the RANGE [0,1] * ASSUMPTION: - bezier can be non-reduced * - bezier is NOT self-intersecting */ par=null; pnt=null; Param parM; if (bez.IsSelfInters(out parM)) { throw new ExceptionGMath("VecD","Project(bez)",null); //return false; } if (bez.IsDegen) { par=new Param(Param.Degen); pnt=bez.Middle; return true; } if (bez.IsSeg(out parM)) { SegD seg=bez.Reduced as SegD; this.Project(seg,out par,out pnt); bez.ParamFromSeg(par); return true; } // case of non-flat Bezier Param[] parsPerp; if (!this.Perp(bez, out parsPerp)) return false; double distS=this.Dist(bez.Start); double distE=this.Dist(bez.End); double distMin=Math.Min(distS,distE); double parMin=(distS<=distE)? 0.0: 1.0; if (parsPerp!=null) { for (int iPerp=0; iPerp<parsPerp.Length; iPerp++) { if (bez.IsEvaluableStrict(parsPerp[iPerp])) { double distPerp=this.Dist(bez.Evaluate(parsPerp[iPerp])); if (distPerp<distMin) { distMin=distPerp; parMin=parsPerp[iPerp]; } } } } par=parMin; pnt=bez.Evaluate(parMin); return true; }
bool Perp(Bez2D bez, out Param[] pars) { /* * MEANING: perpendicular to the parametric range * [-Infinity, Infinity] for NON-DEGENERATED, * NON-FLAT bezier */ pars=null; Param parM; if (bez.IsDegen) { throw new ExceptionGMath("VecD","Perp",null); //return false; } if (bez.IsSeg(out parM)||bez.IsSelfInters(out parM)) { throw new ExceptionGMath("VecD","Perp",null); //return false; } VecD[] pcf; bez.PowerCoeff(out pcf); double a = 2*(pcf[2].Dot(pcf[2])); double b = 3*(pcf[2].Dot(pcf[1])); double c = pcf[1].Dot(pcf[1])+2*((pcf[0]-(this)).Dot(pcf[2])); double d = (pcf[0]-(this)).Dot(pcf[1]); int numRootReal; double[] root; Equation.RootsReal(a,b,c,d,out numRootReal,out root); pars=new Param[root.Length]; for (int iRoot=0; iRoot<root.Length; iRoot++) { pars[iRoot]=new Param(root[iRoot]); } return true; }