improve text placement a little
This commit is contained in:
parent
70e6266319
commit
6a34e478f5
@ -179,7 +179,7 @@ public final class WayDecorator {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
double segmentLength = Math.sqrt(vx * vx + vy * vy);
|
float segmentLength = (float) Math.sqrt(vx * vx + vy * vy);
|
||||||
|
|
||||||
if (skipPixels > 0) {
|
if (skipPixels > 0) {
|
||||||
skipPixels -= segmentLength;
|
skipPixels -= segmentLength;
|
||||||
@ -202,9 +202,9 @@ public final class WayDecorator {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float s = wayNameWidth / (float) segmentLength;
|
float s = (wayNameWidth + 20) / segmentLength;
|
||||||
int width, height;
|
float width, height;
|
||||||
int x1, y1, x2, y2;
|
float x1, y1, x2, y2;
|
||||||
|
|
||||||
if (prevX < curX) {
|
if (prevX < curX) {
|
||||||
x1 = prevX;
|
x1 = prevX;
|
||||||
@ -219,13 +219,15 @@ public final class WayDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// estimate position of text on path
|
// estimate position of text on path
|
||||||
width = (x2 - x1) / 2;
|
width = (x2 - x1) / 2f;
|
||||||
x2 = x2 - (int) (width - s * width);
|
//width += 4 * (width / wayNameWidth);
|
||||||
x1 = x1 + (int) (width - s * width);
|
x2 = x2 - (width - s * width);
|
||||||
|
x1 = x1 + (width - s * width);
|
||||||
|
|
||||||
height = (y2 - y1) / 2;
|
height = (y2 - y1) / 2f;
|
||||||
y2 = y2 - (int) (height - s * height);
|
//height += 4 * (height / wayNameWidth);
|
||||||
y1 = y1 + (int) (height - s * height);
|
y2 = y2 - (height - s * height);
|
||||||
|
y1 = y1 + (height - s * height);
|
||||||
|
|
||||||
// short top = (short) (y1 < y2 ? y1 : y2);
|
// short top = (short) (y1 < y2 ? y1 : y2);
|
||||||
// short bot = (short) (y1 < y2 ? y2 : y1);
|
// short bot = (short) (y1 < y2 ? y2 : y1);
|
||||||
@ -260,17 +262,24 @@ public final class WayDecorator {
|
|||||||
// previousY = (int) coordinates[pos + i + 1];
|
// previousY = (int) coordinates[pos + i + 1];
|
||||||
// continue;
|
// continue;
|
||||||
// }
|
// }
|
||||||
|
TextItem n = TextItem.get();
|
||||||
|
|
||||||
t = TextItem.get();
|
// link items together
|
||||||
|
if (t != null) {
|
||||||
|
t.n1 = n;
|
||||||
|
n.n2 = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = n;
|
||||||
t.x = x1 + (x2 - x1) / 2f;
|
t.x = x1 + (x2 - x1) / 2f;
|
||||||
t.y = y1 + (y2 - y1) / 2f;
|
t.y = y1 + (y2 - y1) / 2f;
|
||||||
t.string = string;
|
t.string = string;
|
||||||
t.text = text;
|
t.text = text;
|
||||||
t.width = wayNameWidth;
|
t.width = wayNameWidth;
|
||||||
t.x1 = (short) x1;
|
t.x1 = x1;
|
||||||
t.y1 = (short) y1;
|
t.y1 = y1;
|
||||||
t.x2 = (short) x2;
|
t.x2 = x2;
|
||||||
t.y2 = (short) y2;
|
t.y2 = y2;
|
||||||
t.length = (short) segmentLength;
|
t.length = (short) segmentLength;
|
||||||
|
|
||||||
t.next = items;
|
t.next = items;
|
||||||
|
@ -58,6 +58,13 @@ public class TextItem {
|
|||||||
TextItem next = ti.next;
|
TextItem next = ti.next;
|
||||||
|
|
||||||
ti.next = pool;
|
ti.next = pool;
|
||||||
|
|
||||||
|
// drop references
|
||||||
|
ti.string = null;
|
||||||
|
ti.text = null;
|
||||||
|
ti.n1 = null;
|
||||||
|
ti.n2 = null;
|
||||||
|
|
||||||
pool = ti;
|
pool = ti;
|
||||||
|
|
||||||
ti = next;
|
ti = next;
|
||||||
@ -92,13 +99,47 @@ public class TextItem {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean bboxOverlaps(TextItem it1, TextItem it2, float add) {
|
||||||
|
if (it1.y1 < it1.y2) {
|
||||||
|
if (it2.y1 < it2.y2)
|
||||||
|
return (it1.x1 - add < it2.x2)
|
||||||
|
&& (it2.x1 < it1.x2 + add)
|
||||||
|
&& (it1.y1 - add < it2.y2)
|
||||||
|
&& (it2.y1 < it1.y2 + add);
|
||||||
|
|
||||||
|
// flip it2
|
||||||
|
return (it1.x1 - add < it2.x2)
|
||||||
|
&& (it2.x1 < it1.x2 + add)
|
||||||
|
&& (it1.y1 - add < it2.y1)
|
||||||
|
&& (it2.y2 < it1.y2 + add);
|
||||||
|
}
|
||||||
|
|
||||||
|
// flip it1
|
||||||
|
if (it2.y1 < it2.y2)
|
||||||
|
return (it1.x1 - add < it2.x2)
|
||||||
|
&& (it2.x1 < it1.x2 + add)
|
||||||
|
&& (it1.y2 - add < it2.y2)
|
||||||
|
&& (it2.y1 < it1.y1 + add);
|
||||||
|
|
||||||
|
// flip both
|
||||||
|
return (it1.x1 - add < it2.x2)
|
||||||
|
&& (it2.x1 < it1.x2 + add)
|
||||||
|
&& (it1.y2 - add < it2.y1)
|
||||||
|
&& (it2.y2 < it1.y1 + add);
|
||||||
|
}
|
||||||
|
|
||||||
public TextItem next;
|
public TextItem next;
|
||||||
|
|
||||||
public float x, y;
|
public float x, y;
|
||||||
public String string;
|
public String string;
|
||||||
public Text text;
|
public Text text;
|
||||||
public float width;
|
public float width;
|
||||||
public short x1, y1, x2, y2;
|
public float x1, y1, x2, y2;
|
||||||
public short length;
|
public short length;
|
||||||
|
|
||||||
|
// link to next/prev label of the way
|
||||||
|
public TextItem n1;
|
||||||
|
public TextItem n2;
|
||||||
|
public boolean active;
|
||||||
// public byte placement
|
// public byte placement
|
||||||
}
|
}
|
||||||
|
@ -21,18 +21,26 @@ import org.oscim.renderer.GLRenderer;
|
|||||||
import org.oscim.renderer.MapTile;
|
import org.oscim.renderer.MapTile;
|
||||||
import org.oscim.renderer.TileManager;
|
import org.oscim.renderer.TileManager;
|
||||||
import org.oscim.renderer.TileSet;
|
import org.oscim.renderer.TileSet;
|
||||||
|
import org.oscim.renderer.layer.Layer;
|
||||||
|
import org.oscim.renderer.layer.Layers;
|
||||||
|
import org.oscim.renderer.layer.LineLayer;
|
||||||
import org.oscim.renderer.layer.TextItem;
|
import org.oscim.renderer.layer.TextItem;
|
||||||
import org.oscim.renderer.layer.TextLayer;
|
import org.oscim.renderer.layer.TextLayer;
|
||||||
|
import org.oscim.theme.renderinstruction.Line;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.utils.GeometryUtils;
|
import org.oscim.utils.GeometryUtils;
|
||||||
import org.oscim.utils.GlUtils;
|
import org.oscim.utils.GlUtils;
|
||||||
import org.oscim.utils.PausableThread;
|
import org.oscim.utils.PausableThread;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint.Cap;
|
||||||
import android.opengl.Matrix;
|
import android.opengl.Matrix;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
public class TextOverlay extends RenderOverlay {
|
public class TextOverlay extends RenderOverlay {
|
||||||
|
private final static String TAG = TextOverlay.class.getName();
|
||||||
|
|
||||||
private TileSet mTiles;
|
private TileSet mTiles;
|
||||||
private LabelThread mThread;
|
private LabelThread mThread;
|
||||||
@ -51,7 +59,7 @@ public class TextOverlay extends RenderOverlay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doWork() {
|
protected void doWork() {
|
||||||
SystemClock.sleep(250);
|
SystemClock.sleep(400);
|
||||||
if (!mRun)
|
if (!mRun)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -79,6 +87,80 @@ public class TextOverlay extends RenderOverlay {
|
|||||||
mThread.start();
|
mThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TextItem mPool;
|
||||||
|
|
||||||
|
private byte checkOverlap(TextLayer tl, TextItem ti) {
|
||||||
|
|
||||||
|
for (TextItem lp = tl.labels; lp != null;) {
|
||||||
|
if (lp.text.caption) {
|
||||||
|
lp = lp.next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check bounding box
|
||||||
|
if (!TextItem.bboxOverlaps(ti, lp, 80)) {
|
||||||
|
lp = lp.next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lp.text == ti.text && (lp.string == ti.string || lp.string.equals(ti.string))) {
|
||||||
|
// make strings unique
|
||||||
|
ti.string = lp.string;
|
||||||
|
|
||||||
|
Log.d(TAG, "overlap, same label in bbox " + lp.string
|
||||||
|
+ " at " + ti.x + ":" + ti.y + ", " + lp.x + ":" + lp.y);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TextItem.bboxOverlaps(ti, lp, 10)) {
|
||||||
|
lp = lp.next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte intersect = GeometryUtils.linesIntersect(
|
||||||
|
ti.x1, ti.y1, ti.x2, ti.y2,
|
||||||
|
lp.x1, lp.y1, lp.x2, lp.y2);
|
||||||
|
|
||||||
|
if (intersect != 0) {
|
||||||
|
//Log.d(TAG, "overlap " + lp.string + " <> " + ti.string
|
||||||
|
//+ " at " + ti.x + ":" + ti.y);
|
||||||
|
|
||||||
|
if ((lp.n1 != null && lp.n1 == ti.n2) ||
|
||||||
|
(lp.n2 != null && lp.n2 == ti.n1)) {
|
||||||
|
//Log.d(TAG, "overlap with adjacent label " + lp.string
|
||||||
|
// + " at " + ti.x + ":" + ti.y + ", " + lp.x + ":" + lp.y);
|
||||||
|
|
||||||
|
return intersect;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ti.n1 != null || ti.n2 != null) && (lp.n1 == null && lp.n2 == null)) {
|
||||||
|
Log.d(TAG, "overlap, other is unique " + lp.string + " " + ti.string
|
||||||
|
+ " at " + ti.x + ":" + ti.y + ", " + lp.x + ":" + lp.y);
|
||||||
|
return intersect;
|
||||||
|
}
|
||||||
|
// just to make it more deterministic
|
||||||
|
if (lp.x > ti.x) {
|
||||||
|
//Log.d(TAG, "drop " + lp.string);
|
||||||
|
|
||||||
|
TextItem tmp = lp;
|
||||||
|
lp = lp.next;
|
||||||
|
|
||||||
|
tl.removeText(tmp);
|
||||||
|
|
||||||
|
tmp.next = mPool;
|
||||||
|
mPool = tmp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return intersect;
|
||||||
|
}
|
||||||
|
|
||||||
|
lp = lp.next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Layers mDebugLayer = null; //new Layers();
|
||||||
|
|
||||||
void updateLabels() {
|
void updateLabels() {
|
||||||
mTiles = TileManager.getActiveTiles(mTiles);
|
mTiles = TileManager.getActiveTiles(mTiles);
|
||||||
|
|
||||||
@ -102,6 +184,7 @@ public class TextOverlay extends RenderOverlay {
|
|||||||
if (diff > 1 || diff < -2) {
|
if (diff > 1 || diff < -2) {
|
||||||
// pass back the current layer
|
// pass back the current layer
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
Log.d(TAG, "drop labels: diff " + diff);
|
||||||
mCurLayer = tl;
|
mCurLayer = tl;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -112,22 +195,34 @@ public class TextOverlay extends RenderOverlay {
|
|||||||
float cos = (float) Math.cos(angle);
|
float cos = (float) Math.cos(angle);
|
||||||
float sin = (float) Math.sin(angle);
|
float sin = (float) Math.sin(angle);
|
||||||
|
|
||||||
TextItem ti2 = null;
|
|
||||||
|
|
||||||
int maxx = Tile.TILE_SIZE << (mWorkPos.zoomLevel - 1);
|
int maxx = Tile.TILE_SIZE << (mWorkPos.zoomLevel - 1);
|
||||||
|
|
||||||
MapTile[] tiles = mTiles.tiles;
|
MapTile[] tiles = mTiles.tiles;
|
||||||
|
TextItem ti2 = null;
|
||||||
|
|
||||||
// order tiles by x/y coordinate to make placement more consistent
|
if (mDebugLayer != null) {
|
||||||
// while map position changes
|
mDebugLayer.clear();
|
||||||
//Arrays.sort(tiles, 0, mTiles.cnt, TileSet.coordComparator);
|
LineLayer ll = (LineLayer) mDebugLayer.getLayer(0, Layer.LINE);
|
||||||
|
ll.line = new Line(Color.BLUE, 1, Cap.BUTT);
|
||||||
|
ll.width = 2;
|
||||||
|
ll = (LineLayer) mDebugLayer.getLayer(3, Layer.LINE);
|
||||||
|
ll.line = new Line(Color.YELLOW, 1, Cap.BUTT);
|
||||||
|
ll.width = 2;
|
||||||
|
ll = (LineLayer) mDebugLayer.getLayer(1, Layer.LINE);
|
||||||
|
ll.line = new Line(Color.RED, 1, Cap.BUTT);
|
||||||
|
ll.width = 2;
|
||||||
|
ll = (LineLayer) mDebugLayer.getLayer(2, Layer.LINE);
|
||||||
|
ll.line = new Line(Color.GREEN, 1, Cap.BUTT);
|
||||||
|
ll.width = 2;
|
||||||
|
}
|
||||||
// TODO more sophisticated placement :)
|
// TODO more sophisticated placement :)
|
||||||
for (int i = 0, n = mTiles.cnt; i < n; i++) {
|
for (int i = 0, n = mTiles.cnt; i < n; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
if (!t.isVisible)
|
if (!t.isVisible)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Log.d(TAG, "add: " + t);
|
||||||
|
|
||||||
float dx = (float) (t.pixelX - mWorkPos.x);
|
float dx = (float) (t.pixelX - mWorkPos.x);
|
||||||
float dy = (float) (t.pixelY - mWorkPos.y);
|
float dy = (float) (t.pixelY - mWorkPos.y);
|
||||||
|
|
||||||
@ -142,18 +237,25 @@ public class TextOverlay extends RenderOverlay {
|
|||||||
|
|
||||||
for (TextItem ti = t.labels; ti != null; ti = ti.next) {
|
for (TextItem ti = t.labels; ti != null; ti = ti.next) {
|
||||||
|
|
||||||
boolean overlaps = false;
|
// acquire a TextItem to add to TextLayer
|
||||||
|
if (ti2 == null) {
|
||||||
|
if (mPool == null)
|
||||||
|
ti2 = TextItem.get();
|
||||||
|
else {
|
||||||
|
ti2 = mPool;
|
||||||
|
mPool = mPool.next;
|
||||||
|
ti2.next = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ti.text.caption) {
|
if (ti.text.caption) {
|
||||||
if (ti2 == null)
|
|
||||||
ti2 = TextItem.get();
|
|
||||||
ti2.move(ti, dx, dy, scale);
|
ti2.move(ti, dx, dy, scale);
|
||||||
|
|
||||||
int tx = (int) (ti2.x);
|
int tx = (int) (ti2.x);
|
||||||
int ty = (int) (ti2.y);
|
int ty = (int) (ti2.y);
|
||||||
int tw = (int) (ti2.width / 2);
|
int tw = (int) (ti2.width / 2);
|
||||||
int th = (int) (ti2.text.fontHeight / 2);
|
int th = (int) (ti2.text.fontHeight / 2);
|
||||||
|
|
||||||
|
boolean overlaps = false;
|
||||||
for (TextItem lp = tl.labels; lp != null;) {
|
for (TextItem lp = tl.labels; lp != null;) {
|
||||||
int px = (int) (lp.x);
|
int px = (int) (lp.x);
|
||||||
int py = (int) (lp.y);
|
int py = (int) (lp.y);
|
||||||
@ -170,89 +272,91 @@ public class TextOverlay extends RenderOverlay {
|
|||||||
}
|
}
|
||||||
lp = lp.next;
|
lp = lp.next;
|
||||||
}
|
}
|
||||||
} else {
|
if (!overlaps) {
|
||||||
|
tl.addText(ti2);
|
||||||
if (ti.width > ti.length * scale) {
|
ti2 = null;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ti2 == null)
|
|
||||||
ti2 = TextItem.get();
|
|
||||||
ti2.move(ti, dx, dy, scale);
|
|
||||||
|
|
||||||
if (cos * (ti.x2 - ti.x1) - sin * (ti.y2 - ti.y1) < 0) {
|
|
||||||
// flip label upside-down
|
|
||||||
ti2.x1 = (short) ((ti.x2 * scale + dx));
|
|
||||||
ti2.y1 = (short) ((ti.y2 * scale + dy));
|
|
||||||
ti2.x2 = (short) ((ti.x1 * scale + dx));
|
|
||||||
ti2.y2 = (short) ((ti.y1 * scale + dy));
|
|
||||||
} else {
|
|
||||||
ti2.x1 = (short) ((ti.x1 * scale + dx));
|
|
||||||
ti2.y1 = (short) ((ti.y1 * scale + dy));
|
|
||||||
ti2.x2 = (short) ((ti.x2 * scale + dx));
|
|
||||||
ti2.y2 = (short) ((ti.y2 * scale + dy));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//float normalLength = (float) Math.hypot(ti2.x2 - ti2.x1, ti2.y2 - ti2.y1);
|
continue;
|
||||||
|
|
||||||
for (TextItem lp = tl.labels; lp != null;) {
|
|
||||||
if (lp.text.caption) {
|
|
||||||
lp = lp.next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GeometryUtils.lineIntersect(ti2.x1, ti2.y1, ti2.x2, ti2.y2,
|
|
||||||
lp.x1, lp.y1, lp.x2, lp.y2)) {
|
|
||||||
// just to make it more deterministic
|
|
||||||
if (lp.width > ti2.width) {
|
|
||||||
TextItem tmp = lp;
|
|
||||||
lp = lp.next;
|
|
||||||
|
|
||||||
tl.removeText(tmp);
|
|
||||||
tmp.next = null;
|
|
||||||
TextItem.release(tmp);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
overlaps = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ti2.x1) < (lp.x2)
|
|
||||||
&& (lp.x1) < (ti2.x2)
|
|
||||||
&& (ti2.y1) < (lp.y2)
|
|
||||||
&& (lp.y1) < (ti2.y2)) {
|
|
||||||
|
|
||||||
// just to make it more deterministic
|
|
||||||
if (lp.width > ti2.width) {
|
|
||||||
TextItem tmp = lp;
|
|
||||||
lp = lp.next;
|
|
||||||
|
|
||||||
tl.removeText(tmp);
|
|
||||||
tmp.next = null;
|
|
||||||
TextItem.release(tmp);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
overlaps = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
lp = lp.next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overlaps) {
|
/* text is way label */
|
||||||
|
|
||||||
|
// check if path at current scale is long enough for text
|
||||||
|
if (mDebugLayer == null && ti.width > ti.length * scale)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// set line endpoints relative to view to be able to
|
||||||
|
// check intersections with label from other tiles
|
||||||
|
float width = (ti.x2 - ti.x1) / 2f;
|
||||||
|
float height = (ti.y2 - ti.y1) / 2f;
|
||||||
|
|
||||||
|
ti2.move(ti, dx, dy, scale);
|
||||||
|
ti2.x2 = (ti2.x + width);
|
||||||
|
ti2.x1 = (ti2.x - width);
|
||||||
|
ti2.y2 = (ti2.y + height);
|
||||||
|
ti2.y1 = (ti2.y - height);
|
||||||
|
|
||||||
|
byte overlaps = checkOverlap(tl, ti2);
|
||||||
|
|
||||||
|
if (mDebugLayer != null) {
|
||||||
|
|
||||||
|
LineLayer ll;
|
||||||
|
if (ti.width > ti.length * scale) {
|
||||||
|
ll = (LineLayer) mDebugLayer.getLayer(1, Layer.LINE);
|
||||||
|
overlaps = 3;
|
||||||
|
}
|
||||||
|
else if (overlaps == 1)
|
||||||
|
ll = (LineLayer) mDebugLayer.getLayer(0, Layer.LINE);
|
||||||
|
else if (overlaps == 2)
|
||||||
|
ll = (LineLayer) mDebugLayer.getLayer(3, Layer.LINE);
|
||||||
|
else
|
||||||
|
ll = (LineLayer) mDebugLayer.getLayer(2, Layer.LINE);
|
||||||
|
|
||||||
|
float[] points = new float[4];
|
||||||
|
short[] indices = { 4 };
|
||||||
|
points[0] = ti2.x1 / scale;
|
||||||
|
points[1] = ti2.y1 / scale;
|
||||||
|
points[2] = ti2.x2 / scale;
|
||||||
|
points[3] = ti2.y2 / scale;
|
||||||
|
ll.addLine(points, indices, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overlaps == 0) {
|
||||||
tl.addText(ti2);
|
tl.addText(ti2);
|
||||||
ti2 = null;
|
ti2 = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ti2 != null)
|
for (TextItem ti = tl.labels; ti != null; ti = ti.next) {
|
||||||
TextItem.release(ti2);
|
// scale back to fixed zoom-level. could be done in setMatrix
|
||||||
|
ti.x /= scale;
|
||||||
|
ti.y /= scale;
|
||||||
|
|
||||||
// scale back to fixed zoom-level. could be done in setMatrix..
|
if (ti.text.caption)
|
||||||
for (TextItem lp = tl.labels; lp != null; lp = lp.next) {
|
continue;
|
||||||
lp.x /= scale;
|
|
||||||
lp.y /= scale;
|
// flip label upside-down
|
||||||
|
if (cos * (ti.x2 - ti.x1) - sin * (ti.y2 - ti.y1) < 0) {
|
||||||
|
float tmp = ti.x1;
|
||||||
|
ti.x1 = ti.x2;
|
||||||
|
ti.x2 = tmp;
|
||||||
|
|
||||||
|
tmp = ti.y1;
|
||||||
|
ti.y1 = ti.y2;
|
||||||
|
ti.y2 = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// release temporarily used TextItems
|
||||||
|
if (ti2 != null) {
|
||||||
|
ti2.next = mPool;
|
||||||
|
mPool = ti2;
|
||||||
|
}
|
||||||
|
if (mPool != null) {
|
||||||
|
TextItem.release(mPool);
|
||||||
|
mPool = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw text to bitmaps and create vertices
|
// draw text to bitmaps and create vertices
|
||||||
@ -279,6 +383,11 @@ public class TextOverlay extends RenderOverlay {
|
|||||||
// clear textures and text items from previous layer
|
// clear textures and text items from previous layer
|
||||||
layers.clear();
|
layers.clear();
|
||||||
|
|
||||||
|
if (mDebugLayer != null) {
|
||||||
|
layers.layers = mDebugLayer.layers;
|
||||||
|
mDebugLayer.layers = null;
|
||||||
|
}
|
||||||
|
|
||||||
// set new TextLayer to be uploaded and used
|
// set new TextLayer to be uploaded and used
|
||||||
layers.textureLayers = mCurLayer;
|
layers.textureLayers = mCurLayer;
|
||||||
|
|
||||||
|
@ -64,11 +64,12 @@ public final class GeometryUtils {
|
|||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean linesIntersect(double x1, double y1, double x2, double y2, double x3, double y3,
|
public static byte linesIntersect(
|
||||||
double x4, double y4) {
|
double x1, double y1, double x2, double y2,
|
||||||
|
double x3, double y3, double x4, double y4) {
|
||||||
// Return false if either of the lines have zero length
|
// Return false if either of the lines have zero length
|
||||||
if (x1 == x2 && y1 == y2 || x3 == x4 && y3 == y4) {
|
if (x1 == x2 && y1 == y2 || x3 == x4 && y3 == y4) {
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
// Fastest method, based on Franklin Antonio's
|
// Fastest method, based on Franklin Antonio's
|
||||||
// "Faster Line Segment Intersection" topic "in Graphics Gems III" book
|
// "Faster Line Segment Intersection" topic "in Graphics Gems III" book
|
||||||
@ -85,21 +86,21 @@ public final class GeometryUtils {
|
|||||||
|
|
||||||
if (commonDenominator > 0) {
|
if (commonDenominator > 0) {
|
||||||
if (alphaNumerator < 0 || alphaNumerator > commonDenominator) {
|
if (alphaNumerator < 0 || alphaNumerator > commonDenominator) {
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (commonDenominator < 0) {
|
} else if (commonDenominator < 0) {
|
||||||
if (alphaNumerator > 0 || alphaNumerator < commonDenominator) {
|
if (alphaNumerator > 0 || alphaNumerator < commonDenominator) {
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double betaNumerator = ax * cy - ay * cx;
|
double betaNumerator = ax * cy - ay * cx;
|
||||||
if (commonDenominator > 0) {
|
if (commonDenominator > 0) {
|
||||||
if (betaNumerator < 0 || betaNumerator > commonDenominator) {
|
if (betaNumerator < 0 || betaNumerator > commonDenominator) {
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (commonDenominator < 0) {
|
} else if (commonDenominator < 0) {
|
||||||
if (betaNumerator > 0 || betaNumerator < commonDenominator) {
|
if (betaNumerator > 0 || betaNumerator < commonDenominator) {
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (commonDenominator == 0) {
|
if (commonDenominator == 0) {
|
||||||
@ -120,13 +121,13 @@ public final class GeometryUtils {
|
|||||||
if (y1 >= y3 && y1 <= y4 || y1 <= y3 && y1 >= y4 || y2 >= y3 && y2 <= y4
|
if (y1 >= y3 && y1 <= y4 || y1 <= y3 && y1 >= y4 || y2 >= y3 && y2 <= y4
|
||||||
|| y2 <= y3 && y2 >= y4
|
|| y2 <= y3 && y2 >= y4
|
||||||
|| y3 >= y1 && y3 <= y2 || y3 <= y1 && y3 >= y2) {
|
|| y3 >= y1 && y3 <= y2 || y3 <= y1 && y3 >= y2) {
|
||||||
return true;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean doesIntersect(double l1x1, double l1y1, double l1x2, double l1y2, double l2x1,
|
static boolean doesIntersect(double l1x1, double l1y1, double l1x2, double l1y2, double l2x1,
|
||||||
@ -144,27 +145,10 @@ public final class GeometryUtils {
|
|||||||
return ((ua >= 0.0d) && (ua <= 1.0d) && (ub >= 0.0d) && (ub <= 1.0d));
|
return ((ua >= 0.0d) && (ua <= 1.0d) && (ub >= 0.0d) && (ub <= 1.0d));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static boolean lineIntersect(
|
||||||
* @param x1
|
int x1, int y1, int x2, int y2,
|
||||||
* ...
|
int x3, int y3, int x4, int y4) {
|
||||||
* @param y1
|
|
||||||
* ...
|
|
||||||
* @param x2
|
|
||||||
* ...
|
|
||||||
* @param y2
|
|
||||||
* ...
|
|
||||||
* @param x3
|
|
||||||
* ...
|
|
||||||
* @param y3
|
|
||||||
* ...
|
|
||||||
* @param x4
|
|
||||||
* ...
|
|
||||||
* @param y4
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public static boolean lineIntersect(int x1, int y1, int x2, int y2, int x3, int y3, int x4,
|
|
||||||
int y4) {
|
|
||||||
float denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
|
float denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
|
||||||
if (denom == 0.0) { // Lines are parallel.
|
if (denom == 0.0) { // Lines are parallel.
|
||||||
return false;
|
return false;
|
||||||
@ -172,7 +156,6 @@ public final class GeometryUtils {
|
|||||||
float ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
|
float ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
|
||||||
float ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
|
float ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
|
||||||
if (ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f) {
|
if (ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f) {
|
||||||
// Get the intersection point.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user