Calculate text collisions properly

This commit is contained in:
Victor Shcherb 2011-10-26 16:23:56 +02:00
parent 4fd9f75b69
commit f2c5a75c94
5 changed files with 83 additions and 33 deletions

View file

@ -8,7 +8,7 @@
#include <SkPath.h>
#include <SkBitmap.h>
//#define DEBUG_NAT_OPERATIONS
#define DEBUG_NAT_OPERATIONS
#ifdef DEBUG_NAT_OPERATIONS
#define NAT_COUNT(rc, op) rc->nativeOperations.pause(); op; rc->nativeOperations.start()
@ -81,7 +81,7 @@ jfieldID getFid(jclass cls,const char* fieldName, const char* sig )
}
class watcher {
int elapsedTime;
long elapsedTime;
bool enableFlag;
// timeval startInit;
// timeval endInit;
@ -94,6 +94,7 @@ public:
watcher() {
elapsedTime = 0;
enableFlag = true;
run = false;
}
void enable(){
enableFlag = true;

View file

@ -223,7 +223,7 @@ bool calculatePathToRotate(RenderingContext* rc, TextDrawInfo* p) {
py += points[i].fY - points[i - 1].fY;
}
if (px != 0 || py != 0) {
p->pathRotate = std::atan2(py, px) * 180 / M_PI;
p->pathRotate = std::atan2(py, px);
}
return true;
}
@ -319,10 +319,10 @@ bool calculatePathToRotate(RenderingContext* rc, TextDrawInfo* p) {
float ox = -py;
float oy = px;
if(plen > 0) {
float rot = std::atan2(py, px) * 180 / M_PI;
if (rot < 0) rot += 360;
if (rot > 90 && rot < 270) {
rot += 180;
float rot = std::atan2(py, px);
if (rot < 0) rot += M_PI * 2;
if (rot > M_PI_2 && rot < 3 * M_PI_2) {
rot += M_PI;
inverse = true;
ox = -ox;
oy = -oy;
@ -354,27 +354,66 @@ bool calculatePathToRotate(RenderingContext* rc, TextDrawInfo* p) {
return true;
}
void drawTestBox(SkCanvas* cv, TextDrawInfo* text, SkPaint* paintIcon, SkPaint* paintText)
void drawTestBox(SkCanvas* cv, SkRect* r, float rot, SkPaint* paintIcon, std::string text, SkPaint* paintText)
{
cv->save();
cv->translate(text->bounds.centerX(),text->bounds.centerY());
cv->rotate(text->pathRotate);
SkRect r = SkRect::MakeLTRB(-text->bounds.width()/2, -text->bounds.height()/2,
text->bounds.width()/2, text->bounds.height()/2);
cv->drawRect(r, *paintIcon);
cv->translate(r->centerX(),r->centerY());
cv->rotate(rot * 180 / M_PI);
SkRect rs = SkRect::MakeLTRB(-r->width()/2, -r->height()/2,
r->width()/2, r->height()/2);
cv->drawRect(rs, *paintIcon);
if (paintText != NULL) {
cv->drawText(text->text.data(), text->text.length(), r.centerX(), r.centerY(),
cv->drawText(text.data(), text.length(), rs.centerX(), rs.centerY(),
*paintText);
}
cv->restore();
}
bool intersect(TextDrawInfo* t, TextDrawInfo* s)
{
// TODO rotation
return t->bounds.intersect(s->bounds);
float sqr(float a){
return a*a;
}
bool intersect(SkRect tRect, float tRot, TextDrawInfo* s)
{
float sRot = s->pathRotate;
if (abs(tRot) < M_PI / 15 && abs(sRot) < M_PI / 15) {
return tRect.intersect(s->bounds);
}
float dist = sqrt(sqr(tRect.centerX() - s->bounds.centerX()) + sqr(tRect.centerY() - s->bounds.centerY()));
if(dist < 3) {
return true;
}
SkRect sRect = s->bounds;
// difference close to 90/270 degrees
if(abs(cos(tRot-sRot)) < 0.3 ){
// rotate one rectangle to 90 degrees
tRot += M_PI_2;
tRect = SkRect::MakeXYWH(tRect.centerX() - tRect.height() / 2, tRect.centerY() - tRect.width() / 2,
tRect.height(), tRect.width());
}
// determine difference close to 180/0 degrees
if(abs(sin(tRot-sRot)) < 0.3){
// rotate t box
// (calculate offset for t center suppose we rotate around s center)
float diff = atan2(tRect.centerY() - sRect.centerY(), tRect.centerX() - sRect.centerX());
diff -= sRot;
float left = sRect.centerX() + dist* cos(diff) - tRect.width()/2;
float top = sRect.centerY() - dist* sin(diff) - tRect.height()/2;
SkRect nRect = SkRect::MakeXYWH(left, top, tRect.width(), tRect.height());
return nRect.intersect(sRect);
}
// TODO other cases not covered
return tRect.intersect(sRect);
}
bool intersect(TextDrawInfo* t, TextDrawInfo* s) {
// TODO
return t->bounds.intersect(s->bounds);
// return intersect(t->bounds, t->pathRotate, s);
}
std::vector<TextDrawInfo*> search;
bool findTextIntersection(SkCanvas* cv, RenderingContext* rc, quad_tree<TextDrawInfo*>& boundIntersections, TextDrawInfo* text,
SkPaint* paintText, SkPaint* paintIcon) {
@ -395,24 +434,27 @@ bool findTextIntersection(SkCanvas* cv, RenderingContext* rc, quad_tree<TextDraw
text->bounds.offset(text->centerX - text->bounds.width()/2, text->centerY - text->bounds.height()/2);
}
SkRect boundsSearch = text->bounds;
float v = -getDensityValue(rc, std::max(5.0f, text->minDistance));
// TODO min distance different !
boundsSearch.inset(v, v);
// for text purposes
// drawTestBox(cv, text, paintIcon, paintText);
boundIntersections.query_in_box(boundsSearch, search);
// drawTestBox(cv, &text->bounds, text->pathRotate, paintIcon, text->text, NULL/*paintText*/);
boundIntersections.query_in_box(text->bounds, search);
for (uint i = 0; i < search.size(); i++) {
TextDrawInfo* t = search.at(i);
if (intersect(text, t)) {
return true;
} else if (boundsSearch.intersect(t->bounds) && t->text == text->text) {
return true;
}
}
if(text->minDistance > 0) {
SkRect boundsSearch = text->bounds;
boundsSearch.inset(-getDensityValue(rc, std::max(5.0f, text->minDistance)), -getDensityValue(rc, 12));
// drawTestBox(cv, &boundsSearch, text->pathRotate, paintIcon, text->text, NULL/*paintText*/);
for (uint i = 0; i < search.size(); i++) {
TextDrawInfo* t = search.at(i);
if (t->minDistance > 0 && intersect(boundsSearch, text->pathRotate, t)) {
return true;
}
}
}
boundIntersections.insert(text, text->bounds);
return false;

Binary file not shown.

View file

@ -1024,7 +1024,7 @@ public class OsmandSettings {
public final OsmandPreference<Boolean> TEST_ANIMATE_ROUTING = new BooleanPreference("animate_routing", false, true);
// this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference<Boolean> NATIVE_RENDERING = new BooleanPreference("native_rendering", true, true);
public final OsmandPreference<Boolean> NATIVE_RENDERING = new BooleanPreference("native_rendering", false, true);
// this value string is synchronized with settings_pref.xml preference name

View file

@ -230,8 +230,6 @@ public class MapRenderRepositories {
double cLeftLongitude = dataBox.left;
double cRightLongitude = dataBox.right;
log.info(String.format("BLat=%s, TLat=%s, LLong=%s, RLong=%s, zoom=%s", //$NON-NLS-1$
cBottomLatitude, cTopLatitude, cLeftLongitude, cRightLongitude, zoom));
long now = System.currentTimeMillis();
@ -334,7 +332,12 @@ public class MapRenderRepositories {
List<MultyPolygon> pMulti = proccessMultiPolygons(multiPolygons, leftX, rightX, bottomY, topY, zoom);
tempList.addAll(pMulti);
log.info(String.format("Search done in %s ms. %s results were found.", System.currentTimeMillis() - now, count)); //$NON-NLS-1$
if (count > 0) {
log.info(String.format("BLat=%s, TLat=%s, LLong=%s, RLong=%s, zoom=%s", //$NON-NLS-1$
cBottomLatitude, cTopLatitude, cLeftLongitude, cRightLongitude, zoom));
log.info(String.format("Search done in %s ms. %s results were found.", System.currentTimeMillis() - now, count)); //$NON-NLS-1$
}
cObjects = tempList;
cObjectsBox = dataBox;
@ -450,6 +453,9 @@ public class MapRenderRepositories {
String renderingDebugInfo = currentRenderingContext.renderingDebugInfo;
currentRenderingContext.ended = true;
if (checkWhetherInterrupted()) {
// revert if it was interrupted
this.bmp = this.prevBmp;
this.bmpLocation = this.prevBmpLocation;
currentRenderingContext = null;
return;
}
@ -464,6 +470,7 @@ public class MapRenderRepositories {
timeInfo += "\n" + renderingDebugInfo;
}
final String msg = timeInfo;
log.info(msg);
handler.post(new Runnable() {
@Override
public void run() {