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); }
/// <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; } }