public void ParamFromReduced(BCurve bcurve, int indCurve) { if (this.param[indCurve]!=null) { this.param[indCurve].FromReduced(bcurve); } }
public static bool IntersectBL(BCurve bcurve, LCurve lrs, ListInfoInters linters) { if (lrs.IsDegen) { throw new ExceptionGMath("Intersect", "IntersectBL", null); //return false; } BCurve bred = bcurve.Reduced; int numIntersBefore = linters.Count; object[] pars = { bred, lrs, linters }; Type[] types = { pars[0].GetType(), typeof(LCurve), typeof(ListInfoInters) }; MethodInfo infoMethod = typeof(Inters).GetMethod("AuxIntersectBL", types); bool res; try { res = (bool)infoMethod.Invoke(null, pars); } catch (System.Reflection.TargetInvocationException TIException) { throw TIException.InnerException; } if ((object)bred != (object)bcurve) { linters.ParamFromReduced(bcurve, 0, numIntersBefore); } return(res); }
public void ParamFromReduced(BCurve bcurve, int indCurve) { if (this.param[indCurve] != null) { this.param[indCurve].FromReduced(bcurve); } }
public void ParamFromReduced(BCurve bcurve, int indCurve, int pozStart) { for (int poz = pozStart; poz < this.linters.Count; poz++) { InfoInters inters = linters[poz] as InfoInters; inters.ParamFromReduced(bcurve, indCurve); } }
/* * METHODS: MISORIENTED */ public bool RayAlmostNormal(out RayD ray, out CParam parStartRay) { ray = null; parStartRay = null; bool isCurveOK = false; int numTrialMax = 100; // TODO: make constant int numTrialCur = 0; while ((!isCurveOK) && (numTrialCur < numTrialMax)) { numTrialCur++; try { int pozKnotStart = rand.Next(this.NumKnot); BCurve curveStart = this.CurveByPoz(pozKnotStart); if (curveStart == null) { pozKnotStart = this.PozNext(pozKnotStart); curveStart = this.CurveByPoz(pozKnotStart); if (curveStart == null) { //Debug.Assert(false, "Contour: RayAlmostNormal"); continue; } } InfoInters inters; if ((!curveStart.IsDegen) && (curveStart.BBox.Diag >= 1 - MConsts.EPS_DEC_WEAK) && (!curveStart.IsSelfInters(out inters))) { double parVal = 0.25 * rand.Next(1, 4); VecD pntStart = curveStart.Evaluate(parVal); VecD dirNorm = curveStart.DirNorm(parVal); if ((pntStart == null) || (dirNorm == null)) { //Debug.Assert(false, "Contour: RayAlmostNormal"); continue; } double angleRot = (rand.NextDouble() - 0.5) * (Math.PI / 5.0); double scale = 100.0; // TODO: make constant VecD dirRay = new VecD(scale * (Math.Cos(angleRot) * dirNorm.X - Math.Sin(angleRot) * dirNorm.Y), scale * (Math.Sin(angleRot) * dirNorm.X + Math.Cos(angleRot) * dirNorm.Y)); bool isChanged; dirRay.FURound(out isChanged); ray = new RayD(pntStart, pntStart + dirRay); parStartRay = new CParam(parVal, this.KnotByPoz(pozKnotStart)); isCurveOK = true; } } catch (ExceptionGMath) { } } return(isCurveOK); }
public bool Intersect(ListInfoInters linters) { bool res = true; for (int pozA = 0; pozA < this.NumKnot - 1; pozA++) { BCurve curveA = this.CurveByPoz(pozA); if (curveA != null) { Knot knA = this.KnotByPoz(pozA); InfoInters inters; if (curveA.IsSelfInters(out inters)) { inters.ParamToCParam(knA, null); linters.Add(inters); } bool isDegenA = curveA.IsDegen; for (int pozB = pozA + 1; pozB < this.NumKnot; pozB++) { BCurve curveB = this.CurveByPoz(pozB); if (curveB != null) { bool isDegenB = curveB.IsDegen; if (isDegenA || isDegenB) { bool areConjAB, areConjBA; if ((!this.AreConjByPozPoz(pozA, pozB, out areConjAB)) || (!this.AreConjByPozPoz(pozB, pozA, out areConjBA))) { res = false; continue; } if (areConjAB || areConjBA) { continue; } } InfoConnect icAB, icBA; if ((!this.InfoConnectByPozPoz(pozA, pozB, out icAB)) || (!this.InfoConnectByPozPoz(pozB, pozA, out icBA))) { res = false; continue; } int numIntersBefore = linters.Count; Knot knB = this.KnotByPoz(pozB); Inters.IntersectBB(curveA, curveB, icAB, icBA, linters); linters.ParamToCParam(knA, knB, numIntersBefore); } } } } return(res); }
public void Subdivide(Param par, out BCurve curveS, out BCurve curveE) { /* * ASSUMPTION: par should be in the range [0,1] */ curveS = null; curveE = null; if (!this.IsEvaluableStrict(par)) { return; } curveS = new DegenD(this.cp); curveE = new DegenD(this.cp); }
public void Subdivide(Param par, out BCurve curveS, out BCurve curveE) { /* * ASSUMPTION: par should be in the range [0,1] */ curveS = null; curveE = null; if (!this.IsEvaluableStrict(par)) { return; } VecD pnt = this.Evaluate(par); curveS = new SegD(this.cp[0], pnt); curveE = new SegD(pnt, this.cp[1]); }
public bool Intersect(Contour cont, ListInfoInters linters) { Contour contA = this; Contour contB = cont; if (contA == contB) { return(this.Intersect(linters)); } BoxD bboxContA = contA.BBox; BoxD bboxContB = contB.BBox; if (!bboxContA.HasInters(bboxContB)) { return(true); } for (int pozA = 0; pozA < contA.NumKnot; pozA++) { Knot knA = contA.KnotByPoz(pozA); BCurve curveA = contA.CurveByPoz(pozA); if (curveA != null) { BoxD bboxCurveA = curveA.BBox; if (bboxCurveA.HasInters(bboxContB)) { for (int pozB = 0; pozB < contB.NumKnot; pozB++) { BCurve curveB = contB.CurveByPoz(pozB); if (curveB != null) { int numIntersBefore = linters.Count; Inters.IntersectBB(curveA, curveB, null, null, linters); Knot knB = contB.KnotByPoz(pozB); linters.ParamToCParam(knA, knB, numIntersBefore); } } } } } contA = null; contB = null; return(true); }
public void Subdivide(Param par, out BCurve curveS, out BCurve curveE) { /* * ASSUMPTION: par should be in the range [0,1] */ curveS = null; curveE = null; if (!this.IsEvaluableStrict(par)) { return; } VecD pnt01 = (1 - par.Val) * this.cp[0] + par.Val * this.cp[1]; VecD pnt12 = (1 - par.Val) * this.cp[1] + par.Val * this.cp[2]; VecD pnt = (1 - par.Val) * pnt01 + par.Val * pnt12; curveS = new Bez2D(this.cp[0], pnt01, pnt); curveE = new Bez2D(pnt, pnt12, this.cp[2]); }
public void FromReduced(BCurve bcurve) { // parameter of the (reduced)curve may be invalidated if // the curve intersects the self-intersecting Bezier if (this.val == Param.Invalid) { return; } if (bcurve.IsDegen) { return; } if (bcurve is Bez2D) { Bez2D bez = bcurve as Bez2D; Param parM; if (bez.IsSeg(out parM)) { bez.ParamFromSeg(this); } } }
public bool IsSelfInters(out InfoInters inters) { /* * RETURN VALUE: true if Self-Intersecting; false otherwise */ inters = null; Param parM; if (!IsSelfInters(out parM)) { return(false); } if (parM.Val == Param.Infinity) { inters = new IntersD1(0, null, 1, null, this, true); } else if (parM > 1) { Param paramStart = 1.0 / (2.0 * parM.Val - 1.0); BCurve curveInters = this.SubCurve(paramStart, 1); if (curveInters == null) { throw new ExceptionGMath("Bez2D", "IsSelfInters", ""); } inters = new IntersD1(paramStart, null, 1.0, null, curveInters, true); } else if (parM < 0) { Param paramEnd = (-2.0 * parM.Val) / (1.0 - 2.0 * parM.Val); BCurve curveInters = this.SubCurve(0, paramEnd); if (curveInters == null) { throw new ExceptionGMath("Bez2D", "IsSelfInters", ""); } inters = new IntersD1(0.0, null, paramEnd, null, curveInters, true); } return(true); }
/* * METHODS: I_DRAWABLE */ public void Draw(I_Draw i_draw, DrawParam dp) { // for debug only - begin /* * if (this.rayTmp!=null) * { * DrawParamCurve dpCurve=new DrawParamCurve("Cyan",1,false,null); * this.rayTmp.Draw(i_draw, dpCurve); * } */ // for debug only - end DrawParamContour dpContour = dp as DrawParamContour; if (dpContour != null) { DrawParamKnot dpKnot = dpContour.DPKnot; if (dpKnot != null) { foreach (Knot knot in this.knots) { knot.Draw(i_draw, dpKnot); } } DrawParamCurve dpCurve = dpContour.DPCurve; if (dpCurve != null) { for (int poz = 0; poz < this.NumKnot; poz++) { BCurve curve = this.CurveByPoz(poz); if (curve != null) { curve.Draw(i_draw, dpCurve); } } } } }
virtual public void ParamFromReduced(BCurve bcurve, int indCurve) { throw new ExceptionGMath("InfoInters", "ParamFromReduced", "Pure virtual function"); }
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 IntersectBL(BCurve bcurve, LCurve lrs, ListInfoInters linters) { if (lrs.IsDegen) { throw new ExceptionGMath("Intersect","IntersectBL",null); //return false; } BCurve bred = bcurve.Reduced; int numIntersBefore=linters.Count; object[] pars={bred,lrs,linters}; Type[] types={pars[0].GetType(),typeof(LCurve),typeof(ListInfoInters)}; MethodInfo infoMethod=typeof(Inters).GetMethod("AuxIntersectBL",types); bool res; try { res=(bool)infoMethod.Invoke(null,pars); } catch(System.Reflection.TargetInvocationException TIException) { throw TIException.InnerException; } if ((object)bred!=(object)bcurve) { linters.ParamFromReduced(bcurve,0,numIntersBefore); } return res; }
override public void ParamFromReduced(BCurve bcurve, int indCurve) { this.ipis[0].ParamFromReduced(bcurve,indCurve); this.ipis[1].ParamFromReduced(bcurve,indCurve); }
public void FromReduced(BCurve bcurve) { // parameter of the (reduced)curve may be invalidated if // the curve intersects the self-intersecting Bezier if (this.val==Param.Invalid) return; if (bcurve.IsDegen) { return; } if (bcurve is Bez2D) { Bez2D bez=bcurve as Bez2D; Param parM; if (bez.IsSeg(out parM)) { bez.ParamFromSeg(this); } } }
public void Subdivide(Param par, out BCurve curveS, out BCurve curveE) { /* * ASSUMPTION: par should be in the range [0,1] */ curveS=null; curveE=null; if (!this.IsEvaluableStrict(par)) return; curveS=new DegenD(this.cp); curveE=new DegenD(this.cp); }
/* * REFINE INTERSECTION D1 */ public static bool RefineIntersBBD1(BCurve curveA, BCurve curveB, out InfoInters inters) { /* * ASSUMPTIONS: * - curveA & curveB are MAXIMALLY REDUCED * - intersection is KNOWN to have dimension D1 * - does not work in case of SI beziers * => OR: both curveA & curveB are SEGMENTS * OR: both curveA & curveB are BEZIER */ inters=null; InfoInters selfinters; if (curveA.IsSelfInters(out selfinters)||curveB.IsSelfInters(out selfinters)) { throw new ExceptionGMath("Intersect","RefineIntersBBD1",null); //return false; } VecD a0=curveA.Start; VecD a1=curveA.End; Param paramBInvA0, paramBInvA1; bool isOn; if (!a0.InverseOn(curveB, out isOn, out paramBInvA0)||(!isOn)) return false; if (!a1.InverseOn(curveB, out isOn, out paramBInvA1)||(!isOn)) return false; paramBInvA0.Round(0,1); paramBInvA1.Round(0,1); bool areCoDirected=(paramBInvA1>=paramBInvA0); if (!areCoDirected) { BCurve revB=curveB.Reversed as BCurve; if (!Inters.RefineIntersBBD1(curveA,revB,out inters)) return false; if (inters!=null) { inters.ParamReverse(1,1); } return true; } VecD b0=curveB.Start; VecD b1=curveB.End; Param paramAInvB0, paramAInvB1; if (!b0.InverseOn(curveA, out isOn, out paramAInvB0)||(!isOn)) return false; if (!b1.InverseOn(curveA, out isOn, out paramAInvB1)||(!isOn)) return false; paramAInvB0.Round(0,1); paramAInvB1.Round(0,1); Param paramInA=null, paramInB=null, paramOutA=null, paramOutB=null; VecD pntIn=null, pntOut=null; if (paramBInvA0<=0) // before or start { paramInA=paramAInvB0; paramInB=0; pntIn=b0; } else if (paramBInvA0<1) // inner { paramInA=0; paramInB=paramBInvA0; pntIn=a0; } if ((paramBInvA1>=0)&&(paramBInvA1<=1)) // inner or end { paramOutA=1; paramOutB=paramBInvA1; pntOut=a1; } else if (paramBInvA1>1) // after { paramOutA=paramAInvB1; paramOutB=1; pntOut=b1; } if ((pntIn==null)||(pntOut==null)) { throw new ExceptionGMath("Intersect","RefineIntersBBD1",null); //return false; } Curve curveInters=curveA.SubCurve(paramInA,paramOutA); inters=new IntersD1(paramInA,paramInB, paramOutA,paramOutB,curveInters,false); 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 AuxIntersectBB(Bez2D bezA, Bez2D bezB, InfoConnect icAB, InfoConnect icBA, ListInfoInters linters) { // bezA and bezB are irreducable !!! bool connectAB = ((icAB != null) && (icAB.IsConnect)); bool connectBA = ((icBA != null) && (icBA.IsConnect)); if ((connectBA) && (!connectAB)) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); } bool connect = connectAB || connectBA; Param parM; bool isSelfIntersA = bezA.IsSelfInters(out parM); bool isSelfIntersB = bezB.IsSelfInters(out parM); if (isSelfIntersA || isSelfIntersB) { BCurve curveA = bezA; if (isSelfIntersA) { curveA = bezA.SupportFlat(); } BCurve curveB = bezB; if (isSelfIntersB) { curveB = bezB.SupportFlat(); } int numIntersBefore = linters.Count; Inters.IntersectBB(curveA, curveB, null, null, linters); /* * CLEAN END-POINT if the curve does not return to it */ if ((connectAB) && (!connectBA)) { bool coversA1 = false; bool coversB0 = false; if (isSelfIntersA) { coversA1 = bezA.CoversEndPoint(false); } if (isSelfIntersB) { coversB0 = bezB.CoversEndPoint(true); } if ((!coversA1) && (!coversB0)) { linters.CleanEndPointBezSI(bezA.End, numIntersBefore); } } linters.ParamInvalidateBezSI(numIntersBefore); return(true); } // test for 1-dimensional intersection of supports bool isB0OnA, isB2OnA; Param paramAInvB0, paramAInvB2; if (!bezB.Cp(0).InverseOn(bezA, out isB0OnA, out paramAInvB0)) { return(false); } if (!bezB.Cp(2).InverseOn(bezA, out isB2OnA, out paramAInvB2)) { return(false); } if ((isB0OnA) && (isB2OnA)) { bool areCoincide = true; Param par; for (int i = 1; i <= 3; i++) { // evaluate bezB at paramaters 1/4, 1/2, 3/4 and check // whether the points lie on bezA [-Infinity,Infinity] VecD pnt = bezB.Evaluate(0.25 * i); if (!pnt.InverseOn(bezA, out areCoincide, out par)) { return(false); } if (!areCoincide) { break; } } if (areCoincide) { Param.TypeParam typeB0 = bezA.ParamClassify(paramAInvB0); Param.TypeParam typeB2 = bezA.ParamClassify(paramAInvB2); int mult = (int)typeB0 * (int)typeB2; if (mult == 4) { return(true); // no intersections } else if (mult == 1) { // bezB is degenerated throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); //return false; } else if (mult == 2) { // 0-dimentional connection at the end point if ((typeB0 == Param.TypeParam.Start) && (typeB2 == Param.TypeParam.Before)) { if (connect) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); //return false; } IntersD0 inters = new IntersD0(0, 0, bezB.Start, false); linters.Add(inters); return(true); } if ((typeB0 == Param.TypeParam.Before) && (typeB2 == Param.TypeParam.Start)) { if (connect) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); //return false; } IntersD0 inters = new IntersD0(1, 0, bezB.End, false); linters.Add(inters); return(true); } if ((typeB0 == Param.TypeParam.End) && (typeB2 == Param.TypeParam.After)) { if (!connect) { IntersD0 inters = new IntersD0(0, 1, bezB.Start, false); linters.Add(inters); return(true); } return(true); } if ((typeB0 == Param.TypeParam.After) && (typeB2 == Param.TypeParam.End)) { if (connect) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); //return false; } IntersD0 inters = new IntersD0(1, 1, bezB.End, false); linters.Add(inters); return(true); } } else if (mult <= 0) { InfoInters inters; Inters.RefineIntersBBD1(bezA, bezB, out inters); linters.Add(inters); return(true); } throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); //return false; } } /* * INTERSECTION IS 0-DIMENTIONAL AT MOST */ VecD[] cfA, cfB; bezA.PowerCoeff(out cfA); bezB.PowerCoeff(out cfB); Param parA, parB; int numRootB; double[] rootsB; double kappa = cfA[2].Cross(cfA[1]); // bezA and bezB are non-degenerated and consequent if (connectAB) { if (bezA.End != bezB.Start) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); //return false; } if (connectBA) { // both ends are connected if (bezA.Start != bezB.End) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); //return false; } if (icAB.IsTangent || icBA.IsTangent) { // tangent connection - no additional intersections return(true); } double crossA2B2 = cfA[2].Cross(cfB[2]); double[] cfEqn = { kappa *(kappa + 2 * crossA2B2 + cfA[1].Cross(cfB[2])), -crossA2B2 * (2 * kappa + crossA2B2), crossA2B2 *crossA2B2 }; Equation.RootsReal(cfEqn[2], cfEqn[1], cfEqn[0], out numRootB, out rootsB); if (numRootB == Equation.NumRootInfinite) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); //return false; } if (rootsB != null) { for (int iRoot = 0; iRoot < numRootB; iRoot++) { parB = rootsB[iRoot]; if (bezB.IsEvaluableStrict(parB)) { parA = 1.0 + parB.Val * (cfA[2].Cross(cfB[2]) * parB.Val + cfA[2].Cross(cfB[1])) / kappa; if (bezA.IsEvaluableStrict(parA) /*&& (parA!=1.)*/) { IntersD0 inters = new IntersD0(parA, parB, 0.5 * (bezA.Evaluate(parA) + bezB.Evaluate(parB)), false); linters.Add(inters); } } } } return(true); } // consequent Bezier with one connection if (icAB.IsTangent) { // tangent connection - at most 2 additional intersections double[] cfEqn = { kappa *(kappa - cfB[2].Cross(cfB[1])), 2 * cfA[2].Cross(cfB[2]) * kappa, cfA[2].Cross(cfB[2]) * cfA[2].Cross(cfB[2]) }; Equation.RootsReal(cfEqn[2], cfEqn[1], cfEqn[0], out numRootB, out rootsB); if (numRootB == Equation.NumRootInfinite) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); //return false; } if (rootsB != null) { for (int iRoot = 0; iRoot < numRootB; iRoot++) { parB = rootsB[iRoot]; if (bezB.IsEvaluableStrict(parB)) { parA = 1 + parB.Val * (cfA[2].Cross(cfB[2]) * parB.Val + cfA[2].Cross(cfB[1])) / kappa; if (bezA.IsEvaluableStrict(parA) /*&&(parA!=1)*/) { IntersD0 inters = new IntersD0(parA, parB, 0.5 * (bezA.Evaluate(parA) + bezB.Evaluate(parB)), false); linters.Add(inters); } } } } return(true); } else { // non-tangent connection - at most 3 additional intersections double[] cfEqn = { kappa *(2 * cfA[2].Cross(cfB[1]) + cfA[1].Cross(cfB[1])), cfA[2].Cross(cfB[1]) * cfA[2].Cross(cfB[1]) + kappa * (2 * cfA[2].Cross(cfB[2]) + cfA[1].Cross(cfB[2])), 2 * cfA[2].Cross(cfB[2]) * cfA[2].Cross(cfB[1]), cfA[2].Cross(cfB[2]) * cfA[2].Cross(cfB[2]) }; Equation.RootsReal(cfEqn[3], cfEqn[2], cfEqn[1], cfEqn[0], out numRootB, out rootsB); if (numRootB == Equation.NumRootInfinite) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); //return false; } if (rootsB != null) { for (int iRoot = 0; iRoot < numRootB; iRoot++) { parB = rootsB[iRoot]; if (bezB.IsEvaluableStrict(parB)) { parA = 1 + parB.Val * (cfA[2].Cross(cfB[2]) * parB + cfA[2].Cross(cfB[1])) / kappa; if (bezA.IsEvaluableStrict(parA) /*&&(parA!=1)*/) { IntersD0 inters = new IntersD0(parA, parB, 0.5 * (bezA.Evaluate(parA) + bezB.Evaluate(parB)), false); linters.Add(inters); } } } } return(true); } } // bezA and bezB are non-degenerated, non-consequent curves bool isSwappedAB = false; if (Math.Abs(cfA[2].Cross(cfA[1])) < Math.Abs(cfB[2].Cross(cfB[1]))) { kappa = cfB[2].Cross(cfB[1]); isSwappedAB = true; VecD tmp; for (int i = 0; i < 3; i++) { tmp = cfA[i]; cfA[i] = cfB[i]; cfB[i] = tmp; } } double[] e = { cfA[2].Cross(cfB[0] - cfA[0]), cfA[2].Cross(cfB[1]), cfA[2].Cross(cfB[2]) }; double[] f = { (cfB[0] - cfA[0]).Cross(cfA[1]), cfB[1].Cross(cfA[1]), cfB[2].Cross(cfA[1]) }; Equation.RootsReal(e[2] * e[2], 2 * e[2] * e[1], e[1] * e[1] + 2 * e[2] * e[0] - kappa * f[2], 2 * e[1] * e[0] - kappa * f[1], e[0] * e[0] - kappa * f[0], out numRootB, out rootsB); if (numRootB == Equation.NumRootInfinite) { throw new ExceptionGMath("Intersect", "AuxIntersectBB(bez,bez)", null); //return false; } if (rootsB != null) { for (int iRoot = 0; iRoot < numRootB; iRoot++) { parB = rootsB[iRoot]; parA = Equation.Evaluate(parB.Val, e[2], e[1], e[0]) / kappa; if (isSwappedAB) { Param parTmp; parTmp = parA; parA = parB; parB = parTmp; } if (bezA.IsEvaluableStrict(parA) && bezB.IsEvaluableStrict(parB)) { IntersD0 inters = new IntersD0(parA, parB, 0.5 * (bezA.Evaluate(parA) + bezB.Evaluate(parB)), false); linters.Add(inters); } } } return(true); }
/* * REFINE INTERSECTION D1 */ public static bool RefineIntersBBD1(BCurve curveA, BCurve curveB, out InfoInters inters) { /* * ASSUMPTIONS: * - curveA & curveB are MAXIMALLY REDUCED * - intersection is KNOWN to have dimension D1 * - does not work in case of SI beziers * => OR: both curveA & curveB are SEGMENTS * OR: both curveA & curveB are BEZIER */ inters = null; InfoInters selfinters; if (curveA.IsSelfInters(out selfinters) || curveB.IsSelfInters(out selfinters)) { throw new ExceptionGMath("Intersect", "RefineIntersBBD1", null); //return false; } VecD a0 = curveA.Start; VecD a1 = curveA.End; Param paramBInvA0, paramBInvA1; bool isOn; if (!a0.InverseOn(curveB, out isOn, out paramBInvA0) || (!isOn)) { return(false); } if (!a1.InverseOn(curveB, out isOn, out paramBInvA1) || (!isOn)) { return(false); } paramBInvA0.Round(0, 1); paramBInvA1.Round(0, 1); bool areCoDirected = (paramBInvA1 >= paramBInvA0); if (!areCoDirected) { BCurve revB = curveB.Reversed as BCurve; if (!Inters.RefineIntersBBD1(curveA, revB, out inters)) { return(false); } if (inters != null) { inters.ParamReverse(1, 1); } return(true); } VecD b0 = curveB.Start; VecD b1 = curveB.End; Param paramAInvB0, paramAInvB1; if (!b0.InverseOn(curveA, out isOn, out paramAInvB0) || (!isOn)) { return(false); } if (!b1.InverseOn(curveA, out isOn, out paramAInvB1) || (!isOn)) { return(false); } paramAInvB0.Round(0, 1); paramAInvB1.Round(0, 1); Param paramInA = null, paramInB = null, paramOutA = null, paramOutB = null; VecD pntIn = null, pntOut = null; if (paramBInvA0 <= 0) // before or start { paramInA = paramAInvB0; paramInB = 0; pntIn = b0; } else if (paramBInvA0 < 1) // inner { paramInA = 0; paramInB = paramBInvA0; pntIn = a0; } if ((paramBInvA1 >= 0) && (paramBInvA1 <= 1)) // inner or end { paramOutA = 1; paramOutB = paramBInvA1; pntOut = a1; } else if (paramBInvA1 > 1) // after { paramOutA = paramAInvB1; paramOutB = 1; pntOut = b1; } if ((pntIn == null) || (pntOut == null)) { throw new ExceptionGMath("Intersect", "RefineIntersBBD1", null); //return false; } Curve curveInters = curveA.SubCurve(paramInA, paramOutA); inters = new IntersD1(paramInA, paramInB, paramOutA, paramOutB, curveInters, false); return(true); }
public void Subdivide(Param par, out BCurve curveS, out BCurve curveE) { /* * ASSUMPTION: par should be in the range [0,1] */ curveS=null; curveE=null; if (!this.IsEvaluableStrict(par)) return; VecD pnt=this.Evaluate(par); curveS=new SegD(this.cp[0],pnt); curveE=new SegD(pnt,this.cp[1]); }
override public void ParamFromReduced(BCurve bcurve, int indCurve) { this.ipis[0].ParamFromReduced(bcurve, indCurve); this.ipis[1].ParamFromReduced(bcurve, indCurve); }
public void Subdivide(Param par, out BCurve curveS, out BCurve curveE) { /* * ASSUMPTION: par should be in the range [0,1] */ curveS=null; curveE=null; if (!this.IsEvaluableStrict(par)) return; VecD pnt01=(1-par.Val)*this.cp[0]+par.Val*this.cp[1]; VecD pnt12=(1-par.Val)*this.cp[1]+par.Val*this.cp[2]; VecD pnt = (1-par.Val)*pnt01+par.Val*pnt12; curveS=new Bez2D(this.cp[0],pnt01,pnt); curveE=new Bez2D(pnt,pnt12,this.cp[2]); }
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); }
virtual public void ParamFromReduced(BCurve bcurve, int indCurve) { throw new ExceptionGMath("InfoInters","ParamFromReduced","Pure virtual function"); }
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; }
public void ParamFromReduced(BCurve bcurve, int indCurve, int pozStart) { for (int poz=pozStart; poz<this.linters.Count; poz++) { InfoInters inters=linters[poz] as InfoInters; inters.ParamFromReduced(bcurve,indCurve); } }