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