labelLevel hysteresis now looks at target labelLevel size

This commit is contained in:
nathan 2021-03-20 11:43:48 -07:00
parent 721b9a4a17
commit 319d910e8d
5 changed files with 129 additions and 55 deletions

View file

@ -8,6 +8,33 @@ static float sign(float x) {
return (x > 0) - (x < 0); return (x > 0) - (x < 0);
} }
SDL_Rect AircraftLabel::getFullRect(int labelLevel) {
SDL_Rect rect = {x,y,0,0};
SDL_Rect currentRect;
if(labelLevel < 2) {
currentRect = speedLabel.getRect();
rect.w = std::max(rect.w,currentRect.w);
rect.h += currentRect.h;
}
if(labelLevel < 1) {
currentRect = altitudeLabel.getRect();
rect.w = std::max(rect.w,currentRect.w);
rect.h += currentRect.h;
currentRect = speedLabel.getRect();
rect.w = std::max(rect.w,currentRect.w);
rect.h += currentRect.h;
}
return rect;
}
void AircraftLabel::update() { void AircraftLabel::update() {
char flight[10] = ""; char flight[10] = "";
snprintf(flight,10," %s", p->flight); snprintf(flight,10," %s", p->flight);
@ -38,7 +65,60 @@ void AircraftLabel::clearAcceleration() {
ddy = 0; ddy = 0;
} }
float AircraftLabel::calculateDensity(Aircraft *check_p, int labelLevel) {
float density_max = 0;
while(check_p) {
if(check_p->addr == p->addr) {
check_p = check_p->next;
continue;
}
if(!check_p->label) {
check_p = check_p->next;
continue;
}
if(check_p->label->x + check_p->label->w < 0) {
check_p = check_p->next;
continue;
}
if(check_p->label->y + check_p->label->h < 0) {
check_p = check_p->next;
continue;
}
if(check_p->label->x > screen_width) {
check_p = check_p->next;
continue;
}
if(check_p->label->y > screen_height) {
check_p = check_p->next;
continue;
}
SDL_Rect currentRect = getFullRect(labelLevel);
float width_proportion = (currentRect.w + check_p->label->w) / fabs(x - check_p->label->x);
float height_proportion = (currentRect.h + check_p->label->h) / fabs(y - check_p->label->y);
float density = width_proportion * height_proportion;
if(density > density_max) {
density_max = density;
}
check_p = check_p -> next;
}
return density_max;
}
void AircraftLabel::calculateForces(Aircraft *check_p) { void AircraftLabel::calculateForces(Aircraft *check_p) {
Aircraft *head = check_p;
int p_left = x; int p_left = x;
int p_right = x + w; int p_right = x + w;
int p_top = y; int p_top = y;
@ -60,7 +140,7 @@ void AircraftLabel::calculateForces(Aircraft *check_p) {
ddy -= sign(offset_y) * attachment_force * (fabs(offset_y) - target_length_y); ddy -= sign(offset_y) * attachment_force * (fabs(offset_y) - target_length_y);
// // //screen edge // screen edge
if(p_left < edge_margin) { if(p_left < edge_margin) {
ddx += boundary_force * (float)(edge_margin - p_left); ddx += boundary_force * (float)(edge_margin - p_left);
@ -84,7 +164,6 @@ void AircraftLabel::calculateForces(Aircraft *check_p) {
int count = 0; int count = 0;
//check against other labels //check against other labels
float density_max = 0;
while(check_p) { while(check_p) {
if(check_p->addr == p->addr) { if(check_p->addr == p->addr) {
@ -97,19 +176,6 @@ void AircraftLabel::calculateForces(Aircraft *check_p) {
continue; continue;
} }
//calculate density for label display level (inversely proportional to area of smallest box connecting this to neighbor)
float density = 1.0 / (0.001f + fabs(x - check_p->label->x) * fabs (x - check_p->label->y));
if(density > density_max) {
density_max = density;
}
density = 1.0 / (0.001f + fabs(x - check_p->x) * fabs(x - check_p->y));
if(density > density_max) {
density_max = density;
}
int check_left = check_p->label->x; int check_left = check_p->label->x;
int check_right = check_p->label->x + check_p->label->w; int check_right = check_p->label->x + check_p->label->w;
int check_top = check_p->label->y; int check_top = check_p->label->y;
@ -161,6 +227,7 @@ void AircraftLabel::calculateForces(Aircraft *check_p) {
check_p = check_p -> next; check_p = check_p -> next;
} }
// float density_max = calculateDensity(head, labelLevel);
// move away from others // move away from others
ddx += density_force * all_x / count; ddx += density_force * all_x / count;
@ -168,13 +235,30 @@ void AircraftLabel::calculateForces(Aircraft *check_p) {
// label drawlevel hysteresis // label drawlevel hysteresis
float density_mult = 100.0f; // float density_mult = 100.0f;
float level_rate = 0.0005f; // float level_rate = 0.0005f;
if(labelLevel < -1.25f + density_mult * density_max) { // if(labelLevel < -1.25f + density_mult * density_max) {
labelLevel += level_rate; // labelLevel += level_rate;
} else if (labelLevel > 0.5f + density_mult * density_max) { // } else if (labelLevel > 0.5f + density_mult * density_max) {
labelLevel -= level_rate; // labelLevel -= level_rate;
// }
char buff[100];
snprintf(buff, sizeof(buff), "%2.2f", labelLevel);
debugLabel.setText(buff);
float density_mult = 0.5f;
float level_rate = 0.001f;
if(labelLevel < 0.8f * density_mult * calculateDensity(head, labelLevel+1)) {
if(labelLevel <= 2) {
labelLevel += level_rate;
}
} else if (labelLevel > 1.2f * density_mult * calculateDensity(head, labelLevel)) {
if(labelLevel >= 0) {
labelLevel -= level_rate;
}
} }
} }
@ -346,7 +430,7 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) {
SDL_Color drawColor = style.labelColor; SDL_Color drawColor = style.labelColor;
drawColor.a = (int) (255.0f * opacity); drawColor.a = (int) (255.0f * opacity);
flightLabel.setFGColor(drawColor); flightLabel.setColor(drawColor);
flightLabel.setPosition(x,y); flightLabel.setPosition(x,y);
flightLabel.draw(renderer); flightLabel.draw(renderer);
// outRect = drawString(flight, x, y, mapBoldFont, drawColor); // outRect = drawString(flight, x, y, mapBoldFont, drawColor);
@ -361,7 +445,7 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) {
SDL_Color drawColor = style.subLabelColor; SDL_Color drawColor = style.subLabelColor;
drawColor.a = (int) (255.0f * opacity); drawColor.a = (int) (255.0f * opacity);
altitudeLabel.setFGColor(drawColor); altitudeLabel.setColor(drawColor);
altitudeLabel.setPosition(x,y + totalHeight); altitudeLabel.setPosition(x,y + totalHeight);
altitudeLabel.draw(renderer); altitudeLabel.draw(renderer);
outRect = altitudeLabel.getRect(); outRect = altitudeLabel.getRect();
@ -369,7 +453,7 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) {
totalWidth = std::max(totalWidth,outRect.w); totalWidth = std::max(totalWidth,outRect.w);
totalHeight += outRect.h; totalHeight += outRect.h;
speedLabel.setFGColor(drawColor); speedLabel.setColor(drawColor);
speedLabel.setPosition(x,y + totalHeight); speedLabel.setPosition(x,y + totalHeight);
speedLabel.draw(renderer); speedLabel.draw(renderer);
outRect = speedLabel.getRect(); outRect = speedLabel.getRect();
@ -379,6 +463,9 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) {
} }
debugLabel.setPosition(x,y + totalHeight);
debugLabel.draw(renderer);
target_w = totalWidth; target_w = totalWidth;
target_h = totalHeight; target_h = totalHeight;
@ -422,4 +509,5 @@ AircraftLabel::AircraftLabel(Aircraft *p, bool metric, int screen_width, int scr
flightLabel.setFont(font); flightLabel.setFont(font);
altitudeLabel.setFont(font); altitudeLabel.setFont(font);
speedLabel.setFont(font); speedLabel.setFont(font);
debugLabel.setFont(font);
} }

View file

@ -20,14 +20,17 @@ class AircraftLabel {
AircraftLabel(Aircraft *p, bool metric, int screen_width, int screen_height, TTF_Font *font); AircraftLabel(Aircraft *p, bool metric, int screen_width, int screen_height, TTF_Font *font);
private: private:
SDL_Rect getFullRect(int labelLevel);
float calculateDensity(Aircraft *check_p, int labelLevel);
Aircraft *p; Aircraft *p;
Label flightLabel; Label flightLabel;
Label altitudeLabel; Label altitudeLabel;
Label speedLabel; Label speedLabel;
Label debugLabel;
int labelLevel; float labelLevel;
bool metric; bool metric;

View file

@ -1,7 +1,6 @@
#include "Label.h" #include "Label.h"
#include <string> #include <string>
void Label::draw(SDL_Renderer *renderer) { void Label::draw(SDL_Renderer *renderer) {
SDL_Rect rect = getRect(); SDL_Rect rect = getRect();
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface); SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
@ -11,20 +10,9 @@ void Label::draw(SDL_Renderer *renderer) {
void Label::makeSurface() { void Label::makeSurface() {
// if(BGColor.a = 0) { surface = TTF_RenderUTF8_Solid(font, text.c_str(), color);
surface = TTF_RenderUTF8_Solid(font, text.c_str(), FGColor);
// } else {
// surface = TTF_RenderUTF8_Shaded(font, text.c_str(), FGColor, BGColor);
// }
if (surface == NULL)
{
printf("Couldn't create surface for String %s: %s\n", text.c_str(), SDL_GetError());
}
} }
SDL_Rect Label::getRect() { SDL_Rect Label::getRect() {
SDL_Rect rect = {0,0,0,0}; SDL_Rect rect = {0,0,0,0};
@ -58,16 +46,12 @@ void Label::setFont(TTF_Font *font) {
this->font = font; this->font = font;
} }
void Label::setFGColor(SDL_Color color) { void Label::setColor(SDL_Color color) {
this->FGColor = color; this->color = color;
} }
//
void Label::setBGColor(SDL_Color color) {
this->BGColor = color;
}
Label::Label() { Label::Label() {
BGColor = {0, 0, 0, 0}; this->color = {255,255,255,255};
surface = NULL; surface = NULL;
} }

View file

@ -10,8 +10,7 @@ class Label {
void setText(std::string text); void setText(std::string text);
void setPosition(int x, int y); void setPosition(int x, int y);
void setFont(TTF_Font *font); void setFont(TTF_Font *font);
void setFGColor(SDL_Color color); void setColor(SDL_Color color);
void setBGColor(SDL_Color color);
SDL_Rect getRect(); SDL_Rect getRect();
@ -21,12 +20,10 @@ class Label {
private: private:
void makeSurface(); void makeSurface();
std::string text; std::string text;
int x; int x;
int y; int y;
TTF_Font *font; TTF_Font *font;
SDL_Color FGColor; SDL_Color color;
SDL_Color BGColor;
SDL_Surface *surface; SDL_Surface *surface;
}; };

View file

@ -332,13 +332,13 @@ void View::drawStatusBox(int *left, int *top, std::string label, std::string mes
Label currentLabel; Label currentLabel;
currentLabel.setFont(labelFont); currentLabel.setFont(labelFont);
currentLabel.setFGColor(style.buttonBackground); currentLabel.setColor(style.buttonBackground);
currentLabel.setPosition(*left + labelFontWidth/2, *top); currentLabel.setPosition(*left + labelFontWidth/2, *top);
currentLabel.setText(label); currentLabel.setText(label);
currentLabel.draw(renderer); currentLabel.draw(renderer);
currentLabel.setFont(messageFont); currentLabel.setFont(messageFont);
currentLabel.setFGColor(color); currentLabel.setColor(color);
currentLabel.setPosition(*left + labelWidth + messageFontWidth/2, *top); currentLabel.setPosition(*left + labelWidth + messageFontWidth/2, *top);
currentLabel.setText(message); currentLabel.setText(message);
currentLabel.draw(renderer); currentLabel.draw(renderer);
@ -565,7 +565,7 @@ void View::drawScaleBars()
Label currentLabel; Label currentLabel;
currentLabel.setFont(mapFont); currentLabel.setFont(mapFont);
currentLabel.setFGColor(style.scaleBarColor); currentLabel.setColor(style.scaleBarColor);
currentLabel.setPosition(10+scaleBarDist, 15*screen_uiscale); currentLabel.setPosition(10+scaleBarDist, 15*screen_uiscale);
currentLabel.setText(scaleLabel); currentLabel.setText(scaleLabel);
currentLabel.draw(renderer); currentLabel.draw(renderer);
@ -673,9 +673,11 @@ void View::drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen
void View::drawPlaceNames() { void View::drawPlaceNames() {
//pre-generating labels in map will trade memory for TTF calls - need to compare when there are a lot of labels on screen
Label currentLabel; Label currentLabel;
currentLabel.setFont(mapFont); currentLabel.setFont(mapFont);
currentLabel.setFGColor(style.geoColor); currentLabel.setColor(style.geoColor);
for(std::vector<MapLabel*>::iterator label = map.mapnames.begin(); label != map.mapnames.end(); ++label) { for(std::vector<MapLabel*>::iterator label = map.mapnames.begin(); label != map.mapnames.end(); ++label) {
float dx, dy; float dx, dy;