// test for bounding box function public static void bbox_test(GeoCollection g) { // draw a triangle Point p1 = new Point(0.1, 0.1, 0); Point p2 = new Point(0.8, 0.3, 0); Point p3 = new Point(0.2, 0.6, 0); Line l1 = new Line(p1, p2); Line l2 = new Line(p1, p3); Line l3 = new Line(p3, p2); g.add(l1); g.add(l2); g.add(l3); // create triangle and calculate bounding box Tri t = new Tri(p1, p2, p3); t.calc_bbox(); Point a = new Point(t.bb.minx, t.bb.miny, 0); Point b = new Point(t.bb.maxx, t.bb.miny, 0); Point c = new Point(t.bb.maxx, t.bb.maxy, 0); Point d = new Point(t.bb.minx, t.bb.maxy, 0); Line h1 = new Line(a, b); Line h2 = new Line(b, c); Line h3 = new Line(c, d); Line h4 = new Line(d, a); g.add(h1); g.add(h2); g.add(h3); g.add(h4); }
public static bool isinside(Tri t, Point p) { // point in triangle test // returns true if the xy projection of point p is inside // the xy projection of triangle t // a new Tri projected onto the xy plane: Point p1 = new Point(t.p[0].x, t.p[0].y, 0); Point p2 = new Point(t.p[1].x, t.p[1].y, 0); Point p3 = new Point(t.p[2].x, t.p[2].y, 0); Point pt = new Point(p.x, p.y, 0); bool b1 = isright(p1, p2, pt); bool b2 = isright(p3, p1, pt); bool b3 = isright(p2, p3, pt); if ((b1) && (b2) && (b3)) { return true; } else if ((!b1) && (!b2) && (!b3)) { return true; } else { return false; } } // end isinside()
public void AddTriangle(Tri t) { // add one triangle to the surface tris.Add(t); // need to re-generate gldata when new triangle added: // this is required if we want to update the rendered triangles // in real-time as triangles are added //gengldata(); // but disabling it makes large STL files load much faster }
// isinside unit test public static void isinside_test(GeoCollection g) { Random r = new Random(); // generate lots of random points int N = 100; List <Point> points = new List <Point>(); for (int n = 0; n < N; n++) { Point p = new Point(0.001 * (float)r.Next(0, 1000), 0.001 * (float)r.Next(0, 1000), 0); points.Add(p); } // draw a triangle Point p1 = new Point(0.1, 0.1, 0); Point p2 = new Point(0.8, 0.1, 0); Point p3 = new Point(0.2, 0.6, 0); Line l1 = new Line(p1, p2); Line l2 = new Line(p1, p3); Line l3 = new Line(p3, p2); g.add(l1); g.add(l2); g.add(l3); // p.color = System.Drawing.Color.Aqua; // draw points Tri t = new Tri(p2, p3, p1); foreach (Point p in points) { /* * if (DropCutter.isinside(t,p.p)) * p.color = System.Drawing.Color.Aqua; * else * p.color = System.Drawing.Color.Red; */ g.add(p); } }
// isinside unit test public static void isinside_test(GeoCollection g) { Random r = new Random(); // generate lots of random points int N = 100; List<Point> points = new List<Point>(); for (int n = 0; n < N; n++) { Point p = new Point(0.001 * (float)r.Next(0, 1000), 0.001 * (float)r.Next(0, 1000), 0); points.Add(p); } // draw a triangle Point p1 = new Point(0.1, 0.1, 0); Point p2 = new Point(0.8, 0.1, 0); Point p3 = new Point(0.2, 0.6, 0); Line l1 = new Line(p1, p2); Line l2 = new Line(p1, p3); Line l3 = new Line(p3, p2); g.add(l1); g.add(l2); g.add(l3); // p.color = System.Drawing.Color.Aqua; // draw points Tri t = new Tri(p2, p3, p1); foreach (Point p in points) { /* if (DropCutter.isinside(t,p.p)) p.color = System.Drawing.Color.Aqua; else p.color = System.Drawing.Color.Red; */ g.add(p); } }
public static bool isinside(Tri t, Point p) { // point in triangle test // returns true if the xy projection of point p is inside // the xy projection of triangle t // a new Tri projected onto the xy plane: Point p1 = new Point(t.p[0].x, t.p[0].y, 0); Point p2 = new Point(t.p[1].x, t.p[1].y, 0); Point p3 = new Point(t.p[2].x, t.p[2].y, 0); Point pt = new Point(p.x, p.y, 0); bool b1 = isright(p1, p2, pt); bool b2 = isright(p3, p1, pt); bool b3 = isright(p2, p3, pt); if ((b1) && (b2) && (b3)) { return true; } else if ((!b1) && (!b2) && (!b3)) { return true; } else { return false; } }
public static double? FacetTest(Cutter cu, Point e, Tri t) { // local copy of the surface normal t.recalc_normals(); // don't trust the pre-calculated normal! calculate it separately here. Vector n = new Vector(t.n.x, t.n.y, t.n.z); Point cc; if (n.z == 0) { // vertical plane, can't touch cutter against that! return null; } else if (n.z < 0) { // flip the normal so it points up (? is this always required?) n = -1*n; } // define plane containing facet double a = n.x; double b = n.y; double c = n.z; double d = - n.x * t.p[0].x - n.y * t.p[0].y - n.z * t.p[0].z; // the z-direction normal is a special case (?required?) // in debug phase, see if this is a useful case! if ((a == 0) && (b == 0)) { // System.Console.WriteLine("facet-test:z-dir normal case!"); e.z = t.p[0].z; cc = new Point(e.x,e.y,e.z); if (isinside(t, cc)) { // System.Console.WriteLine("facet-test:z-dir normal case!, returning {0}",e.z); // System.Console.ReadKey(); return e.z; } else return null; } // System.Console.WriteLine("facet-test:general case!"); // facet test general case // uses trigonometry, so might be too slow? // flat endmill and ballnose should be simple to do without trig // toroidal case might require offset-ellipse idea? /* theta = asin(c); zf= -d/c - (a*xe+b*ye)/c+ (R-r)/tan(theta) + r/sin(theta) -r; e=[xe ye zf]; u=[0 0 1]; rc=e + ((R-r)*tan(theta)+r)*u - ((R-r)/cos(theta) + r)*n; t=isinside(p1,p2,p3,rc); */ double theta = Math.Asin(c); double zf = -d/c - (a*e.x+b*e.y)/c + (cu.R-cu.r)/Math.Tan(theta) + cu.r/Math.Sin(theta) - cu.r; Vector ve = new Vector(e.x,e.y,zf); Vector u = new Vector(0,0,1); Vector rc = new Vector(); rc = ve +((cu.R-cu.r)*Math.Tan(theta)+cu.r)*u - ((cu.R-cu.r)/Math.Cos(theta)+cu.r)*n; /* if (rc.z > 1000) System.Console.WriteLine("z>1000 !"); */ cc = new Point(rc.x, rc.y, rc.z); // check that CC lies in plane: // a*rc(1)+b*rc(2)+c*rc(3)+d double test = a * cc.x + b * cc.y + c * cc.z + d; if (test > 0.000001) System.Console.WriteLine("FacetTest ERROR! CC point not in plane"); if (isinside(t, cc)) { if (Math.Abs(zf) > 100) { System.Console.WriteLine("serious problem... at" +e.x + "," + e.y); } return zf; } else return null; }
} // end VertexTest public static double? FacetTest(Cutter cu, Point e, Tri t) { // local copy of the surface normal t.recalc_normals(); // don't trust the pre-calculated normal! calculate it separately here. Vector n = new Vector(t.n.x, t.n.y, t.n.z); Point cc; if (n.z == 0) { // vertical plane, can't touch cutter against that! return null; } else if (n.z < 0) { // flip the normal so it points up (? is this always required?) n = -1*n; } // define plane containing facet double a = n.x; double b = n.y; double c = n.z; double d = - n.x * t.p[0].x - n.y * t.p[0].y - n.z * t.p[0].z; // the z-direction normal is a special case (?required?) // in debug phase, see if this is a useful case! if ((a == 0) && (b == 0)) { // System.Console.WriteLine("facet-test:z-dir normal case!"); e.z = t.p[0].z; cc = new Point(e.x,e.y,e.z); if (isinside(t, cc)) { // System.Console.WriteLine("facet-test:z-dir normal case!, returning {0}",e.z); // System.Console.ReadKey(); return e.z; } else return null; } // System.Console.WriteLine("facet-test:general case!"); // facet test general case // uses trigonometry, so might be too slow? // flat endmill and ballnose should be simple to do without trig // toroidal case might require offset-ellipse idea? /* theta = asin(c); zf= -d/c - (a*xe+b*ye)/c+ (R-r)/tan(theta) + r/sin(theta) -r; e=[xe ye zf]; u=[0 0 1]; rc=e + ((R-r)*tan(theta)+r)*u - ((R-r)/cos(theta) + r)*n; t=isinside(p1,p2,p3,rc); */ double theta = Math.Asin(c); double zf = -d/c - (a*e.x+b*e.y)/c + (cu.R-cu.r)/Math.Tan(theta) + cu.r/Math.Sin(theta) - cu.r; Vector ve = new Vector(e.x,e.y,zf); Vector u = new Vector(0,0,1); Vector rc = new Vector(); rc = ve +((cu.R-cu.r)*Math.Tan(theta)+cu.r)*u - ((cu.R-cu.r)/Math.Cos(theta)+cu.r)*n; /* if (rc.z > 1000) System.Console.WriteLine("z>1000 !"); */ cc = new Point(rc.x, rc.y, rc.z); // check that CC lies in plane: // a*rc(1)+b*rc(2)+c*rc(3)+d double test = a * cc.x + b * cc.y + c * cc.z + d; if (test > 0.000001) System.Console.WriteLine("FacetTest ERROR! CC point not in plane"); if (isinside(t, cc)) { if (Math.Abs(zf) > 100) { System.Console.WriteLine("serious problem... at" +e.x + "," + e.y); } return zf; } else return null; } // end FacetTest
public void AddTriangle(Tri t) { // add one triangle to the surface tris.Add(t); }
public static STLSurf Load(System.IO.StreamReader fs) { STLSurf surf = new STLSurf(); int state = 0; int counter = 0; string[] data; Tri triangle = new Tri(); Vector normal = new Vector(); System.Globalization.CultureInfo locale = new System.Globalization.CultureInfo("en-GB"); int n_triangles=0; while ( !fs.EndOfStream ) { data = fs.ReadLine().TrimStart(' ').Split(' '); switch (state) { case 0: if (data[0].Equals("solid")) { state = 1; // continue readingx } break; case 1: if (data[0].Equals("facet")) { normal.x = double.Parse(data[2], locale); normal.y = double.Parse(data[3], locale); normal.z = double.Parse(data[4], locale); triangle = new Tri(normal); counter = 0; state = 2; } break; case 2: if (data[0].Equals("vertex")) { if ( counter <= 2 ) { triangle.p[counter].x = double.Parse(data[1], locale); triangle.p[counter].y = double.Parse(data[2], locale); triangle.p[counter].z = double.Parse(data[3], locale); // System.Console.WriteLine("STLReader: added point" + triangle.p[counter]); // System.Console.ReadKey(); counter++; } } else if (data[0].Equals("endfacet")) { if (counter == 3) { surf.AddTriangle(triangle); n_triangles += 1; } state = 1; } break; } } fs.Close(); System.Console.WriteLine("STLReader: read {0} triangles!",n_triangles); return (surf); }
static public STLSurf Load(System.IO.StreamReader fs) { STLSurf surf = new STLSurf(); int state = 0; int counter = 0; string[] data; Tri triangle = new Tri(); Vector normal = new Vector(); System.Globalization.CultureInfo locale = new System.Globalization.CultureInfo("en-GB"); int n_triangles = 0; while (!fs.EndOfStream) { data = fs.ReadLine().TrimStart(' ').Split(' '); switch (state) { case 0: if (data[0].Equals("solid")) { state = 1; // continue readingx } break; case 1: if (data[0].Equals("facet")) { normal.x = double.Parse(data[2], locale); normal.y = double.Parse(data[3], locale); normal.z = double.Parse(data[4], locale); triangle = new Tri(normal); counter = 0; state = 2; } break; case 2: if (data[0].Equals("vertex")) { if (counter <= 2) { triangle.p[counter].x = double.Parse(data[1], locale); triangle.p[counter].y = double.Parse(data[2], locale); triangle.p[counter].z = double.Parse(data[3], locale); // System.Console.WriteLine("STLReader: added point" + triangle.p[counter]); // System.Console.ReadKey(); counter++; } } else if (data[0].Equals("endfacet")) { if (counter == 3) { surf.AddTriangle(triangle); n_triangles += 1; } state = 1; } break; } } fs.Close(); System.Console.WriteLine("STLReader: read {0} triangles!", n_triangles); return(surf); }