public void InnerOuterBySelfOrientation(out MConsts.TypeInnerOuter typeInnerOuter) { typeInnerOuter=MConsts.TypeInnerOuter.Undef; RayD ray; CParam parStartRay; MConsts.TypeParity typeParity; for (int iTrial=0; iTrial<MConsts.MAX_RAY_INTERS_TRIAL; iTrial++) { try { if (!this.RayAlmostNormal(out ray, out parStartRay)) continue; // does not count the start of the ray as the intersection if (!this.RayParity(ray, parStartRay, out typeParity)) continue; if (typeParity==MConsts.TypeParity.Undef) continue; } catch (ExceptionGMath) { continue; } typeInnerOuter=(typeParity==MConsts.TypeParity.Even)? MConsts.TypeInnerOuter.Outer: MConsts.TypeInnerOuter.Inner; return; } }
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; }