public void InnerOuterByOutline(Outline outl, out MConsts.TypeInnerOuter typeInnerOuter) { typeInnerOuter = MConsts.TypeInnerOuter.Undef; RayD ray; CParam parStartRay; MConsts.TypeParity typeParityContour, typeParityAll = MConsts.TypeParity.Even; int iTrial; for (iTrial = 0; iTrial < MConsts.MAX_RAY_INTERS_TRIAL; iTrial++) { try { typeParityAll = MConsts.TypeParity.Even; if (!this.RayAlmostNormal(out ray, out parStartRay)) { continue; } int pozCont; for (pozCont = 0; pozCont < outl.NumCont; pozCont++) { Contour cont = outl.ContourByPoz(pozCont); if (cont == this) { continue; } if (!cont.RayParity(ray, null, out typeParityContour)) { break; } if (typeParityContour == MConsts.TypeParity.Undef) { break; } typeParityAll = (typeParityAll == typeParityContour)? MConsts.TypeParity.Even: MConsts.TypeParity.Odd; } if (pozCont != outl.NumCont) { continue; // parity failed for one of contours } } catch (ExceptionGMath) { continue; } break; // the result is clear, stop trials } if (iTrial == MConsts.MAX_RAY_INTERS_TRIAL) { return; // typeInnerOuter is undefined } typeInnerOuter = (typeParityAll == MConsts.TypeParity.Even)? MConsts.TypeInnerOuter.Outer: MConsts.TypeInnerOuter.Inner; }
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); }