static void DoMemoryTest() { int i = 0; try { Point_dt p1 = new Point_dt(1, 1); Point_dt p3 = new Point_dt(1, 0); Point_dt p2 = new Point_dt(0, 0); List<Triangle_dt> vec = new List<Triangle_dt>(); while (true) { Triangle_dt t = new Triangle_dt(p1, p2, p3); vec.Add(t); i++; if (i % 10000 == 0) Console.WriteLine(i); } } catch (OutOfMemoryException oome) { Console.WriteLine("out of MEMORY: points: " + i); } catch (Exception e) { Console.WriteLine("out of MEMORY: points: " + i); } }
/** * creates a half plane using the segment (A,B). * @param A * @param B */ public Triangle_dt(Point_dt A, Point_dt B) { // visitflag=visitValue; a = A; b = B; halfplane = true; // _id = _counter++; }
/** * creates a Delaunay Triangulation from all the points. Note: duplicated * points are ignored. */ public Delaunay_Triangulation(Point_dt[] ps) { _modCount = 0; _modCount2 = 0; _bb_min = null; _bb_max = null; this._vertices = new TreeSet<Point_dt>(Point_dt.getComparator()); _triangles = new List<Triangle_dt>(); allCollinear = true; for (int i = 0; ps != null && i < ps.Length && ps[i] != null; i++) { this.insertPoint(ps[i]); } // build grid points to make find faster gridPoints = new PointsGridDT(5, this); }
public MainForm(Delaunay_Triangulation aj) { this.Text = "ajDelaunay GUI tester"; this.Size = new Size(550, 550); _stage = 0; _ajd = aj; _dx_f = new Point_dt(5, this.Width - 5); _dy_f = new Point_dt(5, this.Height - 5); _dx_map = new Point_dt(aj.maxBoundingBox().x, aj.minBoundingBox().x); _dy_map = new Point_dt(aj.maxBoundingBox().y, aj.minBoundingBox().y); _clients = null; _guards = null; //addWindowListener(new WindowAdapter() { // public void windowClosing(WindowEvent e) { // System.exit(0); // } //}); }
static void DoTimeTest() { int size = 100000, size2 = size; double delta = 1000, delta2 = delta / 2; double[] xx = new double[size], yy = new double[size]; Point_dt[] ps = new Point_dt[size]; double[] xx2 = new double[size2], yy2 = new double[size2]; DateTime start = DateTime.Now; Delaunay_Triangulation ad = new Delaunay_Triangulation(); Random r = new Random(); for (int i = 0; i < size; i++) { xx[i] = (r.NextDouble() * delta - (delta * 0.1)); yy[i] = (r.NextDouble() * delta - (delta * 0.1)); ps[i] = new Point_dt(xx[i], yy[i]); ad.insertPoint(ps[i]); } DateTime mid = DateTime.Now; for (int i = 0; i < size2; i++) { xx2[i] = (r.NextDouble() * delta2); yy2[i] = (r.NextDouble() * delta2); } DateTime m1 = DateTime.Now; for (int i = 0; i < size2; i++) { Point_dt p = new Point_dt(xx2[i], yy2[i]); Triangle_dt t1 = ad.find(p); if (!t1.contains(p)) { Console.WriteLine(i + ") **ERR: find *** T: " + t1); } } DateTime e1 = DateTime.Now; Console.WriteLine("delaunay_triangulation " + ad.size() + " points, " + ad.trianglesSize() + " triangles, Triangles_td: " + Triangle_dt._counter + " ,c2: " + Triangle_dt._c2); Console.WriteLine("Constructing time: " + (mid - start).TotalSeconds); Console.WriteLine("*** E3 find: time: " + (e1 - m1).TotalSeconds); Console.WriteLine("delaunay_triangulation " + ad.size() + " points, " + ad.trianglesSize() + " triangles, Triangles_td: " + Triangle_dt._counter + " ,c2: " + Triangle_dt._c2); }
// *** text area *** public MainForm() { InitializeComponent(); this.Text = "Delaunay GUI tester"; this.Size = new Size(500, 500); this.BackColor = Color.White; _stage = 0; _ajd = new Delaunay_Triangulation(); _ajd.PotentialBbMax = new Point_dt(this.Width, this.Height); _dx_f = new Point_dt(10, this.Width - 10); _dy_f = new Point_dt(55, this.Height - 10); _dx_map = new Point_dt(_dx_f); _dy_map = new Point_dt(_dy_f); //addWindowListener(new WindowAdapter() { // public void windowClosing(WindowEvent e) { // System.exit(0); // } //}); }
/** * this method checke if there is a Line Of Site between p1 and p2, note the * z value of the points is the Hieght ABOVE ground!! * * @param p1 * "guard", * @param p2 * "client" * @return true iff both points are valid (not null && inside the * triangulation) */ public bool los(Point_dt p1, Point_dt p2) { bool ans = true; if (_dt == null) throw new Exception( "** ERR: null pointer triangulation (LOS) **"); if (p1 == null || p2 == null) throw new Exception("** ERR: null pointer points (LOS) **"); if (!_dt.contains(p1.x, p1.y)) throw new Exception("** ERR: p1:" + p1 + " is NOT contained in the triangulation **"); if (!_dt.contains(p2.x, p2.y)) throw new Exception("** ERR: p2:" + p2 + " is NOT contained in the triangulation **"); this.computeSection(p1, p2); ans = this.isVisible(p1.z, p2.z); this.computeSection(p2, p1); ans = ans && this.isVisible(p2.z, p1.z); printSection(p1, p2); return ans; }
internal void computeSection(Point_dt p1, Point_dt p2) { Triangle_dt t1 = _dt.find(p1); Triangle_dt t2 = _dt.find(p2); _p1 = t1.z(p1); _p2 = t2.z(p2); if (_tr == null) _tr = new List<Triangle_dt>(); else _tr.Clear(); if (_section == null) _section = new List<Point_dt>(); else _section.Clear(); Triangle_dt curr_t = t1; while (curr_t != t2 && curr_t != null) { _tr.Add(curr_t); cut(curr_t); curr_t = next_t(p1, p2, curr_t, _tr); } _tr.Add(t2); }
//public int _id; /** constructs a triangle form 3 point - store it in counterclockwised order.*/ public Triangle_dt(Point_dt A, Point_dt B, Point_dt C) { //visitflag=visitValue; a = A; int res = C.pointLineTest(A,B); if ( (res <= Point_dt.LEFT) || (res == Point_dt.INFRONTOFA) || (res == Point_dt.BEHINDB) ) { b = B; c = C; } else { // RIGHT Console.WriteLine("Warning, ajTriangle(A,B,C) "+ "expects points in counterclockwise order."); Console.WriteLine("" + A + B + C); b=C; c=B; } circumcircle(); //_id = _counter++; //_counter++;_c2++; //if(_counter%10000 ==0) System.out.println("Triangle: "+_counter); }
private Triangle_dt treatDegeneracyInside(Triangle_dt t, Point_dt p) { if (t.abnext.halfplane && p.pointLineTest(t.b, t.a) == Point_dt.ONSEGMENT) return extendOutside(t.abnext, p); if (t.bcnext.halfplane && p.pointLineTest(t.c, t.b) == Point_dt.ONSEGMENT) return extendOutside(t.bcnext, p); if (t.canext.halfplane && p.pointLineTest(t.a, t.c) == Point_dt.ONSEGMENT) return extendOutside(t.canext, p); return null; }
private Triangle_dt insertPointSimple(Point_dt p) { nPoints++; if (!allCollinear) { Triangle_dt t = find(startTriangle, p); if (t.halfplane) startTriangle = extendOutside(t, p); else startTriangle = extendInside(t, p); return startTriangle; } if (nPoints == 1) { firstP = p; return null; } if (nPoints == 2) { startTriangulation(firstP, p); return null; } switch (p.pointLineTest(firstP, lastP)) { case Point_dt.LEFT: startTriangle = extendOutside(firstT.abnext, p); allCollinear = false; break; case Point_dt.RIGHT: startTriangle = extendOutside(firstT, p); allCollinear = false; break; case Point_dt.ONSEGMENT: insertCollinear(p, Point_dt.ONSEGMENT); break; case Point_dt.INFRONTOFA: insertCollinear(p, Point_dt.INFRONTOFA); break; case Point_dt.BEHINDB: insertCollinear(p, Point_dt.BEHINDB); break; } return null; }
private Triangle_dt extendOutside(Triangle_dt t, Point_dt p) { if (p.pointLineTest(t.a, t.b) == Point_dt.ONSEGMENT) { Triangle_dt dg = new Triangle_dt(t.a, t.b, p); Triangle_dt hp = new Triangle_dt(p, t.b); t.b = p; dg.abnext = t.abnext; dg.abnext.switchneighbors(t, dg); dg.bcnext = hp; hp.abnext = dg; dg.canext = t; t.abnext = dg; hp.bcnext = t.bcnext; hp.bcnext.canext = hp; hp.canext = t; t.bcnext = hp; return dg; } Triangle_dt ccT = extendcounterclock(t, p); Triangle_dt cT = extendclock(t, p); ccT.bcnext = cT; cT.canext = ccT; startTriangleHull = cT; return cT.abnext; }
private Triangle_dt extendcounterclock(Triangle_dt t, Point_dt p) { t.halfplane = false; t.c = p; t.circumcircle(); Triangle_dt tca = t.canext; if (p.pointLineTest(tca.a, tca.b) >= Point_dt.RIGHT) { Triangle_dt nT = new Triangle_dt(t.a, p); nT.abnext = t; t.canext = nT; nT.canext = tca; tca.bcnext = nT; return nT; } return extendcounterclock(tca, p); }
private static Point_dt[] read_tsin(string tsinFile) { Point_dt[] ans = null; using (StreamReader fr = new StreamReader(tsinFile)) { String s = fr.ReadLine(); while (s[0] == '/') s = fr.ReadLine(); int numOfVer = int.Parse(s); ans = new Point_dt[numOfVer]; // ** reading the file verteces - insert them to the triangulation ** for (int i = 0; i < numOfVer; i++) { s = fr.ReadLine(); string[] t = s.Split(' '); double d1 = double.Parse(t[0]); double d2 = double.Parse(t[1]); double d3 = double.Parse(t[2]); ans[i] = new Point_dt((int)d1, (int)d2, d3); } } return ans; }
///** // * this method write the triangulation as an SMF file (OFF like format) // * // * // * @param smfFile // * - file name // * @throws Exception // */ public void write_smf(String smfFile) { int len = this._vertices.Count; Point_dt[] ans = new Point_dt[len]; Point_dt[] it = this._vertices.ToArray(); IComparer<Point_dt> comp = Point_dt.getComparator(); for (int i = 0; i < len; i++) { ans[i] = it[i]; } Array.Sort(ans, comp); using (StreamWriter fw = new StreamWriter(smfFile)) { // prints the tsin file header: fw.WriteLine("begin"); for (int i = 0; i < len; i++) { fw.WriteLine("v " + ans[i].toFile()); } int t = 0, i1 = -1, i2 = -1, i3 = -1; foreach (Triangle_dt curr in this.trianglesIterator()) { if (!curr.halfplane) { i1 = Array.BinarySearch(ans, curr.a, comp); i2 = Array.BinarySearch(ans, curr.b, comp); i3 = Array.BinarySearch(ans, curr.c, comp); if (i1 < 0 || i2 < 0 || i3 < 0) throw new Exception("wrong triangulation inner bug - cant write as an SMF file!"); fw.WriteLine("f " + (i1 + 1) + " " + (i2 + 1) + " " + (i3 + 1)); } } fw.WriteLine("end"); fw.Close(); } }
/** * * @param x * - X cordination of the query point * @param y * - Y cordination of the query point * @return the q point with updated Z value (z value is as given the * triangulation). */ public double z(double x, double y) { Point_dt q = new Point_dt(x, y); Triangle_dt t = find(q); return t.z_value(q); }
private double fz(Point_dt p1, Point_dt p2, double x) { return(mz(p1, p2) * x + kz(p1, p2)); }
private double k(Point_dt p1, Point_dt p2) { double k = p1.y - m(p1, p2) * p1.x; return(k); }
public void GivenIHaveAPointWithCoordinates(double p0, double p1) { point = new Point_dt(p0, p1); }
private double f(Point_dt p1, Point_dt p2, double x) { return(m(p1, p2) * x + k(p1, p2)); }
/** * insert the point to this Delaunay Triangulation. Note: if p is null or * already exist in this triangulation p is ignored. * * @param p * new vertex to be inserted the triangulation. */ public void insertPoint(Point_dt p) { if (this._vertices.Contains<Point_dt>(p)) return; _modCount++; updateBoundingBox(p); this._vertices.Add(p); Triangle_dt t = insertPointSimple(p); if (t == null) // return; Triangle_dt tt = t; currT = t; // recall the last point for - fast (last) update iterator. do { flip(tt, _modCount); tt = tt.canext; } while (tt != t && !tt.halfplane); }
/* * assumes v is NOT an halfplane! * returns the next triangle for find. */ private static Triangle_dt findnext1(Point_dt p, Triangle_dt v) { if (p.pointLineTest(v.a, v.b) == Point_dt.RIGHT && !v.abnext.halfplane) return v.abnext; if (p.pointLineTest(v.b, v.c) == Point_dt.RIGHT && !v.bcnext.halfplane) return v.bcnext; if (p.pointLineTest(v.c, v.a) == Point_dt.RIGHT && !v.canext.halfplane) return v.canext; if (p.pointLineTest(v.a, v.b) == Point_dt.RIGHT) return v.abnext; if (p.pointLineTest(v.b, v.c) == Point_dt.RIGHT) return v.bcnext; if (p.pointLineTest(v.c, v.a) == Point_dt.RIGHT) return v.canext; return null; }
/** * * @param q * Query point * @return the q point with updated Z value (z value is as given the * triangulation). */ public Point_dt z(Point_dt q) { Triangle_dt t = find(q); return t.z(q); }
private static Point_dt[] read_smf(string smfFile, double dx, double dy, double dz, double minX, double minY, double minZ) { StreamReader fr = new StreamReader(smfFile); string s = fr.ReadLine(); while (s[0] != 'v') s = fr.ReadLine(); List<Point_dt> vec = new List<Point_dt>(); Point_dt[] ans = null; // while (s != null && s[0] == 'v') { string[] t = s.Split(' '); double d1 = double.Parse(t[1]) * dx + minX; double d2 = double.Parse(t[2]) * dy + minY; double d3 = double.Parse(t[3]) * dz + minZ; vec.Add(new Point_dt((int)d1, (int)d2, d3)); s = fr.ReadLine(); } ans = new Point_dt[vec.Count]; for (int i = 0; i < vec.Count; i++) ans[i] = (Point_dt)vec.ElementAt(i); return ans; }
private static Triangle_dt find(Triangle_dt curr, Point_dt p) { if (p == null) return null; Triangle_dt next_t; if (curr.halfplane) { next_t = findnext2(p, curr); if (next_t == null || next_t.halfplane) return curr; curr = next_t; } while (true) { next_t = findnext1(p, curr); if (next_t == null) return curr; if (next_t.halfplane) return next_t; curr = next_t; } }
public void drawTriangle(Graphics g, Triangle_dt t, Color cl) { if (_view_flag == VIEW1 || t.isHalfplane()) { if (t.isHalfplane()) { if (cl == Color.Empty) { drawLine(g, t.p1(), t.p2(), Color.Blue); } else { drawLine(g, t.p1(), t.p2(), cl); } } else { if (cl == Color.Empty) { drawLine(g, t.p1(), t.p2(), Color.Black); drawLine(g, t.p2(), t.p3(), Color.Black); drawLine(g, t.p3(), t.p1(), Color.Black); } { drawLine(g, t.p1(), t.p2(), cl); drawLine(g, t.p2(), t.p3(), cl); drawLine(g, t.p3(), t.p1(), cl); } } } else { // ////////////////////////////////////////////////////////////////// double maxZ = _ajd.maxBoundingBox().z; double minZ = _ajd.minBoundingBox().z; double z = (t.p1().z + t.p2().z + t.p3().z) / 3.0; double dz = maxZ - minZ; if (dz == 0) { dz = 1; } int co = 30 + (int)(220 * ((z - minZ) / dz)); if (cl == Color.Empty) { cl = Color.FromArgb(co, co, co); } int[] xx = new int[3], yy = new int[3]; // double f = 0; // double dx_map = _dx_map.y- _dx_map.x; // double dy_map = _dy_map.y- _dy_map.x; // f = (t.p1().x -_dx_map.x)/dx_map; Point_dt p1 = world2screen(t.p1()); xx[0] = (int)p1.x; yy[0] = (int)p1.y; Point_dt p2 = world2screen(t.p2()); xx[1] = (int)p2.x; yy[1] = (int)p2.y; Point_dt p3 = world2screen(t.p3()); xx[2] = (int)p3.x; yy[2] = (int)p3.y; Brush b = new SolidBrush(cl); g.FillPolygon(b, ToPoints(xx, yy)); // //////////////////////////////////// } }
/** assumes v is an halfplane! - returns another (none halfplane) triangle */ private static Triangle_dt findnext2(Point_dt p, Triangle_dt v) { if (v.abnext != null && !v.abnext.halfplane) return v.abnext; if (v.bcnext != null && !v.bcnext.halfplane) return v.bcnext; if (v.canext != null && !v.canext.halfplane) return v.canext; return null; }
public void drawPoint(Graphics g, Point_dt p1, Color cl) { drawPoint(g, p1, 4, cl); }
void MainForm_Click(object sender, MouseEventArgs e) { int xx = e.X; int yy = e.Y; switch (_stage) { case 0: { Console.WriteLine("[" + xx + "," + yy + "]"); break; } case POINT: { Point_dt q = new Point_dt(xx, yy); Point_dt p = screen2world(q); _ajd.insertPoint(p); Refresh(); break; } case FIND: { Point_dt q = new Point_dt(xx, yy); Point_dt p = screen2world(q); //_t1 = _ajd.find(p); _t1 = _ajd.FastFind(p); Refresh(); break; } case SECTION1: { Point_dt q = new Point_dt(xx, yy); _p1 = screen2world(q); // _p1 = new Point_dt(99792.03,1073355.0,30.0); // _t1 = _ajd.find(_p1); _stage = SECTION2; break; } case SECTION2: { Point_dt q = new Point_dt(xx, yy); _p2 = screen2world(q); // _p2 = new Point_dt(149587.055,1040477.0,5.0); // _t2 = _ajd.find(_p2); _los = new Visibility(_ajd); _los.computeSection(_p1, _p2); Refresh(); _stage = SECTION1; break; } case GUARD: { Point_dt q = new Point_dt(xx, yy); _p1 = screen2world(q); if (_guards == null) { _guards = new List <Point_dt>(); } _guards.Add(new Point_dt(_p1.x, _p1.y, GH)); /* * if(_p2!=null) { _los = new Visibility(_ajd); * _los.computeSection(_p1,_p2); _visible = * _los.isVisible(30,5); } */ Refresh(); break; } case CLIENT: { Point_dt q = new Point_dt(xx, yy); _p2 = screen2world(q); if (_clients == null) { _clients = new List <Point_dt>(); } _clients.Add(new Point_dt(_p2.x, _p2.y, CH)); /* * if(_p1!=null) { _los = new Visibility(_ajd); * _los.computeSection(_p1,_p2); _visible = * _los.isVisible(30,5); } */ Refresh(); break; } } }
void MainMenuClick(object sender, EventArgs e) { MenuItem mi = sender as MenuItem; if (mi == null) { throw new Exception("MainMenuClick"); } string arg = mi.Text; if (arg.Equals("Open")) { openTextFile(); } else if (arg.Equals("Save tsin")) { saveTextFile(); } else if (arg.Equals("Save smf")) { saveTextFile2(); } else if (arg.Equals("Lines")) { this._view_flag = VIEW1; Refresh(); } else if (arg.Equals("Triangles")) { this._view_flag = VIEW2; Refresh(); } else if (arg.Equals("Topo")) { this._view_flag = VIEW3; Refresh(); } else if (arg.Equals("Clear")) { _ajd = new Delaunay_Triangulation(); _dx_map = new Point_dt(_dx_f); _dy_map = new Point_dt(_dy_f); _clients = null; _guards = null; _mc = 0; Refresh(); } else if (arg.Equals("Exit")) { Application.Exit(); } else if (arg.Equals("Point")) { _stage = POINT; } else if (arg.Equals("CH")) { _ajd.CH_vertices_Iterator(); } else if (arg.Equals("100-rand-ps")) { Random r = new Random(); double x0 = 10, y0 = 60, dx = this.Width - x0 - 10, dy = this.Height - y0 - 10; for (int i = 0; i < 100; i++) { double x = r.NextDouble() * dx + x0; double y = r.NextDouble() * dy + y0; Point_dt q = new Point_dt(x, y); Point_dt p = screen2world(q); _ajd.insertPoint(p); } Refresh(); } else if (arg.Equals("Find")) { _stage = MainForm.FIND; } else if (arg.Equals("Section")) { _stage = MainForm.SECTION1; } else if (arg.Equals("Client-5m")) { // Console.WriteLine("CL!"); _stage = MainForm.CLIENT; } else if (arg.Equals("Guard-30m")) { _stage = MainForm.GUARD; } else if (arg.Equals("Info")) { string ans = "" + _ajd.GetType().FullName + " # vertices:" + _ajd.size() + " # triangles:" + _ajd.trianglesSize(); ans += " min BB:" + _ajd.minBoundingBox() + " max BB:" + _ajd.maxBoundingBox(); Console.WriteLine(ans); Console.WriteLine(); } }
private Triangle_dt extendclock(Triangle_dt t, Point_dt p) { t.halfplane = false; t.c = p; t.circumcircle(); Triangle_dt tbc = t.bcnext; if (p.pointLineTest(tbc.a, tbc.b) >= Point_dt.RIGHT) { Triangle_dt nT = new Triangle_dt(p, t.b); nT.abnext = t; t.bcnext = nT; nT.bcnext = tbc; tbc.canext = nT; return nT; } return extendclock(tbc, p); }
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; // _ajd.initTriangle(); // ajTriangle[] tt = _ajd._triangles; if (_ajd == null || _ajd.size() == 0) { return; } _dx_f = new Point_dt(5, this.Width - 5); _dy_f = new Point_dt(5, this.Height - 5); List <Triangle_dt> it = _ajd.trianglesIterator(); foreach (Triangle_dt curr in it) { if (!curr.isHalfplane()) { drawTriangle(g, curr, Color.Empty); } } it = _ajd.trianglesIterator(); foreach (Triangle_dt curr in it) { if (curr.isHalfplane()) { drawTriangle(g, curr, Color.Empty); } } if (_t2 != null) { drawTriangle(g, _t2, Color.Red); } if (_t1 != null && _stage == FIND) { drawTriangle(g, _t1, Color.YellowGreen); } if (this._view_flag == VIEW3) { drawTopo(g); } // debug if (_mc < _ajd.getModeCounter()) { _mc = _ajd.getModeCounter(); List <Triangle_dt> it2 = _ajd.getLastUpdatedTriangles(); for (int i = 0; i < it2.Count; i++) { drawTriangle(g, it2[i], Color.Cyan); } Console.WriteLine(" MC: " + _mc + " number of triangles updated: " + it2.Count); } if (_los != null && (_stage == SECTION1 || _stage == SECTION2)) { if (_los != null && _los._tr != null) { foreach (Triangle_dt curr in _los._tr) { if (!curr.isHalfplane()) { drawTriangle(g, curr, Color.Red); } } } for (int i = 0; i < _los._section.Count; i++) { Point_dt curr_p = _los._section[i]; if (curr_p != null) { drawPoint(g, curr_p, Color.Blue); Console.WriteLine(i + ") " + curr_p + " dist _p1: " + _p1.distance(curr_p)); } } drawLine(g, _p1, _p2, Color.Blue); } /* * if(_stage == GUARD | _stage == CLIENT) { if(_p1!=null) * drawPoint(g,_p1,6,Color.ORANGE); if(_p2!=null) { if(_visible) * drawPoint(g,_p2,6,Color.BLUE); else drawPoint(g,_p2,6, Color.RED); } * } */ if (_los == null) { _los = new Visibility(_ajd); } if (_stage == GUARD || _stage == CLIENT) { int[] ccc = new int[0]; if (_clients != null) { ccc = new int[_clients.Count]; } for (int gr = 0; _guards != null && gr < _guards.Count; gr++) { Point_dt gg = _guards.ElementAt(gr); drawPoint(g, gg, 8, Color.Orange); for (int c = 0; _clients != null && c < _clients.Count; c++) { Point_dt cc = _clients.ElementAt(c); drawPoint(g, cc, 6, Color.White); // Color cl = Color.RED; if (_los.los(gg, cc)) { this.drawLine(g, gg, cc, Color.Red); ccc[c]++; } } } int c1 = 0, c2 = 0, c3 = 0; for (int i = 0; i < ccc.Length; i++) { if (ccc[i] > 0) { c1++; c2 += ccc[i]; } } if (c1 > 0) { Console.WriteLine("clients:" + ccc.Length + " visible c:" + c1 + " ave:" + c2 / c1); } } }
private Triangle_dt extendInside(Triangle_dt t, Point_dt p) { Triangle_dt h1, h2; h1 = treatDegeneracyInside(t, p); if (h1 != null) return h1; h1 = new Triangle_dt(t.c, t.a, p); h2 = new Triangle_dt(t.b, t.c, p); t.c = p; t.circumcircle(); h1.abnext = t.canext; h1.bcnext = t; h1.canext = h2; h2.abnext = t.bcnext; h2.bcnext = h1; h2.canext = t; h1.abnext.switchneighbors(t, h1); h2.abnext.switchneighbors(t, h2); t.bcnext = h2; t.canext = h1; return t; }
public Triangle_dt FastFind(Point_dt p) { return find(gridPoints.FindClosestTriangle(p), p); }
private void insertCollinear(Point_dt p, int res) { Triangle_dt t, tp, u; switch (res) { case Point_dt.INFRONTOFA: t = new Triangle_dt(firstP, p); tp = new Triangle_dt(p, firstP); t.abnext = tp; tp.abnext = t; t.bcnext = tp; tp.canext = t; t.canext = firstT; firstT.bcnext = t; tp.bcnext = firstT.abnext; firstT.abnext.canext = tp; firstT = t; firstP = p; break; case Point_dt.BEHINDB: t = new Triangle_dt(p, lastP); tp = new Triangle_dt(lastP, p); t.abnext = tp; tp.abnext = t; t.bcnext = lastT; lastT.canext = t; t.canext = tp; tp.bcnext = t; tp.canext = lastT.abnext; lastT.abnext.bcnext = tp; lastT = t; lastP = p; break; case Point_dt.ONSEGMENT: u = firstT; while (p.isGreater(u.a)) u = u.canext; t = new Triangle_dt(p, u.b); tp = new Triangle_dt(u.b, p); u.b = p; u.abnext.a = p; t.abnext = tp; tp.abnext = t; t.bcnext = u.bcnext; u.bcnext.canext = t; t.canext = u; u.bcnext = t; tp.canext = u.abnext.canext; u.abnext.canext.bcnext = tp; tp.bcnext = u.abnext; u.abnext.canext = tp; if (firstT == u) { firstT = t; } break; } }
/** * finds the triangle the query point falls in, note if out-side of this * triangulation a half plane triangle will be returned (see contains), the * search has expected time of O(n^0.5), and it starts form a fixed triangle * (this.startTriangle), * * @param p * query point * @return the triangle that point p is in. */ public Triangle_dt find(Point_dt p) { return find(this.startTriangle, p); }
private void startTriangulation(Point_dt p1, Point_dt p2) { Point_dt ps, pb; if (p1.isLess(p2)) { ps = p1; pb = p2; } else { ps = p2; pb = p1; } firstT = new Triangle_dt(pb, ps); lastT = firstT; Triangle_dt t = new Triangle_dt(ps, pb); firstT.abnext = t; t.abnext = firstT; firstT.bcnext = t; t.canext = firstT; firstT.canext = t; t.bcnext = firstT; firstP = firstT.b; lastP = lastT.a; startTriangleHull = firstT; }
/** * finds the triangle the query point falls in, note if out-side of this * triangulation a half plane triangle will be returned (see contains). the * search starts from the the start triangle * * @param p * query point * @param start * the triangle the search starts at. * @return the triangle that point p is in.. */ public Triangle_dt find(Point_dt p, Triangle_dt start) { if (start == null) start = this.startTriangle; Triangle_dt T = find(start, p); return T; }
private void updateBoundingBox(Point_dt p) { double x = p.x, y = p.y, z = p.z; if (_bb_min == null) { _bb_min = new Point_dt(p); _bb_max = new Point_dt(p); } else { if (x < _bb_min.x) _bb_min.x = x; else if (x > _bb_max.x) _bb_max.x = x; if (y < _bb_min.y) _bb_min.y = y; else if (y > _bb_max.y) _bb_max.y = y; if (z < _bb_min.z) _bb_min.z = z; else if (z > _bb_max.z) _bb_max.z = z; } }
private double kz(Point_dt p1, Point_dt p2) { double k = p1.z - mz(p1, p2) * p1.x; return(k); }