public bool TestCrossing(MyLine src, double[,] p) { if (myEnd == src.myBegin) { return(false); } if (myBegin == src.myEnd) { return(false); } if (!TwoLine2D.CrossRel(new Point(p[myBegin, 0], p[myBegin, 1]), new Point(p[myEnd, 0], p[myEnd, 1]), new Point(p[src.myBegin, 0], p[src.myBegin, 1]), new Point(p[src.myEnd, 0], p[src.myEnd, 1]), out Point t)) { return(false); } if (!TwoLine2D.TestRelOnLine(TwoLine2D.CrossStatus.And, t.X)) { return(false); } if (!TwoLine2D.TestRelOnLine(TwoLine2D.CrossStatus.And, t.Y)) { return(false); } if (Funcs2D.IsEqual(t.X, 0, Funcs2D.Epson) || Funcs2D.IsEqual(t.Y, 0, Funcs2D.Epson)) { return(false); // prusecik je na zacatku usecky, nezapisu } f_AddCross(t.X, src.myBegin); src.f_AddCross(t.Y, myBegin); return(true); }
public static double[] AnglesCrossLine(Point centre, double r, Point pt1, Point pt2) { Point t = Funcs2D.PointToLine(pt1, pt2, centre); if (Funcs2D.IsEqual(t, centre)) { double an = Funcs2D.LineAngle(pt1, pt2); return(new double[] { Funcs2D.PureRadianAngle(an + Math.PI), an }); } double z = Funcs2D.Distance(centre, t); double a = Funcs2D.LineAngle(centre, t); if (z.IsGreater(r)) { return(null); // mimo } if (z.IsEqual(r)) // tecna { return(new double[] { a }); } //secna double aa = Math.Acos(z / r); // uhel pulky tetivy return(new double[] { Funcs2D.PureRadianAngle(a + aa), Funcs2D.PureRadianAngle(a - aa) }); }
//rekurze pro jeden polygon private void f_GetOnePolygonSplit() { List <Point> rpt = new List <Point>(); List <int> rptInx = new List <int>(); int start = -1; if (myPTR.inxLn != -1) { if (!Funcs2D.IsEqual(myPTR.kRel, 1, Funcs2D.Epson)) // zapisu bod pokud neni prusecik na konci usecky { rpt.Add(myPTR.pPt); rptInx.Add(myPTR.inxLn); } start = myPTR.inxLn; } while (f_NextPTR()) // najdu dalsi bod { if (myPTR.IsCrossing && myPTR.inxCrLn == start) { break; // uzavrela se moje smycka } if (myPTR.IsCrossing) { f_GetOnePolygonSplit(); // jdu dovnitr dalsi smycky } if (!Funcs2D.IsEqual(myPTR.kRel, 1, Funcs2D.Epson)) // zapisu bod pokud neni prusecik na konci usecky { rpt.Add(myPTR.pPt); // zapisu bod rptInx.Add(myPTR.inxLn); } } mySplits.Add(rpt); myInxSplits.Add(rptInx); }
public static IPolygonReader[] PolygonsInterconnect(IPolygonReader[] polygons, Point pt, Vector v) { IPolygonReader[] ret = null; List <Tuple <double, int, int> > cr = new List <Tuple <double, int, int> >(); bool[] bcr = new bool[polygons.Length]; Point ptt = new Point(); Vector norm = Funcs2D.VectorNormal(v); for (int i = 0; i < polygons.Length; i++) { for (int j = 0; j < polygons[i].Length; j++) { polygons[i].GetRow(j, out double x, out double y); ptt.X = x; ptt.Y = y; if (TwoLine2D.CrossRel(pt, v, ptt, norm, out Point pr)) { if (Funcs2D.IsEqual(pr.Y, 0.0, Funcs2D.Epson)) { cr.Add(new Tuple <double, int, int>(pr.X, i, j)); bcr[i] = true; } } } } if (cr.Count < 2) { return(null); } int k = 1; foreach (var b in bcr) { if (!b) { k++; } } ret = new IPolygonReader[k]; k = 0; for (int i = 0; i < bcr.Length; i++) { if (!bcr[i]) { ret[k++] = polygons[i]; } } // trideni cr.Sort((a, b) => a.Item1.CompareTo(b.Item1)); List <Point> rpt = new List <Point>(); f_InterconnectJoin(0, cr, polygons, rpt); ret[k] = new BoxListPoint(Funcs2D.PolygonPure(new BoxListPoint(rpt), true)); return(ret); }
/// <summary> /// vytvori oblouk zadany dvema body a polomerem /// </summary> /// <param name="begin">pocatecni bod</param> /// <param name="end">koncovy bod</param> /// <param name="radius">polomer, + = kratky oblouk , - = dlouhy oblouk</param> /// <param name="clockwise">smer</param> public Arc2D(Point begin, Point end, double radius, bool clockwise) { Begin = begin; End = end; if (Funcs2D.IsEqual(begin, end)) { Radius = 0; } else { Radius = radius; } Clockwise = clockwise; }
// zjisti zda jsou usecky korektne zadane, nemaji nulovou delku public int IsNotCorrectLine() { Line2D l = new Line2D(myPoint[0], myPoint[1]); if (Funcs2D.IsEqual(l.Length, 0, Funcs2D.Epson)) { return(1); } l.Begin = myPoint[2]; l.End = myPoint[3]; if (Funcs2D.IsEqual(l.Length, 0, Funcs2D.Epson)) { return(2); } return(0); }
public static bool CrossRel(Point pta, Vector da, //bod a vektor prvni primky Point ptb, Vector db, //bod a vektor druhe primky out Point retRel) // vraci relativni souradnice { double t; retRel = new Point(); t = (da.X * db.Y) - (da.Y * db.X); if (Funcs2D.IsEqual(t, 0.0, Funcs2D.Epson)) { return(false); } retRel.X = ((ptb.X * db.Y) - (ptb.Y * db.X) - (pta.X * db.Y) + (pta.Y * db.X)) / t; retRel.Y = ((pta.X * da.Y) - (pta.Y * da.X) - (ptb.X * da.Y) + (ptb.Y * da.X)) / ((db.X * da.Y) - (db.Y * da.X)); return(true); }
private static bool testRelEndPt(CrossStatus st, double t) { switch (st) { case CrossStatus.Infinite: break; case CrossStatus.And: if (!(t < 1 || Funcs2D.IsEqual(t, 1.0, Funcs2D.Epson))) { return(false); } break; case CrossStatus.Not: if (Funcs2D.IsEqual(t, 1.0, Funcs2D.Epson)) { return(false); } if (!(t < 1)) { return(false); } break; } return(true); }
public static bool IsNull(Vector v, double limit) // testuje nulovy vektor , s povolenou odchylkou 'limit' { return(IsEqual(v.X, 0, limit) && Funcs2D.IsEqual(v.Y, 0, limit)); }
public static bool IsEqual(Vector v1, Vector v2, double limit) // testuje rovnost dvou vektoru , s povolenou odchylkou 'limit' { return(IsEqual(v1.X, v2.X, limit) && Funcs2D.IsEqual(v1.Y, v2.Y, limit)); }
public static bool IsEqual(Point pt1, Point pt2, double limit) // testuje rovnost dvou bodu , s povolenou odchylkou 'limit' { return(IsEqual(pt1.X, pt2.X, limit) && Funcs2D.IsEqual(pt1.Y, pt2.Y, limit)); }
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> /// vytvori polygon delenim oblouku /// </summary> /// <param name="koef">predpis pro deleni /// keof vetsi nez 0 - uhlovy segment v radianech /// koef mensi nebo rovno 0 - absolutni hodnota urcuje pocet dilu na ktere se segment rozdeli /// </param> /// <param name="withoutBegin">urcuje zda ma vratit pole bez prvniho bodu</param> /// <returns>Vrati pole bodu, pokud je oblouk empty vrati null </returns> public Point[] Discretization(double koef, bool withoutBegin) { Circle2D?c = GetAngles(out double start, out double angle); Point[] ret = null; if (c.HasValue) { if (koef > 0) { var l = new List <Point>(); if (!withoutBegin) { l.Add(Begin); } double d = 0; if (angle < 0) { koef = -koef; for (d = koef; d >= angle; d += koef) { l.Add(c.Value.PointOn(start + d)); } } else { for (d = koef; d <= angle; d += koef) { l.Add(c.Value.PointOn(start + d)); } } if (Funcs2D.IsEqual(angle, d)) { //Bugfix #14454 if (l.Count != 0) { l[l.Count - 1] = End; } else { l.Add(End); } } ret = l.ToArray(); } else { int num = (int)Math.Abs(koef); if (num != 0) { int i = 1; if (withoutBegin) { i = 0; } ret = new Point[num + i]; if (!withoutBegin) { ret[0] = Begin; } angle /= num; for (double d = angle; i < num; i++, d += angle) { ret[i] = c.Value.PointOn(start + d); } } } } return(ret); }
private static bool f_PolygonPure(Point[] pt, bool closed, double limit, ref List <int> ret) { if (pt.Length < 2) { if (ret != null) { ret = new List <int>() { 0 } } ; return(false); } int b, m, e, len; if (closed) { // budu zmensovat delku tak dlouho dokud nebude prvni, posledni a predposledni bod na jedne primce for (len = pt.Length; len > 2; len--) { if (!Funcs2D.IsThreePointsOnLine(pt[0], pt[len - 1], pt[len - 2], limit)) { break; } else { if (ret == null) { return(false); // testovani } } } // jeste otestuji s poslednim a druhym if (!Funcs2D.IsThreePointsOnLine(pt[len - 1], pt[0], pt[1], limit)) { if (ret != null) { ret.Add(0); } } else if (ret == null) { return(false); // testovani } } else { // budu zmensovat delku tak dlouho dokud nebude prvni a posledni bod stejny // musim zajistit aby byl polygon skutecne otevreny for (len = pt.Length; len > 1; len--) { if (!Funcs2D.IsEqual(pt[0], pt[len - 1], limit)) { break; } else { if (ret == null) { return(false); // testovani } } } if (ret != null) { ret.Add(0); } } // skoncim u predposledniho bodu len--; // zapisu prvni bod bool saved = true; for (b = 0, m = 1, e = 2; m < len; e++) { if (Funcs2D.IsThreePointsOnLine(pt[b], pt[m], pt[e], limit)) { if (ret == null) { return(false); // testovani } if (m > b + 1) { if (!Funcs2D.IsThreePointsOnLine(pt[b], pt[b + 1], pt[e], limit)) { if (ret != null) { ret.Add(b + 1); } saved = false; b = b + 1; m = b + 1; e = m; continue; } } saved = false; m = e; continue; // vynecham } if (ret != null) { ret.Add(m); } saved = true; b = m; m = e; } // zapisu posledni if (saved) { if (ret != null) { ret.Add(len); // rovnou zapisu pokud predposledni bod prosel kontrolou } } else { //zapisu pouze pokud posledni a predposledni neni shodny if (!Funcs2D.IsEqual(pt[len - 1], pt[len], limit)) { if (ret != null) { ret.Add(len); } } } return(true); }
public bool IsEqual(Direction pt, double eps) { return(Funcs2D.IsEqual(pt.myVc, myVc, eps)); }