/// <summary> /// kruznice urcena tremi body na obvodu /// </summary> /// <param name="pt1">prvni bod</param> /// <param name="pt2">druhy bod</param> /// <param name="pt3">treti bod</param> public Circle2D(Point pt1, Point pt2, Point pt3) { Radius = 0; Center = pt1; Point[] p = new Point[2]; Vector[] v = new Vector[2]; p[0].X = (pt1.X + pt2.X) / 2; p[0].Y = (pt1.Y + pt2.Y) / 2; p[1].X = (pt2.X + pt3.X) / 2; p[1].Y = (pt2.Y + pt3.Y) / 2; v[0].X = pt2.Y - pt1.Y; v[0].Y = -(pt2.X - pt1.X); v[1].X = pt3.Y - pt2.Y; v[1].Y = -(pt3.X - pt2.X); TwoLine2D.CrossStatus st = TwoLine2D.CrossStatus.Infinite; if (TwoLine2D.CrossAbs(p[0], st, v[0], st, p[1], st, v[1], st, out Center)) { Radius = Funcs2D.Distance(pt1, Center); } }
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); }
//vypocita kolmy prumet bodu na usecce , vysledek je relativni souradnice usecky public static double PointToLine(Point pt1, Vector v, Point pk) { Vector vn = Funcs2D.VectorNormal(v); TwoLine2D.CrossRel(pt1, v, pk, vn, out Point ret); return(ret.X); }
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); }
//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); }
// vrati relativni souradnice pruseciku primky s polygonem public static List <double> PolygonLineCrossingRel(IPolygonReader poly, bool closed, Point pt, Vector v) { if (poly == null) { throw (new ArgumentNullException("PolygonLineCrossing_rel(poly,..)")); } List <double> ret = new List <double>(); int b, e; double[,] p = poly.CopyTo(); if (closed) { e = poly.Length - 1; b = 0; } else { e = 0; b = 1; } Point p1, p2; for (int i = b; i < poly.Length; i++) { b = e; e = i; p1 = new Point(p[b, 0], p[b, 1]); p2 = new Point(p[e, 0], p[e, 1]); if (TwoLine2D.CrossRel(pt, v, p1, p2.Minus(p1), out Point pr)) { if (TwoLine2D.TestRelOnLine(TwoLine2D.CrossStatus.And, pr.Y)) { ret.Add(pr.X); } } } ret.Sort(); 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; } }