refactor TileClipper
- fix: TileClipper check len<6 before len==0
This commit is contained in:
parent
d263089c06
commit
d6b95c936a
@ -55,7 +55,6 @@ public class TileClipper {
|
||||
if (geom.isPoly()) {
|
||||
|
||||
GeometryBuffer out = mGeomOut;
|
||||
|
||||
out.clear();
|
||||
|
||||
clipEdge(geom, out, LineClipper.LEFT);
|
||||
@ -102,26 +101,39 @@ public class TileClipper {
|
||||
|
||||
int pointPos = 0;
|
||||
|
||||
for (int i = 0, n = in.index.length; i < n; i++) {
|
||||
int len = in.index[i];
|
||||
for (int indexPos = 0, n = in.index.length; indexPos < n; indexPos++) {
|
||||
int len = in.index[indexPos];
|
||||
if (len < 0)
|
||||
break;
|
||||
|
||||
if (len < 6) {
|
||||
pointPos += len;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
out.startPolygon();
|
||||
outer = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len < 6) {
|
||||
pointPos += len;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!outer)
|
||||
out.startHole();
|
||||
|
||||
clipRing(i, pointPos, in, out, edge);
|
||||
switch (edge) {
|
||||
case LineClipper.LEFT:
|
||||
clipRingLeft(indexPos, pointPos, in, out);
|
||||
break;
|
||||
case LineClipper.RIGHT:
|
||||
clipRingRight(indexPos, pointPos, in, out);
|
||||
break;
|
||||
case LineClipper.TOP:
|
||||
clipRingTop(indexPos, pointPos, in, out);
|
||||
break;
|
||||
case LineClipper.BOTTOM:
|
||||
clipRingBottom(indexPos, pointPos, in, out);
|
||||
break;
|
||||
}
|
||||
|
||||
//if (out.index[i] < 6) {
|
||||
// out.index[i] = 0;
|
||||
@ -134,10 +146,116 @@ public class TileClipper {
|
||||
|
||||
outer = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void clipRingLeft(int indexPos, int pointPos, GeometryBuffer in, GeometryBuffer out) {
|
||||
int end = in.index[indexPos] + pointPos;
|
||||
float px = in.points[end - 2];
|
||||
float py = in.points[end - 1];
|
||||
|
||||
for (int i = pointPos; i < end;) {
|
||||
float cx = in.points[i++];
|
||||
float cy = in.points[i++];
|
||||
if (cx > minX) {
|
||||
/* current is inside */
|
||||
if (px > minX) {
|
||||
/* previous was inside */
|
||||
out.addPoint(cx, cy);
|
||||
} else {
|
||||
/* previous was outside, add edge point */
|
||||
out.addPoint(minX, py + (cy - py) * (minX - px) / (cx - px));
|
||||
out.addPoint(cx, cy);
|
||||
}
|
||||
} else {
|
||||
if (px > minX) {
|
||||
/* previous was inside, add edge point */
|
||||
out.addPoint(minX, py + (cy - py) * (minX - px) / (cx - px));
|
||||
}
|
||||
/* else skip point */
|
||||
}
|
||||
px = cx;
|
||||
py = cy;
|
||||
}
|
||||
}
|
||||
|
||||
private void clipRingRight(int indexPos, int pointPos, GeometryBuffer in, GeometryBuffer out) {
|
||||
int len = in.index[indexPos] + pointPos;
|
||||
float px = in.points[len - 2];
|
||||
float py = in.points[len - 1];
|
||||
|
||||
for (int i = pointPos; i < len;) {
|
||||
float cx = in.points[i++];
|
||||
float cy = in.points[i++];
|
||||
|
||||
if (cx < maxX) {
|
||||
if (px < maxX) {
|
||||
out.addPoint(cx, cy);
|
||||
} else {
|
||||
out.addPoint(maxX, py + (cy - py) * (maxX - px) / (cx - px));
|
||||
out.addPoint(cx, cy);
|
||||
}
|
||||
} else {
|
||||
if (px < maxX) {
|
||||
out.addPoint(maxX, py + (cy - py) * (maxX - px) / (cx - px));
|
||||
}
|
||||
}
|
||||
px = cx;
|
||||
py = cy;
|
||||
}
|
||||
}
|
||||
|
||||
private void clipRingTop(int indexPos, int pointPos, GeometryBuffer in, GeometryBuffer out) {
|
||||
int len = in.index[indexPos] + pointPos;
|
||||
float px = in.points[len - 2];
|
||||
float py = in.points[len - 1];
|
||||
|
||||
for (int i = pointPos; i < len;) {
|
||||
float cx = in.points[i++];
|
||||
float cy = in.points[i++];
|
||||
|
||||
if (cy < maxY) {
|
||||
if (py < maxY) {
|
||||
out.addPoint(cx, cy);
|
||||
} else {
|
||||
out.addPoint(px + (cx - px) * (maxY - py) / (cy - py), maxY);
|
||||
out.addPoint(cx, cy);
|
||||
}
|
||||
} else {
|
||||
if (py < maxY) {
|
||||
out.addPoint(px + (cx - px) * (maxY - py) / (cy - py), maxY);
|
||||
}
|
||||
}
|
||||
px = cx;
|
||||
py = cy;
|
||||
}
|
||||
}
|
||||
|
||||
private void clipRingBottom(int indexPos, int pointPos, GeometryBuffer in, GeometryBuffer out) {
|
||||
int len = in.index[indexPos] + pointPos;
|
||||
float px = in.points[len - 2];
|
||||
float py = in.points[len - 1];
|
||||
|
||||
for (int i = pointPos; i < len;) {
|
||||
float cx = in.points[i++];
|
||||
float cy = in.points[i++];
|
||||
if (cy > minY) {
|
||||
if (py > minY) {
|
||||
out.addPoint(cx, cy);
|
||||
} else {
|
||||
out.addPoint(px + (cx - px) * (minY - py) / (cy - py), minY);
|
||||
out.addPoint(cx, cy);
|
||||
}
|
||||
} else {
|
||||
if (py > minY) {
|
||||
out.addPoint(px + (cx - px) * (minY - py) / (cy - py), minY);
|
||||
}
|
||||
}
|
||||
px = cx;
|
||||
py = cy;
|
||||
}
|
||||
}
|
||||
|
||||
private int clipLine(GeometryBuffer in, GeometryBuffer out) {
|
||||
|
||||
int pointPos = 0;
|
||||
@ -209,92 +327,4 @@ public class TileClipper {
|
||||
|
||||
return numLines;
|
||||
}
|
||||
|
||||
private boolean clipRing(int indexPos, int pointPos, GeometryBuffer in, GeometryBuffer out,
|
||||
int edge) {
|
||||
|
||||
int len = in.index[indexPos];
|
||||
if (len < 6)
|
||||
return false;
|
||||
|
||||
len += pointPos;
|
||||
|
||||
float px = in.points[len - 2];
|
||||
float py = in.points[len - 1];
|
||||
|
||||
for (int i = pointPos; i < len;) {
|
||||
float cx = in.points[i++];
|
||||
float cy = in.points[i++];
|
||||
|
||||
switch (edge) {
|
||||
case LineClipper.LEFT:
|
||||
if (cx > minX) {
|
||||
// current is inside
|
||||
if (px > minX) {
|
||||
// previous was inside
|
||||
out.addPoint(cx, cy);
|
||||
} else {
|
||||
// previous was outside, add edge point
|
||||
out.addPoint(minX, py + (cy - py) * (minX - px) / (cx - px));
|
||||
out.addPoint(cx, cy);
|
||||
}
|
||||
} else {
|
||||
if (px > minX) {
|
||||
// previous was inside, add edge point
|
||||
out.addPoint(minX, py + (cy - py) * (minX - px) / (cx - px));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LineClipper.RIGHT:
|
||||
if (cx < maxX) {
|
||||
if (px < maxX) {
|
||||
out.addPoint(cx, cy);
|
||||
} else {
|
||||
out.addPoint(maxX, py + (cy - py) * (maxX - px) / (cx - px));
|
||||
out.addPoint(cx, cy);
|
||||
}
|
||||
} else {
|
||||
if (px < maxX) {
|
||||
out.addPoint(maxX, py + (cy - py) * (maxX - px) / (cx - px));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LineClipper.BOTTOM:
|
||||
if (cy > minY) {
|
||||
if (py > minY) {
|
||||
out.addPoint(cx, cy);
|
||||
} else {
|
||||
out.addPoint(px + (cx - px) * (minY - py) / (cy - py), minY);
|
||||
out.addPoint(cx, cy);
|
||||
}
|
||||
} else {
|
||||
if (py > minY) {
|
||||
out.addPoint(px + (cx - px) * (minY - py) / (cy - py), minY);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LineClipper.TOP:
|
||||
if (cy < maxY) {
|
||||
if (py < maxY) {
|
||||
out.addPoint(cx, cy);
|
||||
} else {
|
||||
out.addPoint(px + (cx - px) * (maxY - py) / (cy - py), maxY);
|
||||
out.addPoint(cx, cy);
|
||||
}
|
||||
} else {
|
||||
if (py < maxY) {
|
||||
out.addPoint(px + (cx - px) * (maxY - py) / (cy - py), maxY);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
px = cx;
|
||||
py = cy;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user