/* * 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 bool RayParity(RayD ray, CParam parStartRay, out MConsts.TypeParity typeParity) { /* * ASSUMPTIONS * INPUT: * - (parStartRay==null) is the ray does not start at * the contour * RETURN VALUE; * - (false) in case of real failure; * (true)+(typeParity==Undef) in unclear cases * */ typeParity = MConsts.TypeParity.Undef; ListInfoInters linters = new ListInfoInters(); bool isStartIntersFound = false; for (int pozKnot = 0; pozKnot < this.NumKnot; pozKnot++) { BCurve curve = this.CurveByPoz(pozKnot); if (curve != null) { Knot knot = this.KnotByPoz(pozKnot); int numIntersBefore = linters.Count; if (!Inters.IntersectBL(curve, ray, linters)) { linters.ClearDestroy(); return(false); } int numIntersAfter = linters.Count; if (numIntersAfter != numIntersBefore) { InfoInters inters; if ((curve.IsDegen) || (curve.IsSelfInters(out inters))) { linters.ClearDestroy(); return(true); } } bool isRayStartOnCurve = ((parStartRay != null) && (parStartRay.IndKnot == knot.IndexKnot)); for (int iInters = numIntersBefore; iInters < numIntersAfter; iInters++) { InfoInters inters = linters[iInters] as InfoInters; if (inters.Dim == InfoInters.TypeDim.Dim1) { linters.ClearDestroy(); return(true); } IntersD0 intersD0 = inters as IntersD0; double parValCurve = intersD0.Ipi.Par(0).Val; double parValRay = intersD0.Ipi.Par(1).Val; if (Math.Abs(parValRay) < MConsts.EPS_DEC) { if ((!isRayStartOnCurve) || (isRayStartOnCurve && isStartIntersFound)) { linters.ClearDestroy(); return(true); } isStartIntersFound = true; } if ((Math.Abs(parValCurve) < MConsts.EPS_DEC_WEAK) || (Math.Abs(1.0 - parValCurve) < MConsts.EPS_DEC_WEAK)) { linters.ClearDestroy(); return(true); } VecD dirTangCurve = curve.DirTang(parValCurve); VecD dirTangRay = (ray as LCurve).DirTang; if ((dirTangCurve == null) || (dirTangRay == null)) { linters.ClearDestroy(); return(true); } if (Math.Abs(dirTangRay.Cross(dirTangCurve)) < MConsts.EPS_DEC_WEAK) { linters.ClearDestroy(); return(true); } } if ((isRayStartOnCurve) && (!isStartIntersFound)) { linters.ClearDestroy(); return(true); } } } int numIntersAll = (isStartIntersFound)? linters.Count - 1: linters.Count; typeParity = (numIntersAll % 2 == 0)? MConsts.TypeParity.Even: MConsts.TypeParity.Odd; linters.ClearDestroy(); return(true); }