public void Reverse() { VecD tmp = this.cp[0]; this.cp[0] = this.cp[2]; this.cp[2] = tmp; }
public VecD DirTang(Param par) { if (this.IsDegen) { return(null); } Param parM; if (this.IsSeg(out parM)) { SegD seg = new SegD(this.cp[0], this.cp[2]); return((seg as LCurve).DirTang); } if (this.IsSelfInters(out parM)) { SegD support = this.SupportFlat(); return((support as LCurve).DirTang); } VecD tan = 2.0 * (1.0 - par.Val) * (this.cp[1] - this.cp[0]) + 2.0 * par.Val * (this.cp[2] - this.cp[1]); if (tan.Norm < MConsts.EPS_COMP) { return(null); } return((1.0 / tan.Norm) * tan); }
public bool CoversEndPoint(bool isStart) { /* * ASSUMPTION: * The Bezier is KNOWN to be SELF-INTERSECTING * MEANING: * Determines whether a SELF-INTERSECTING Bezier covers * its end-point more than once */ if (this.cp[0] == this.cp[2]) { return(true); } if (isStart) { VecD vec01 = this.cp[1] - this.cp[0]; VecD vec02 = this.cp[2] - this.cp[0]; return(vec01.Dot(vec02) < 0); } else { VecD vec21 = this.cp[1] - this.cp[2]; VecD vec20 = this.cp[0] - this.cp[2]; return(vec21.Dot(vec20) < 0); } }
public void PowerCoeff(out VecD[] pcf) { pcf = new VecD[3]; pcf[2] = this.cp[0] - 2 * this.cp[1] + this.cp[2]; pcf[1] = 2 * (this.cp[1] - this.cp[0]); pcf[0] = this.cp[0]; }
public MatrixD(OTF2Dot14[,] tr, VecD shift) : this() { if (tr!=null) { if ((tr.GetLength(0)!=2)||(tr.GetLength(1)!=2)) { throw new ExceptionGMath("MatrixD","MatrixD",null); } for (int i=0;i<2;i++) for (int j=0;j<2;j++) { this.tr[i,j]=(double)tr[i,j]; } } else { this.tr[0,0]=this.tr[1,1]=1.0; this.tr[0,1]=this.tr[1,0]=0.0; } if (shift!=null) { this.tr[2,0]=shift.X; this.tr[2,1]=shift.Y; } }
public bool Project(LCurve lcurve, out Param param, out VecD pnt) { /* * MEANING: the NEAREST point in the PARAMETRIC RANGE * of the curve * * ASSUMPTIONS: the curve may be not reduced */ param = null; pnt = null; if (lcurve.IsDegen) { SegD seg = lcurve as SegD; if (seg == null) { throw new ExceptionGMath("VecD", "Project", null); //return false; } param = new Param(Param.Degen); pnt = seg.Middle; return(true); } this.Perp(lcurve, out param); param.Clip(lcurve.ParamStart, lcurve.ParamEnd); pnt = lcurve.Evaluate(param); return(true); }
public VecD Transformed(MatrixD m) { VecD vec = new VecD(this); vec.Transform(m); return(vec); }
/* * CONSTRUCTORS */ public IntersD0(Param parA, Param parB, VecD pnt, bool includeBezSI) { // COPY this.ipi = new InfoParamInters(parA, parB); this.pntInters = new VecD(pnt); this.includeBezSI = includeBezSI; }
public Bez2D(VecD start, VecD mid, VecD end) : this() { this.cp[0]=new VecD(start); this.cp[1]=new VecD(mid); this.cp[2]=new VecD(end); }
public Bez2D(VecD start, VecD mid, VecD end) : this() { this.cp[0] = new VecD(start); this.cp[1] = new VecD(mid); this.cp[2] = new VecD(end); }
public MatrixD(OTF2Dot14[,] tr, VecD shift) : this() { if (tr != null) { if ((tr.GetLength(0) != 2) || (tr.GetLength(1) != 2)) { throw new ExceptionGMath("MatrixD", "MatrixD", null); } for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { this.tr[i, j] = (double)tr[i, j]; } } } else { this.tr[0, 0] = this.tr[1, 1] = 1.0; this.tr[0, 1] = this.tr[1, 0] = 0.0; } if (shift != null) { this.tr[2, 0] = shift.X; this.tr[2, 1] = shift.Y; } }
public bool Project(Bez2D bez, out Param par, out VecD pnt) { /* * MEANING: the NEAREST point in the RANGE [0,1] * ASSUMPTION: - bezier can be non-reduced * - bezier is NOT self-intersecting */ par = null; pnt = null; Param parM; if (bez.IsSelfInters(out parM)) { throw new ExceptionGMath("VecD", "Project(bez)", null); //return false; } if (bez.IsDegen) { par = new Param(Param.Degen); pnt = bez.Middle; return(true); } if (bez.IsSeg(out parM)) { SegD seg = bez.Reduced as SegD; this.Project(seg, out par, out pnt); bez.ParamFromSeg(par); return(true); } // case of non-flat Bezier Param[] parsPerp; if (!this.Perp(bez, out parsPerp)) { return(false); } double distS = this.Dist(bez.Start); double distE = this.Dist(bez.End); double distMin = Math.Min(distS, distE); double parMin = (distS <= distE)? 0.0: 1.0; if (parsPerp != null) { for (int iPerp = 0; iPerp < parsPerp.Length; iPerp++) { if (bez.IsEvaluableStrict(parsPerp[iPerp])) { double distPerp = this.Dist(bez.Evaluate(parsPerp[iPerp])); if (distPerp < distMin) { distMin = distPerp; parMin = parsPerp[iPerp]; } } } } par = parMin; pnt = bez.Evaluate(parMin); return(true); }
/* * 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 override bool Equals(object obj) { VecD vec = obj as VecD; if (vec == null) { return(false); } return((this.x == vec.X) && (this.y == vec.Y)); }
public VecD DirNorm(Param par) { VecD tan = this.DirTang(par); if ((object)tan == null) { return(null); } return(new VecD(-tan.Y, tan.X)); }
public VecD Evaluate(Param par) { if (!this.IsEvaluableWide(par)) { throw new ExceptionGMath("VecD", "Evaluate", null); } VecD vec = (1 - par) * (1 - par) * this.cp[0] + 2 * par * (1 - par) * this.cp[1] + par * par * this.cp[2]; return(vec); }
public Component(Component component) { this.indGlyphComponent = component.IndexGlyphComponent; this.indKnotAttGlyph = component.IndexKnotAttGlyph; this.indKnotAttComponent = component.IndexKnotAttComponent; this.shift = component.Shift; this.trOTF2Dot14 = component.TrOTF2Dot14; this.trD = component.TrD; this.numKnot = component.NumKnot; this.numCont = component.NumCont; this.indKnotStart = component.IndKnotStart; this.pozContStart = component.PozContStart; }
public Component(int indexGlyphComponent) { this.indGlyphComponent = indexGlyphComponent; this.indKnotAttGlyph = GConsts.IND_UNINITIALIZED; this.indKnotAttComponent = GConsts.IND_UNINITIALIZED; this.shift = null; this.trOTF2Dot14 = null; this.trD = null; this.numKnot = GConsts.IND_UNINITIALIZED; this.numCont = GConsts.IND_UNINITIALIZED; this.indKnotStart = GConsts.IND_UNINITIALIZED; this.pozContStart = GConsts.IND_UNINITIALIZED; }
public VecD Evaluate(Param par) { if (this.IsEvaluableWide(par)) { VecD vec = (1 - par) * this.cp[0] + par * this.cp[1]; return(vec); } if ((par.IsDegen) && (this.IsDegen)) { return(0.5 * (this.cp[0] + this.cp[1])); } return(null); }
public BCurve SubCurve(Param parA, Param parB) { if ((!this.IsEvaluableStrict(parA)) || (!this.IsEvaluableStrict(parB))) { return(null); } VecD pntA = this.Evaluate(parA); VecD pntB = this.Evaluate(parB); /* * if (Math.Abs(parA-parB)<MConsts.EPS_COMP) * return new DegenD(0.5*(pntA+pntB)); */ return(new SegD(pntA, pntB)); }
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]); }
/* * knot0=this; * knot1=(Knot *)(knot0->next); * knot2=(Knot *)(knot1->next); * on0=knot0->on; on1=knot1->on; on2=knot2->on; * if ((!on0)&&(on1)) return false; * * if (icToNext) icToNext->From(true,false); * curve.type=eGeomUndef; * knotStartNext=knot1; * * if (on1) * { * if (on0) * { * curve.seg.From(knot0->x,knot0->y,knot1->x,knot1->y,false); * curve.type=eGeomSeg; * } * else * { * if (icToNext) icToNext->Connect(false); * } * } * else // 1 - off curve knot * { * curve.type=eGeomBez; * VecD cp0, cp1, cp2; * * if (on0) * { * cp0.From(knot0->x,knot0->y,false); * } * else * { * cp0.From(0.5*(knot0->x+knot1->x),0.5*(knot0->y+knot1->y)); * } * * cp1.From(knot1->x,knot1->y,false); * * if (on2) * { * knotStartNext=knot2; * cp2.From(knot2->x,knot2->y,false); * } * else * { * if (icToNext) icToNext->Tangent(true); * cp2.From(0.5*(knot1->x+knot2->x),0.5*(knot1->y+knot2->y)); * } * curve.bez.From(cp0,cp1,cp2); * } * * * if (getNextNonDegen) * { * CurveD curveAux; * Knot *knotCurAux, *knotNextAux; * if (!knotStartNext->GetCurve(curveAux, knotNextAux)) return false; * if (!curveAux.IsPnt()) return true; * icToNext->Tangent(false); * while (curveAux.IsPnt()) * { * knotCurAux=knotNextAux; * if (knotCurAux==knotStartNext) return false; // no non-degenerated curves... * if (!knotCurAux->GetCurve(curveAux, knotNextAux)) return false; * } * knotStartNext=knotCurAux; * } * return true; * } */ public Knot KnotNearest(VecD vecLocation) { double distMin = MConsts.Infinity; Knot knotNearest = null; foreach (Knot knot in this.knots) { double distCur = vecLocation.Dist(knot.Val); if (distCur < distMin) { distMin = distCur; knotNearest = knot; } } return(knotNearest); }
public void CleanEndPointBezSI(VecD pnt, int pozStart) { for (int poz = pozStart; poz < this.linters.Count; poz++) { IntersD0 intersD0 = linters[poz] as IntersD0; if (intersD0 != null) { bool toDelete = (intersD0.PntInters == pnt); if (toDelete) { this.linters.RemoveAt(poz); poz--; } } } }
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]); }
/* * METHODS: I_DRAWABLE */ public void Draw(I_Draw i_draw, DrawParam dp) { DrawParamCurve dpCurve = dp as DrawParamCurve; if (dpCurve != null) { if (!this.IsDegen) { VecD endToDraw = this.Start + i_draw.DrawWorldInfinity * (this as LCurve).DirTang; i_draw.DrawSeg(this.cp[0].X, this.cp[0].Y, endToDraw.X, endToDraw.Y, dpCurve.StrColor, dpCurve.ScrWidth); } } if (dpCurve.ToDrawEndPoints) { this.Cp(0).Draw(i_draw, dpCurve.DPEndPoints); this.Cp(1).Draw(i_draw, dpCurve.DPEndPoints); } }
public Knot KnotNearest(VecD vecLocation) { double distMin = MConsts.Infinity; Knot knotNearest = null; foreach (Contour cont in this.conts) { Knot knotNearestCur = cont.KnotNearest(vecLocation); if (knotNearestCur != null) { double distCur = vecLocation.Dist(knotNearestCur.Val); if (distCur < distMin) { distMin = distCur; knotNearest = knotNearestCur; } } } return(knotNearest); }
bool Perp(LCurve lrs, out Param param) { /* * MEANING: perpendicular to the parametric range * [-Infinity, Infinity] */ param = null; if (lrs.IsDegen) { throw new ExceptionGMath("VecD", "Perp", null); //return false; } VecD start = lrs.Start; VecD end = lrs.End; double length = (end - start).Norm; VecD tang = lrs.DirTang; param = new Param(((this - start).Dot(tang)) / ((end - start).Dot(tang))); return(true); }
/* * METHODS: I_DRAWABLE */ public void Draw(I_Draw i_draw, DrawParam dp) { DrawParamCurve dpCurve = dp as DrawParamCurve; if (dpCurve == null) { return; } i_draw.DrawSeg(this.cp[0].X, this.cp[0].Y, this.cp[1].X, this.cp[1].Y, dpCurve.StrColor, dpCurve.ScrWidth); if (dpCurve.ToDrawEndPoints) { DrawParamVec dpEndPoints = dpCurve.DPEndPoints; if (dpEndPoints != null) { VecD vec = this.cp[0]; vec.Draw(i_draw, dpEndPoints); vec = this.cp[1]; vec.Draw(i_draw, dpEndPoints); } } }
/* * CONSTRUCTORS */ public IntersD0(Param parA, Param parB, VecD pnt, bool includeBezSI) { // COPY this.ipi=new InfoParamInters(parA,parB); this.pntInters=new VecD(pnt); this.includeBezSI=includeBezSI; }
/* * METHODS: INFO (all information is copied * prior passing to a user) */ public Knot InfoKnotByLocation(VecD vecLocation) { Knot knotNearestCopy=null; if (this.outl!=null) { Knot knotNearest=this.outl.KnotNearest(vecLocation); if (knotNearest!=null) { knotNearestCopy=new Knot(knotNearest); } } return knotNearestCopy; }
public RayD(VecD start, VecD end): this() { this.cp[0]=new VecD(start); this.cp[1]=new VecD(end); }
public BoxD(double xMin, double yMin, double xMax, double yMax) { this.vecMin=new VecD(xMin,yMin); this.vecMax=new VecD(xMax,yMax); }
public bool Contains(VecD vec) { // true: if vec is inside or on boundary return ((this.VecMin.X<=vec.X)&&(vec.X<=this.VecMax.X)&& (this.VecMin.Y<=vec.Y)&&(vec.Y<=this.VecMax.Y)); }
public Component(Component component) { this.indGlyphComponent=component.IndexGlyphComponent; this.indKnotAttGlyph=component.IndexKnotAttGlyph; this.indKnotAttComponent=component.IndexKnotAttComponent; this.shift=component.Shift; this.trOTF2Dot14=component.TrOTF2Dot14; this.trD=component.TrD; this.numKnot=component.NumKnot; this.numCont=component.NumCont; this.indKnotStart=component.IndKnotStart; this.pozContStart=component.PozContStart; }
public DegenD(VecD vec) : this() { this.cp.From(vec); }
public double Dist(VecD vec) { return (this-vec).Norm; }
public bool Project(LCurve lcurve, out Param param, out VecD pnt) { /* * MEANING: the NEAREST point in the PARAMETRIC RANGE * of the curve * * ASSUMPTIONS: the curve may be not reduced */ param=null; pnt=null; if (lcurve.IsDegen) { SegD seg=lcurve as SegD; if (seg==null) { throw new ExceptionGMath("VecD","Project",null); //return false; } param=new Param(Param.Degen); pnt=seg.Middle; return true; } this.Perp(lcurve, out param); param.Clip(lcurve.ParamStart,lcurve.ParamEnd); pnt=lcurve.Evaluate(param); return true; }
public bool ProjectGeneral(Bez2D bez, out Param[] pars, out VecD pnt) { /* * MEANING: parameter (or parameters) of the nearest point * in range [0,1] * * ASSUMPTIONS: bezier can be non-reduced * bezier can be self-intersecting * */ pars=null; pnt=null; Param parM; if (!bez.IsSelfInters(out parM)) { Param par; if (!this.Project(bez,out par,out pnt)) return false; if (par!=null) { pars=new Param[1]; pars[0]=par; } return true; } double valM=parM.Val; if (parM<0) { Bez2D bezRev=new Bez2D(bez); bezRev.Reverse(); if (!this.ProjectGeneral(bezRev,out pars,out pnt)) return false; if (pars!=null) { for (int iPar=0; iPar<pars.Length; iPar++) { pars[iPar].Reverse(1); } } return true; } SegD support=bez.SupportFlat(); Param parSupport; if (!this.Project(support,out parSupport, out pnt)) return false; if (!bez.ParamFromSupport(parSupport,out pars)) return false; return true; }
public bool Project(Bez2D bez, out Param par, out VecD pnt) { /* * MEANING: the NEAREST point in the RANGE [0,1] * ASSUMPTION: - bezier can be non-reduced * - bezier is NOT self-intersecting */ par=null; pnt=null; Param parM; if (bez.IsSelfInters(out parM)) { throw new ExceptionGMath("VecD","Project(bez)",null); //return false; } if (bez.IsDegen) { par=new Param(Param.Degen); pnt=bez.Middle; return true; } if (bez.IsSeg(out parM)) { SegD seg=bez.Reduced as SegD; this.Project(seg,out par,out pnt); bez.ParamFromSeg(par); return true; } // case of non-flat Bezier Param[] parsPerp; if (!this.Perp(bez, out parsPerp)) return false; double distS=this.Dist(bez.Start); double distE=this.Dist(bez.End); double distMin=Math.Min(distS,distE); double parMin=(distS<=distE)? 0.0: 1.0; if (parsPerp!=null) { for (int iPerp=0; iPerp<parsPerp.Length; iPerp++) { if (bez.IsEvaluableStrict(parsPerp[iPerp])) { double distPerp=this.Dist(bez.Evaluate(parsPerp[iPerp])); if (distPerp<distMin) { distMin=distPerp; parMin=parsPerp[iPerp]; } } } } par=parMin; pnt=bez.Evaluate(parMin); return true; }
public VecD Transformed(MatrixD m) { VecD vec=new VecD(this); vec.Transform(m); return vec; }
/* * METHODS */ override public void ClearRelease() { this.ipi.ClearRelease(); this.ipi=null; this.pntInters=null; }
public void PowerCoeff(out VecD[] pcf) { pcf=new VecD[1]; pcf[0]=new VecD(this.cp); }
/* * CONSTRUCTORS */ public DegenD() { this.cp=new VecD(0,0); }
public double Cross(VecD vec) { return (this.x*vec.Y-this.y*vec.X); }
public Component(int indexGlyphComponent) { this.indGlyphComponent=indexGlyphComponent; this.indKnotAttGlyph=GConsts.IND_UNINITIALIZED; this.indKnotAttComponent=GConsts.IND_UNINITIALIZED; this.shift=null; this.trOTF2Dot14=null; this.trD=null; this.numKnot=GConsts.IND_UNINITIALIZED; this.numCont=GConsts.IND_UNINITIALIZED; this.indKnotStart=GConsts.IND_UNINITIALIZED; this.pozContStart=GConsts.IND_UNINITIALIZED; }
public double Dot(VecD vec) { return (this.x*vec.X+this.y*vec.Y); }
internal void ClearRelease() { this.shift=null; this.trOTF2Dot14=null; this.trD=null; }
public void From(VecD vec) { this.x=vec.X; this.y=vec.Y; }
public BoxD(VecD vecMin, VecD vecMax) { this.vecMin=new VecD(vecMin); this.vecMax=new VecD(vecMax); }
public VecD(VecD vec) { this.x=vec.X; this.y=vec.Y; }
public void PowerCoeff(out VecD[] pcf) { pcf=new VecD[2]; pcf[1]=this.cp[1]-this.cp[0]; pcf[0]=this.cp[0]; }
/* * 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 AuxIntersectBL(Bez2D bez, LCurve lrs, ListInfoInters linters) { // bezier is irreducable !!! if (linters == null) { throw new ExceptionGMath("Intersect", "AuxIntersectBL(bez,lrs)", "Null argument"); } if (lrs.IsDegen) { throw new ExceptionGMath("Intersect", "AuxIntersectBL(bez,lrs)", null); } Param parM; if (bez.IsSelfInters(out parM)) { if (parM.Val < 0) { Bez2D bezRev = bez.Reversed as Bez2D; int numIntersBefore = linters.Count; if (!Inters.AuxIntersectBL(bezRev, lrs, linters)) { return(false); } linters.ParamReverse(1, 0, numIntersBefore); return(true); } SegD support = bez.SupportFlat(); InfoInters intersSup; if (!Inters.IntersectLL(support, lrs, out intersSup)) { return(false); } if (intersSup == null) { return(true); } /* * convert parameters from support to Bezier */ // invalidate in case of D1 intersection if (intersSup.Dim == InfoInters.TypeDim.Dim1) { (intersSup as IntersD1).ParamInvalidateBezSI(); linters.Add(intersSup); return(true); } // write as 1 or 2 intersections with different parameters // in case of D0 intersections InfoInters[] intersBez; if (!bez.IntersFromSupport(intersSup, 0, out intersBez)) { return(false); } for (int iIntersBez = 0; iIntersBez < intersBez.Length; iIntersBez++) { linters.Add(intersBez[iIntersBez]); } return(true); } // bezier is NOT self/intersecting VecD[] cfLrs, cfBez; lrs.PowerCoeff(out cfLrs); bez.PowerCoeff(out cfBez); VecD norm = lrs.DirNorm; VecD tang = lrs.DirTang; double[] roots; int numRootBez; Equation.RootsReal(cfBez[2].Dot(norm), cfBez[1].Dot(norm), (cfBez[0] - cfLrs[0]).Dot(norm), out numRootBez, out roots); if (numRootBez == Equation.NumRootInfinite) { // bezier is irreducable,=> only D0 intersections are possible throw new ExceptionGMath("Intersect", "AuxIntersectBL(bez,lrs)", null); //return false; } for (int iRoot = 0; iRoot < numRootBez; iRoot++) { Param parBez = roots[iRoot]; if (bez.IsEvaluableStrict(parBez)) { Param parLrs = Equation.Evaluate(parBez.Val, cfBez[2].Dot(tang), cfBez[1].Dot(tang), (cfBez[0] - cfLrs[0]).Dot(tang)) / (cfLrs[1].Dot(tang)); if (lrs.IsEvaluableStrict(parLrs)) { IntersD0 inters = new IntersD0(parBez, parLrs, 0.5 * (lrs.Evaluate(parLrs.Val) + bez.Evaluate(parBez.Val)), false); linters.Add(inters); } } } return(true); }
/* knot0=this; knot1=(Knot *)(knot0->next); knot2=(Knot *)(knot1->next); on0=knot0->on; on1=knot1->on; on2=knot2->on; if ((!on0)&&(on1)) return false; if (icToNext) icToNext->From(true,false); curve.type=eGeomUndef; knotStartNext=knot1; if (on1) { if (on0) { curve.seg.From(knot0->x,knot0->y,knot1->x,knot1->y,false); curve.type=eGeomSeg; } else { if (icToNext) icToNext->Connect(false); } } else // 1 - off curve knot { curve.type=eGeomBez; VecD cp0, cp1, cp2; if (on0) { cp0.From(knot0->x,knot0->y,false); } else { cp0.From(0.5*(knot0->x+knot1->x),0.5*(knot0->y+knot1->y)); } cp1.From(knot1->x,knot1->y,false); if (on2) { knotStartNext=knot2; cp2.From(knot2->x,knot2->y,false); } else { if (icToNext) icToNext->Tangent(true); cp2.From(0.5*(knot1->x+knot2->x),0.5*(knot1->y+knot2->y)); } curve.bez.From(cp0,cp1,cp2); } if (getNextNonDegen) { CurveD curveAux; Knot *knotCurAux, *knotNextAux; if (!knotStartNext->GetCurve(curveAux, knotNextAux)) return false; if (!curveAux.IsPnt()) return true; icToNext->Tangent(false); while (curveAux.IsPnt()) { knotCurAux=knotNextAux; if (knotCurAux==knotStartNext) return false; // no non-degenerated curves... if (!knotCurAux->GetCurve(curveAux, knotNextAux)) return false; } knotStartNext=knotCurAux; } return true; } */ public Knot KnotNearest(VecD vecLocation) { double distMin=MConsts.Infinity; Knot knotNearest=null; foreach (Knot knot in this.knots) { double distCur=vecLocation.Dist(knot.Val); if (distCur<distMin) { distMin=distCur; knotNearest=knot; } } return knotNearest; }
internal void ClearRelease() { this.shift = null; this.trOTF2Dot14 = null; this.trD = null; }
public void PowerCoeff(out VecD[] pcf) { pcf=new VecD[3]; pcf[2]=this.cp[0]-2*this.cp[1]+this.cp[2]; pcf[1]=2*(this.cp[1]-this.cp[0]); pcf[0]=this.cp[0]; }
public Knot KnotNearest(VecD vecLocation) { double distMin=MConsts.Infinity; Knot knotNearest=null; foreach (Contour cont in this.conts) { Knot knotNearestCur=cont.KnotNearest(vecLocation); if (knotNearestCur!=null) { double distCur=vecLocation.Dist(knotNearestCur.Val); if (distCur<distMin) { distMin=distCur; knotNearest=knotNearestCur; } } } return knotNearest; }
/* * METHODS */ override public void ClearRelease() { this.ipi.ClearRelease(); this.ipi = null; this.pntInters = null; }
/* * 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 void CleanEndPointBezSI(VecD pnt, int pozStart) { for (int poz=pozStart; poz<this.linters.Count; poz++) { IntersD0 intersD0=linters[poz] as IntersD0; if (intersD0!=null) { bool toDelete=(intersD0.PntInters==pnt); if (toDelete) { this.linters.RemoveAt(poz); poz--; } } } }