public static bool IntersectBB(BCurve curveA, BCurve curveB, InfoConnect icAB, InfoConnect icBA, ListInfoInters linters) { BoxD bboxA = curveA.BBox; BoxD bboxB = curveB.BBox; if (!bboxA.HasInters(bboxB)) { return(true); } int numIntersBefore = linters.Count; bool connectAB = (icAB != null) && (icAB.IsConnect); bool connectBA = (icBA != null) && (icBA.IsConnect); bool toReverseByConnection = (connectBA) && (!connectAB); if (toReverseByConnection) { if (!Inters.IntersectBB(curveB, curveA, icBA, icAB, linters)) { return(false); } linters.ParamSwap(numIntersBefore); return(false); } BCurve redA = curveA.Reduced; BCurve redB = curveB.Reduced; bool toReverseByComplexity = (redA.BComplexity > redB.BComplexity); object[] pars = { redA, redB, icAB, icBA, linters }; if (toReverseByComplexity) { // TODO: check !!! // TODO: what happens with connection info ??? pars[0] = redB.Reversed; pars[1] = redA.Reversed; } Type[] types = { pars[0].GetType(), pars[1].GetType(), typeof(InfoConnect), typeof(InfoConnect), typeof(ListInfoInters) }; MethodInfo infoMethod = typeof(Inters).GetMethod("AuxIntersectBB", types); bool res; try { res = (bool)infoMethod.Invoke(null, pars); } catch (System.Reflection.TargetInvocationException TIException) { throw TIException.InnerException; } if (toReverseByComplexity) { linters.ParamReverse(1, 0, numIntersBefore); linters.ParamReverse(1, 1, numIntersBefore); linters.ParamSwap(numIntersBefore); } if ((object)redA != (object)curveA) { linters.ParamFromReduced(curveA, 0, numIntersBefore); } if ((object)redB != (object)curveB) { linters.ParamFromReduced(curveB, 1, numIntersBefore); } // clean-up end-point intersections linters.CleanEndPointInters(connectAB, connectBA, numIntersBefore); return(res); }
public static bool IntersectBB(BCurve curveA, BCurve curveB, InfoConnect icAB, InfoConnect icBA, ListInfoInters linters) { BoxD bboxA=curveA.BBox; BoxD bboxB=curveB.BBox; if (!bboxA.HasInters(bboxB)) return true; int numIntersBefore=linters.Count; bool connectAB=(icAB!=null)&&(icAB.IsConnect); bool connectBA=(icBA!=null)&&(icBA.IsConnect); bool toReverseByConnection=(connectBA)&&(!connectAB); if (toReverseByConnection) { if (!Inters.IntersectBB(curveB,curveA,icBA,icAB,linters)) return false; linters.ParamSwap(numIntersBefore); return false; } BCurve redA = curveA.Reduced; BCurve redB = curveB.Reduced; bool toReverseByComplexity=(redA.BComplexity>redB.BComplexity); object[] pars={redA,redB,icAB,icBA,linters}; if (toReverseByComplexity) { // TODO: check !!! // TODO: what happens with connection info ??? pars[0]=redB.Reversed; pars[1]=redA.Reversed; } Type[] types={pars[0].GetType(),pars[1].GetType(), typeof(InfoConnect),typeof(InfoConnect),typeof(ListInfoInters)}; MethodInfo infoMethod=typeof(Inters).GetMethod("AuxIntersectBB",types); bool res; try { res=(bool)infoMethod.Invoke(null,pars); } catch(System.Reflection.TargetInvocationException TIException) { throw TIException.InnerException; } if (toReverseByComplexity) { linters.ParamReverse(1,0,numIntersBefore); linters.ParamReverse(1,1,numIntersBefore); linters.ParamSwap(numIntersBefore); } if ((object)redA!=(object)curveA) { linters.ParamFromReduced(curveA,0,numIntersBefore); } if ((object)redB!=(object)curveB) { linters.ParamFromReduced(curveB,1,numIntersBefore); } // clean-up end-point intersections linters.CleanEndPointInters(connectAB,connectBA,numIntersBefore); return res; }
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; }