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);
}
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() {
char flight[10] = "";
snprintf(flight,10," %s", p->flight);
@ -38,7 +65,60 @@ void AircraftLabel::clearAcceleration() {
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) {
Aircraft *head = check_p;
int p_left = x;
int p_right = x + w;
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);
// // //screen edge
// screen edge
if(p_left < edge_margin) {
ddx += boundary_force * (float)(edge_margin - p_left);
@ -84,7 +164,6 @@ void AircraftLabel::calculateForces(Aircraft *check_p) {
int count = 0;
//check against other labels
float density_max = 0;
while(check_p) {
if(check_p->addr == p->addr) {
@ -97,19 +176,6 @@ void AircraftLabel::calculateForces(Aircraft *check_p) {
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_right = check_p->label->x + check_p->label->w;
int check_top = check_p->label->y;
@ -161,6 +227,7 @@ void AircraftLabel::calculateForces(Aircraft *check_p) {
check_p = check_p -> next;
}
// float density_max = calculateDensity(head, labelLevel);
// move away from others
ddx += density_force * all_x / count;
@ -168,14 +235,31 @@ void AircraftLabel::calculateForces(Aircraft *check_p) {
// label drawlevel hysteresis
float density_mult = 100.0f;
float level_rate = 0.0005f;
// float density_mult = 100.0f;
// float level_rate = 0.0005f;
if(labelLevel < -1.25f + density_mult * density_max) {
// if(labelLevel < -1.25f + density_mult * density_max) {
// labelLevel += level_rate;
// } else if (labelLevel > 0.5f + density_mult * density_max) {
// 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 > 0.5f + density_mult * density_max) {
}
} 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;
drawColor.a = (int) (255.0f * opacity);
flightLabel.setFGColor(drawColor);
flightLabel.setColor(drawColor);
flightLabel.setPosition(x,y);
flightLabel.draw(renderer);
// outRect = drawString(flight, x, y, mapBoldFont, drawColor);
@ -361,7 +445,7 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) {
SDL_Color drawColor = style.subLabelColor;
drawColor.a = (int) (255.0f * opacity);
altitudeLabel.setFGColor(drawColor);
altitudeLabel.setColor(drawColor);
altitudeLabel.setPosition(x,y + totalHeight);
altitudeLabel.draw(renderer);
outRect = altitudeLabel.getRect();
@ -369,7 +453,7 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) {
totalWidth = std::max(totalWidth,outRect.w);
totalHeight += outRect.h;
speedLabel.setFGColor(drawColor);
speedLabel.setColor(drawColor);
speedLabel.setPosition(x,y + totalHeight);
speedLabel.draw(renderer);
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_h = totalHeight;
@ -422,4 +509,5 @@ AircraftLabel::AircraftLabel(Aircraft *p, bool metric, int screen_width, int scr
flightLabel.setFont(font);
altitudeLabel.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);
private:
SDL_Rect getFullRect(int labelLevel);
float calculateDensity(Aircraft *check_p, int labelLevel);
Aircraft *p;
Label flightLabel;
Label altitudeLabel;
Label speedLabel;
Label debugLabel;
int labelLevel;
float labelLevel;
bool metric;

View file

@ -1,7 +1,6 @@
#include "Label.h"
#include <string>
void Label::draw(SDL_Renderer *renderer) {
SDL_Rect rect = getRect();
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
@ -11,19 +10,8 @@ void Label::draw(SDL_Renderer *renderer) {
void Label::makeSurface() {
// if(BGColor.a = 0) {
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());
surface = TTF_RenderUTF8_Solid(font, text.c_str(), color);
}
}
SDL_Rect Label::getRect() {
SDL_Rect rect = {0,0,0,0};
@ -58,16 +46,12 @@ void Label::setFont(TTF_Font *font) {
this->font = font;
}
void Label::setFGColor(SDL_Color color) {
this->FGColor = color;
void Label::setColor(SDL_Color color) {
this->color = color;
}
void Label::setBGColor(SDL_Color color) {
this->BGColor = color;
}
//
Label::Label() {
BGColor = {0, 0, 0, 0};
this->color = {255,255,255,255};
surface = NULL;
}

View file

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

View file

@ -332,13 +332,13 @@ void View::drawStatusBox(int *left, int *top, std::string label, std::string mes
Label currentLabel;
currentLabel.setFont(labelFont);
currentLabel.setFGColor(style.buttonBackground);
currentLabel.setColor(style.buttonBackground);
currentLabel.setPosition(*left + labelFontWidth/2, *top);
currentLabel.setText(label);
currentLabel.draw(renderer);
currentLabel.setFont(messageFont);
currentLabel.setFGColor(color);
currentLabel.setColor(color);
currentLabel.setPosition(*left + labelWidth + messageFontWidth/2, *top);
currentLabel.setText(message);
currentLabel.draw(renderer);
@ -565,7 +565,7 @@ void View::drawScaleBars()
Label currentLabel;
currentLabel.setFont(mapFont);
currentLabel.setFGColor(style.scaleBarColor);
currentLabel.setColor(style.scaleBarColor);
currentLabel.setPosition(10+scaleBarDist, 15*screen_uiscale);
currentLabel.setText(scaleLabel);
currentLabel.draw(renderer);
@ -673,9 +673,11 @@ void View::drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen
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;
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) {
float dx, dy;