//Zkontroluje prubeh zaobleni // return 0 = OK // 1 bit = je mimo prvni usecku // 2 bit = je mimo druhou usecku // 3 bit = body jsou na jedne primce public static int TestRounding(Point pt1, Point pt2, Point pt3, double r) { int ret = 0; double a = Vector.AngleBetween(pt2.Minus(pt1), pt3.Minus(pt2)); if (a > 0) { r = -r; } // vypocitam prusecik offsetovanych primek Point[] p1 = Funcs2D.LineOffset(pt1, pt2, a); if (p1 == null) { ret |= 1; } Point[] p2 = Funcs2D.LineOffset(pt2, pt3, a); if (p2 == null) { ret |= 2; } if (ret != 0) { return(ret); } if (!TwoLine2D.CrossRel(p1[0], p1[1], p2[0], p2[1], out Point rr)) { return(4); } if (!TwoLine2D.TestRelOnLine(TwoLine2D.CrossStatus.And, rr.X)) { ret |= 1; } if (!TwoLine2D.TestRelOnLine(TwoLine2D.CrossStatus.And, rr.Y)) { ret |= 2; } return(ret); }
private Object[] f_MakeCross() { Object[] ret = new Object[2]; List <Point> retPt = new List <Point>(); List <int> retInx = new List <int>(); Point[] bln = null, eln; // ofsetovane usecky int b, m, e, len; if (IsClosed) { b = mySrc.Length - 1; m = 0; len = mySrc.Length; } else { b = 0; m = 1; len = mySrc.Length - 1; } for (; m < len; m++) { e = m + 1; if (e == mySrc.Length) { e = 0; } // test totoznych bodu if (Funcs2D.IsEqual(mySrc[b].Pt, mySrc[m].Pt, Funcs2D.Epson)) { b = m; continue; // vynecham } // test tri body na jedne primce if (Funcs2D.IsThreePointsOnLine(mySrc[b].Pt, mySrc[m].Pt, mySrc[e].Pt, Funcs2D.Epson)) { b = m; continue; // vynecham } //vypocitam offsety if (bln == null) { bln = Funcs2D.LineOffset(mySrc[b].Pt, mySrc[m].Pt, mySrc[b].Offset); } eln = Funcs2D.LineOffset(mySrc[m].Pt, mySrc[e].Pt, mySrc[m].Offset); if (!IsClosed && b == 0) { retPt.Add(bln[0]); retInx.Add(0); } // prusecik TwoLine2D.CrossAbs(bln[0], bln[1], eln[0], eln[1], TwoLine2D.CrossStatus.Infinite, out Point rpt); retPt.Add(rpt); retInx.Add(m); if (!IsClosed && e == len) { retPt.Add(eln[1]); retInx.Add(len); } b = m; bln = eln; } if (len == 1) { bln = Funcs2D.LineOffset(mySrc[b].Pt, mySrc[m].Pt, mySrc[b].Offset); retPt.Add(bln[0]); retInx.Add(0); retPt.Add(bln[1]); retInx.Add(1); } ret[0] = retPt; ret[1] = retInx; return(ret); }
/// <summary> /// oblouk tvoreny dvema po sobe jdoucimi useckami a polomerem /// takzvane zaobleni rohu /// pokud je polomer zaporny vytvori se tzv. vykousnuti se stredem ve spolecnem bode /// objekt se nastavi na empty pokud jsou usecky rovnobezne nebo jedna z nich ma nulovou delku /// </summary> /// <param name="pt1">pocatecni bod prvni ridici usecky</param> /// <param name="pt2">spolecny bod ridicich usecek</param> /// <param name="pt3">konecny bod druhe ridici usecky</param> /// <param name="radius">polomer zaobleni, zaporny polomer provede vykousnuti</param> /// <param name="testPt">pokud se pocatecni nebo koncovy bod vypocita mimo usecku, objekt se nastavi na Empty</param> public Arc2D(Point pt1, Point pt2, Point pt3, double radius, bool testPt = false) { // zjistim smer offsetu double a = Vector.AngleBetween(pt2.Minus(pt1), pt3.Minus(pt2)); if (a > 0) { a = -Math.Abs(radius); Clockwise = false; } else { a = Math.Abs(radius); Clockwise = true; } // vypocitam prusecik offsetovanych primek Point[] p1 = Funcs2D.LineOffset(pt1, pt2, a); Point[] p2 = Funcs2D.LineOffset(pt2, pt3, a); if (p1 == null || p2 == null || !TwoLine2D.CrossRel(p1[0], p1[1], p2[0], p2[1], out Point rr)) { // tri body na jedne primce Begin = pt1; End = pt3; Radius = 0; return; } if (radius > 0) { if (testPt) { if (!TwoLine2D.TestRelOnLine(TwoLine2D.CrossStatus.And, rr.X) || !TwoLine2D.TestRelOnLine(TwoLine2D.CrossStatus.And, rr.Y)) { // body jsou mimo usecky Begin = pt1; End = pt3; Radius = 0; return; } } // koeficienty prenesu do puvodnich usecek a spocitam body Begin = Funcs2D.PointOnLine(pt1, pt2, rr.X); End = Funcs2D.PointOnLine(pt2, pt3, rr.Y); Radius = radius; } else { Radius = -radius; if (testPt) { if (Funcs2D.Distance(pt1, pt2) < Radius || Funcs2D.Distance(pt2, pt3) < Radius) { // body jsou mimo usecky Begin = pt1; End = pt3; Radius = 0; return; } } // bod na prvni primce ve vzdalenosti abs(radius) od spolecneho bodu Begin = Funcs2D.PointOnLineLen(pt2, pt1, Radius); // bod na druhe primce End = Funcs2D.PointOnLineLen(pt2, pt3, Radius); Clockwise = !Clockwise; } }