/* * 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 RefineIntersLLD1(LCurve lrsA, LCurve lrsB, out InfoInters inters) { inters = null; if ((lrsA is SegD) && (lrsB is SegD)) { BCurve curveA = lrsA as BCurve; BCurve curveB = lrsB as BCurve; return(Inters.RefineIntersBBD1(curveA, curveB, out inters)); } if (lrsA.LComplexity > lrsB.LComplexity) { bool res = Inters.RefineIntersLLD1(lrsB, lrsA, out inters); if (inters != null) { inters.ParamSwap(); } return(res); } VecD a0 = lrsA.Start; VecD a1 = lrsA.End; VecD b0 = lrsB.Start; VecD b1 = lrsB.End; Param paramBInvA0, paramBInvA1; bool isOn; if ((!a0.InverseOn(lrsB, out isOn, out paramBInvA0)) || (!isOn)) { return(false); } if ((!a1.InverseOn(lrsB, out isOn, out paramBInvA1)) || (!isOn)) { return(false); } Param paramAInvB0, paramAInvB1; if ((!b0.InverseOn(lrsA, out isOn, out paramAInvB0)) || (!isOn)) { return(false); } if ((!b1.InverseOn(lrsA, out isOn, out paramAInvB1)) || (!isOn)) { return(false); } bool areCoDirected = (paramBInvA1.Val >= paramBInvA0.Val); if (!areCoDirected) { if (lrsA is LineD) { if (lrsB is LineD) { paramAInvB0 = (areCoDirected)? -Param.Infinity: Param.Infinity; paramAInvB1 = (areCoDirected)? Param.Infinity: -Param.Infinity; inters = new IntersD1(paramAInvB0, -Param.Infinity, paramAInvB1, Param.Infinity, lrsB, false); return(true); } if (lrsB is RayD) { paramAInvB1 = (areCoDirected)? Param.Infinity: -Param.Infinity; inters = new IntersD1(paramAInvB0, 0, paramAInvB1, Param.Infinity, lrsB, false); return(true); } if (lrsB is SegD) { inters = new IntersD1(paramAInvB0, 0, paramAInvB1, 1, lrsB, false); return(true); } } if (lrsA is RayD) { if (lrsB is RayD) { if (areCoDirected) { if (paramAInvB0 > 0) { inters = new IntersD1(paramAInvB0, 0, Param.Infinity, Param.Infinity, lrsB, false); return(true); } else { inters = new IntersD1(0, paramBInvA0, Param.Infinity, Param.Infinity, lrsA, false); return(true); } } else { if (paramAInvB0 > 0) { inters = new IntersD1(0, paramBInvA0, paramAInvB0, 0, new SegD(a0, b0), false); return(true); } } } if (lrsB is SegD) { // intersection is known to have dimension D1 !!! if ((paramBInvA0 >= 1) || (paramBInvA0 <= 0)) { inters = new IntersD1(paramAInvB0, 0, paramAInvB1, 1, new SegD(b0, b1), false); return(true); } if ((0 < paramBInvA0) && (paramBInvA1 < 1)) { if (areCoDirected) { inters = new IntersD1(0, paramBInvA0, paramAInvB1, 1, new SegD(a0, b1), false); return(true); } else { inters = new IntersD1(0, paramBInvA0, paramAInvB0, 0, new SegD(a0, b0), false); return(true); } } } } } throw new ExceptionGMath("Intersect", "RefineIntersLLD1", null); //return false; }