Calculate text collisions properly
This commit is contained in:
parent
4fd9f75b69
commit
f2c5a75c94
5 changed files with 83 additions and 33 deletions
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
}
|
||||
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.
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
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() {
|
||||
|
|
Loading…
Reference in a new issue