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