From: <adr...@us...> - 2009-12-30 17:30:12
|
Revision: 3410 http://reprap.svn.sourceforge.net/reprap/?rev=3410&view=rev Author: adrian-bowyer Date: 2009-12-30 17:29:42 +0000 (Wed, 30 Dec 2009) Log Message: ----------- Outline finder now experimentally using the boolean grid. Modified Paths: -------------- trunk/reprap/host/src/org/reprap/geometry/LayerProducer.java trunk/reprap/host/src/org/reprap/geometry/polygons/BooleanGrid.java Modified: trunk/reprap/host/src/org/reprap/geometry/LayerProducer.java =================================================================== --- trunk/reprap/host/src/org/reprap/geometry/LayerProducer.java 2009-12-30 00:37:41 UTC (rev 3409) +++ trunk/reprap/host/src/org/reprap/geometry/LayerProducer.java 2009-12-30 17:29:42 UTC (rev 3410) @@ -284,15 +284,15 @@ } else { RrCSGPolygonList offBorder = csgP.offset(layerConditions, true); - offBorder.divide(Preferences.tiny(), 1.01); - borderPolygons = offBorder.megList(); -// BooleanGrid bg; -// borderPolygons = new RrPolygonList(); -// for(int i = 0; i < offBorder.size(); i++) -// { -// bg = new BooleanGrid(offBorder.get(i).csg()); -// borderPolygons.add(bg.allPerimiters(offBorder.get(i).getAttributes())); -// } +// offBorder.divide(Preferences.tiny(), 1.01); +// borderPolygons = offBorder.megList(); + BooleanGrid bg; + borderPolygons = new RrPolygonList(); + for(int i = 0; i < offBorder.size(); i++) + { + bg = new BooleanGrid(offBorder.get(i).csg()); + borderPolygons.add(bg.allPerimiters(offBorder.get(i).getAttributes())); + } } offHatch.divide(Preferences.tiny(), 1.01); Modified: trunk/reprap/host/src/org/reprap/geometry/polygons/BooleanGrid.java =================================================================== --- trunk/reprap/host/src/org/reprap/geometry/polygons/BooleanGrid.java 2009-12-30 00:37:41 UTC (rev 3409) +++ trunk/reprap/host/src/org/reprap/geometry/polygons/BooleanGrid.java 2009-12-30 17:29:42 UTC (rev 3410) @@ -59,6 +59,12 @@ y = ya; } + iPoint(iPoint a) + { + x = a.x; + y = a.y; + } + Rr2Point realPoint() { return new Rr2Point(x*xInc, y*yInc); @@ -74,6 +80,16 @@ return new iPoint(x + b.x, y + b.y); } + iPoint sub(iPoint b) + { + return new iPoint(x - b.x, y - b.y); + } + + iPoint abs() + { + return new iPoint(Math.abs(x), Math.abs(y)); + } + iPoint divide(int i) { return new iPoint(x/i, y/i); @@ -90,13 +106,20 @@ } } + /** + * Integer-point polygon + * @author ensab + * + */ class iPolygon { private List<iPoint> points = null; + private boolean closed; - public iPolygon() + public iPolygon(boolean c) { points = new ArrayList<iPoint>(); + closed = c; } public iPolygon(iPolygon a) @@ -104,6 +127,7 @@ points = new ArrayList<iPoint>(); for(int i = 0; i < a.size(); i++) add(a.point(i)); + closed = a.closed; } public iPoint point(int i) @@ -121,52 +145,86 @@ points.add(p); } - private int nextX(int i, int x) + private int findAngleStart(int v1) { - i++; - while(i < size()) + int leng = size(); + iPoint p1 = point(v1%leng); + int v2 = v1; + for(int i = 0; i <= leng; i++) { - if(x != point(i).x) - return i; - i++; + v2++; + DDA line = new DDA(p1, point(v2%leng)); + iPoint n = line.next(); + boolean off = false; + int j = v1; + while(n != null) + { + if(point(j%leng).coincidesWith(n)) + { + off = false; + } else + { + if(off) + { + if(v2 - 2 >= 0) + return v2 - 2; + return leng - 1; + } + off = true; + } + n = line.next(); + j++; + } } - return size(); + System.err.println("iPolygon.findAngleStart(): polygon is all one straight line!"); + return -1; } - private int nextY(int i, int y) + public iPolygon simplify() { - i++; - while(i < size()) + int leng = size(); + if(leng <= 3) + return new iPolygon(this); + iPolygon r = new iPolygon(closed); + + int v1 = findAngleStart(0); + // We get back -1 if the points are in a straight line. + if (v1<0) { - if(y != point(i).y) - return i; - i++; + r.add(point(0)); + r.add(point(leng-1)); + return r; } - return size(); - } - - public iPolygon rightFilter() - { - if(size() < 3) - return new iPolygon(this); - iPolygon result = new iPolygon(); - - int last = 0; - int nextx, nexty; - while(last < size()) + if(!closed) + r.add(point(0)); + + r.add(point(v1%leng)); + int v2 = v1; + while(true) { - result.add(point(last)); - nextx = nextX(last, point(last).x); - nexty = nextY(last, point(last).y); - if(nexty > nextx) - last = nexty - 1; - else - last = nextx - 1; + // We get back -1 if the points are in a straight line. + v2 = findAngleStart(v2); + if(v2<0) + { + System.err.println("iPolygon.simplify(): points were not in a straight line; now they are!"); + return(r); + } + + if(v2 > leng || (!closed && v2 == leng)) + { + return(r); + } + + if(v2 == leng && closed) + { + r.points.add(0, point(0)); + return r; + } + r.add(point(v2%leng)); } - - - return result; + // The compiler is very clever to spot that no return + // is needed here... } public RrPolygon realPolygon(Attributes a, boolean closed) @@ -178,6 +236,81 @@ } } + /** + * Straight-line DDA + * @author ensab + * + */ + class DDA + { + private iPoint delta, count, p; + private int steps, taken; + private boolean xPlus, yPlus, finished; + + /** + * Set up the DDA between a start and an end point + * @param s + * @param e + */ + DDA(iPoint s, iPoint e) + { + delta = e.sub(s).abs(); + + steps = Math.max(delta.x, delta.y); + taken = 0; + + xPlus = e.x >= s.x; + yPlus = e.y >= s.y; + + count = new iPoint(-steps/2, -steps/2); + + p = new iPoint(s); + + finished = false; + } + + /** + * Return the next point along the line, or null + * if the last point returned was the final one. + * @return + */ + iPoint next() + { + if(finished) + return null; + + iPoint result = new iPoint(p); + + finished = taken >= steps; + + if(!finished) + { + taken++; + count = count.add(delta); + + if (count.x > 0) + { + count.x -= steps; + if (xPlus) + p.x++; + else + p.x--; + } + + if (count.y > 0) + { + count.y -= steps; + if (yPlus) + p.y++; + else + p.y--; + } + } + + return result; + } + } + //************************************************************************************************** // Constructors and administration @@ -791,26 +924,26 @@ public RrPolygonList allPerimiters(Attributes a) { RrPolygonList result = new RrPolygonList(); - RrPolygon p; + iPolygon ip; iPoint pixel = findUnvisitedEdgePixel(); while(pixel != null) { - p = new RrPolygon(a, true); + ip = new iPolygon(true); while(pixel != null) { - p.add(pixel.realPoint()); + ip.add(pixel); setVisited(pixel, true); pixel = findUnvisitedNeighbourOnEdge(pixel); } - System.err.print("Polygon before size: " + p.size()); - p = p.simplify(0.5*(xInc + yInc)); - System.err.println(", polygon after size: " + p.size()); - if(p.size() >= 3) - result.add(p); + //System.err.print("Polygon before size: " + ip.size()); + ip = ip.simplify(); + //System.err.println(", polygon after size: " + ip.size()); + if(ip.size() >= 3) + result.add(ip.realPolygon(a, true)); pixel = findUnvisitedEdgePixel(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |