/* * METHODS */ public bool IsSeg(out Param parM) { /* * MEANING: NON_DEGENERATED, PARAMETRIC segment * (implies, that the Bezier is not * self-intersecting) */ parM=null; if (this.IsDegen) return false; if (this.cp[0]==this.cp[2]) return false; // S/I bezier if (this.cp[0]==this.cp[1]) { parM=new Param(0); return true; } if (this.cp[1]==this.cp[2]) { parM=new Param(1); return true; } SegD seg=new SegD(this.cp[0], this.cp[2]); LineD line=new LineD(seg); VecD pnt; Param par; this.cp[1].Project(line,out par,out pnt); if (this.cp[1].Dist(pnt)>MConsts.EPS_DEC) return false; if (!seg.IsEvaluableStrict(par)) return false; parM=par; if (Math.Abs(parM.Val-0.5)<MConsts.EPS_DEC) { parM.Val=0.5; } return true; }
public bool IsSelfInters(out Param parM) { /* * RETURN VALUE: true if Self-Intersecting; false otherwise */ parM=null; if (this.IsDegen) return false; Param parSeg; if (this.IsSeg(out parSeg)) return false; SegD seg=new SegD(this.cp[0], this.cp[2]); if (seg.IsDegen) { parM=Param.Infinity; return true; } LineD line=new LineD(seg); VecD pnt; this.cp[1].Project(line,out parM,out pnt); if (this.cp[1].Dist(pnt)>MConsts.EPS_DEC) return false; 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; }
/* * 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); }
/* * 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; }