add line-clipping to TileClipper

This commit is contained in:
Hannes Janetzek 2013-12-02 21:50:27 +01:00
parent 50ec62264e
commit 940a32668e

View File

@ -20,6 +20,7 @@ public class TileClipper {
this.minY = minY; this.minY = minY;
this.maxX = maxX; this.maxX = maxX;
this.maxY = maxY; this.maxY = maxY;
mLineClipper = new LineClipper((int) minX, (int) minY, (int) maxX, (int) maxY, true);
} }
public void setRect(float minX, float minY, float maxX, float maxY) { public void setRect(float minX, float minY, float maxX, float maxY) {
@ -27,29 +28,54 @@ public class TileClipper {
this.minY = minY; this.minY = minY;
this.maxX = maxX; this.maxX = maxX;
this.maxY = maxY; this.maxY = maxY;
mLineClipper = new LineClipper((int) minX, (int) minY, (int) maxX, (int) maxY, true);
} }
private LineClipper mLineClipper;
private final GeometryBuffer mGeomOut = new GeometryBuffer(10, 1); private final GeometryBuffer mGeomOut = new GeometryBuffer(10, 1);
public boolean clip(GeometryBuffer geom) { public boolean clip(GeometryBuffer geom) {
GeometryBuffer out = mGeomOut; if (geom.isPoly()) {
out.clear(); GeometryBuffer out = mGeomOut;
clipEdge(geom, out, LineClipper.LEFT); out.clear();
geom.clear();
clipEdge(out, geom, LineClipper.TOP); clipEdge(geom, out, LineClipper.LEFT);
out.clear(); geom.clear();
clipEdge(geom, out, LineClipper.RIGHT); clipEdge(out, geom, LineClipper.TOP);
geom.clear(); out.clear();
clipEdge(out, geom, LineClipper.BOTTOM); clipEdge(geom, out, LineClipper.RIGHT);
geom.clear();
if ((geom.indexPos == 0) && (geom.index[0] < 6)) clipEdge(out, geom, LineClipper.BOTTOM);
return false;
if ((geom.indexPos == 0) && (geom.index[0] < 6))
return false;
}
else if (geom.isLine()) {
GeometryBuffer out = mGeomOut;
out.clear();
int numLines = clipLine(geom, out);
short idx[] = geom.ensureIndexSize(numLines + 1, false);
System.arraycopy(out.index, 0, idx, 0, numLines);
geom.index[numLines] = -1;
float pts[] = geom.ensurePointSize(out.pointPos >> 1, false);
System.arraycopy(out.points, 0, pts, 0, out.pointPos);
geom.indexPos = out.indexPos;
geom.pointPos = out.pointPos;
if ((geom.indexPos == 0) && (geom.index[0] < 4))
return false;
}
return true; return true;
} }
@ -81,12 +107,12 @@ public class TileClipper {
clipRing(i, pointPos, in, out, edge); clipRing(i, pointPos, in, out, edge);
// if (out.index[i] < 6) { //if (out.index[i] < 6) {
// out.index[i] = 0; // out.index[i] = 0;
// //if (out.indexPos > 0) // //if (out.indexPos > 0)
// // out.indexPos--; // // out.indexPos--;
// // TODO if outer skip holes // // TODO if outer skip holes
// } //}
pointPos += len; pointPos += len;
@ -96,6 +122,78 @@ public class TileClipper {
return true; return true;
} }
private int clipLine(GeometryBuffer in, GeometryBuffer out) {
int pointPos = 0;
int numLines = 0;
for (int i = 0, n = in.index.length; i < n; i++) {
int len = in.index[i];
if (len < 0)
break;
if (len < 4) {
pointPos += len;
continue;
}
if (len == 0) {
continue;
}
int inPos = pointPos;
int end = inPos + len;
float prevX = in.points[inPos + 0];
float prevY = in.points[inPos + 1];
boolean inside = mLineClipper.clipStart(prevX, prevY);
if (inside) {
out.startLine();
out.addPoint(prevX, prevY);
numLines++;
}
for (inPos += 2; inPos < end; inPos += 2) {
// get the current way point coordinates
float curX = in.points[inPos];
float curY = in.points[inPos + 1];
int clip;
if ((clip = mLineClipper.clipNext(curX, curY)) != 0) {
//System.out.println(inside + " clip: " + clip + " "
// + Arrays.toString(mLineClipper.out));
if (clip < 0) {
if (inside) {
// previous was inside
out.addPoint(mLineClipper.out[2], mLineClipper.out[3]);
inside = false;
} else {
// previous was outside
out.startLine();
numLines++;
out.addPoint(mLineClipper.out[0], mLineClipper.out[1]);
out.addPoint(mLineClipper.out[2], mLineClipper.out[3]);
inside = mLineClipper.clipStart(curX, curY);
}
} else {
out.addPoint(curX, curY);
}
} else {
inside = false;
}
}
pointPos += len;
}
return numLines;
}
private boolean clipRing(int indexPos, int pointPos, GeometryBuffer in, GeometryBuffer out, private boolean clipRing(int indexPos, int pointPos, GeometryBuffer in, GeometryBuffer out,
int edge) { int edge) {
@ -183,26 +281,4 @@ public class TileClipper {
} }
return true; return true;
} }
// public static void main(String[] args) {
// TileClipper clipper = new TileClipper(0, 0, 100, 100);
// GeometryBuffer geom = new GeometryBuffer(10, 1);
//
// geom.startPolygon();
// geom.addPoint(-10, -10);
// geom.addPoint(110, -10);
// geom.addPoint(110, 110);
// geom.addPoint(-10, 110);
//
// geom.startHole();
// geom.addPoint(10, 10);
// geom.addPoint(110, 10);
// geom.addPoint(110, 90);
// geom.addPoint(10, 90);
//
// System.out.println("" + Arrays.toString(geom.points));
// clipper.clip(geom);
// System.out.println("" + Arrays.toString(geom.points) + " " + geom.index[0]);
//
// }
} }