/* * 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); }
/* * 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 static bool AuxIntersectBB(SegD seg, Bez2D bez, InfoConnect icAB, InfoConnect icBA, ListInfoInters linters) { // both seg & bez are irreducable !!! if (linters == null) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(seg,bez)", "Null argument"); } bool connectAB = ((icAB != null) && (icAB.IsConnect)); bool connectBA = ((icBA != null) && (icBA.IsConnect)); if ((connectBA) && (!connectAB)) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(seg,bez)", null); //return false; } bool connect = connectAB || connectBA; if (!connect) { int numIntersBefore = linters.Count; if (!Inters.AuxIntersectBL(bez, seg, linters)) { return(false); } linters.ParamSwap(numIntersBefore); return(true); } // bez and seg are connected, => connectAB=true Param parM; if (bez.IsSelfInters(out parM)) { if (connectBA) // both ends are connected { // parM!=Infinity - otherwise the seg is degenerated double valM = parM.Val; IntersD1 inters; if (valM > 1) { inters = new IntersD1(0, 1, 1, 1 / (2 * valM - 1), seg, true); } else { inters = new IntersD1(0, 1, 1, (2 * valM) / (2 * valM - 1), seg, true); } linters.Add(inters); return(true); } if (icAB.IsTangent) { return(true); // no additional intersections } else { SegD segSupp = bez.SupportFlat(); InfoInters inters; if (!Inters.IntersectLL(seg, segSupp, out inters)) { return(false); } if (inters == null) { return(true); } inters.ParamInvalidateBezSI(); int numIntersBefore = linters.Count; linters.Add(inters); /* * CLEAN END-POINT if the Bezier does not return to it */ bool coversBezStart = bez.CoversEndPoint(true); if (!coversBezStart) { linters.CleanEndPointBezSI(bez.Start, numIntersBefore); } return(true); } } // bezier is NOT self-intersecting if (connectBA) { return(true); // no additional intersections } if (icAB.IsTangent) { return(true); // no additional intersections } // seg & bez are connected and not-tangent,=> // at most one additional point of intersection VecD[] cfSeg, cfBez; seg.PowerCoeff(out cfSeg); bez.PowerCoeff(out cfBez); VecD tang = (seg as LCurve).DirTang; VecD norm = (seg as LCurve).DirNorm; // connected but not-tangent: one double[] rootsBez; int numRootBez; Equation.RootsReal(cfBez[2].Dot(norm), cfBez[1].Dot(norm), out numRootBez, out rootsBez); if (numRootBez == Equation.NumRootInfinite) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(seg,bez)", null); //return false; } if (rootsBez == null) { return(true); } Param parBez = rootsBez[0]; if (bez.IsEvaluableStrict(parBez)) { double valBez = parBez.Val; Param parSeg = 1 + valBez * (cfBez[2].Dot(tang) * valBez + cfBez[1].Dot(tang)) / cfSeg[1].Dot(tang); if (seg.IsEvaluableStrict(parSeg)) // ??? && (parSeg!=1) { IntersD0 inters = new IntersD0(parSeg, parBez, 0.5 * (seg.Evaluate(parSeg) + bez.Evaluate(parBez)), false); linters.Add(inters); } } return(true); }
public static bool AuxIntersectBB(SegD seg, Bez2D bez, InfoConnect icAB, InfoConnect icBA, ListInfoInters linters) { // both seg & bez are irreducable !!! if (linters==null) { throw new ExceptionGMath("Intersect","AuxIntersectBB(seg,bez)","Null argument"); } bool connectAB = ((icAB!=null)&&(icAB.IsConnect)); bool connectBA = ((icBA!=null)&&(icBA.IsConnect)); if ((connectBA)&&(!connectAB)) { throw new ExceptionGMath("Intersect","AuxIntersectBB(seg,bez)",null); //return false; } bool connect=connectAB||connectBA; if (!connect) { int numIntersBefore=linters.Count; if (!Inters.AuxIntersectBL(bez,seg,linters)) return false; linters.ParamSwap(numIntersBefore); return true; } // bez and seg are connected, => connectAB=true Param parM; if (bez.IsSelfInters(out parM)) { if (connectBA) // both ends are connected { // parM!=Infinity - otherwise the seg is degenerated double valM=parM.Val; IntersD1 inters; if (valM>1) { inters=new IntersD1(0,1, 1,1/(2*valM-1),seg,true); } else { inters=new IntersD1(0,1, 1,(2*valM)/(2*valM-1),seg,true); } linters.Add(inters); return true; } if (icAB.IsTangent) { return true; // no additional intersections } else { SegD segSupp=bez.SupportFlat(); InfoInters inters; if (!Inters.IntersectLL(seg,segSupp,out inters)) return false; if (inters==null) return true; inters.ParamInvalidateBezSI(); int numIntersBefore=linters.Count; linters.Add(inters); /* * CLEAN END-POINT if the Bezier does not return to it */ bool coversBezStart=bez.CoversEndPoint(true); if (!coversBezStart) { linters.CleanEndPointBezSI(bez.Start,numIntersBefore); } return true; } } // bezier is NOT self-intersecting if (connectBA) return true; // no additional intersections if (icAB.IsTangent) return true; // no additional intersections // seg & bez are connected and not-tangent,=> // at most one additional point of intersection VecD[] cfSeg, cfBez; seg.PowerCoeff(out cfSeg); bez.PowerCoeff(out cfBez); VecD tang=(seg as LCurve).DirTang; VecD norm=(seg as LCurve).DirNorm; // connected but not-tangent: one double[] rootsBez; int numRootBez; Equation.RootsReal(cfBez[2].Dot(norm),cfBez[1].Dot(norm), out numRootBez, out rootsBez); if (numRootBez==Equation.NumRootInfinite) { throw new ExceptionGMath("Intersect","AuxIntersectBB(seg,bez)",null); //return false; } if (rootsBez==null) return true; Param parBez=rootsBez[0]; if (bez.IsEvaluableStrict(parBez)) { double valBez=parBez.Val; Param parSeg=1+valBez*(cfBez[2].Dot(tang)*valBez+cfBez[1].Dot(tang))/cfSeg[1].Dot(tang); if (seg.IsEvaluableStrict(parSeg)) // ??? && (parSeg!=1) { IntersD0 inters=new IntersD0(parSeg,parBez, 0.5*(seg.Evaluate(parSeg)+bez.Evaluate(parBez)),false); linters.Add(inters); } } return true; }