diff --git a/AircraftLabel.cpp b/AircraftLabel.cpp index 0dddd34..9469c17 100644 --- a/AircraftLabel.cpp +++ b/AircraftLabel.cpp @@ -32,12 +32,12 @@ SDL_Rect AircraftLabel::getFullRect(int labelLevel) { } if(labelLevel < 1) { - currentRect = altitudeLabel.getRect(); + currentRect = altitudeLabel.getRect(); rect.w = std::max(rect.w,currentRect.w); rect.h += currentRect.h; - currentRect = speedLabel.getRect(); + currentRect = speedLabel.getRect(); rect.w = std::max(rect.w,currentRect.w); rect.h += currentRect.h; @@ -132,20 +132,20 @@ float AircraftLabel::calculateDensity(Aircraft *check_p, int labelLevel) { } void AircraftLabel::calculateForces(Aircraft *check_p) { - if(w == 0 || h == 0) { - return; - } + //if(w == 0 || h == 0) { +// return; +// } - Aircraft *head = check_p; + Aircraft *head = check_p; - int p_left = x; - int p_right = x + w; - int p_top = y; - int p_bottom = y + h; + float p_left = static_cast(x); + float p_right = static_cast(x + w); + float p_top = static_cast(y); + float p_bottom = static_cast(y + h); - float boxmid_x = static_cast(p_left + p_right) / 2.0f; - float boxmid_y = static_cast(p_top + p_bottom) / 2.0f; + float boxmid_x = (p_left + p_right) / 2.0f; + float boxmid_y = (p_top + p_bottom) / 2.0f; float offset_x = boxmid_x - p->x; float offset_y = boxmid_y - p->y; @@ -162,19 +162,19 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { // screen edge if(p_left < edge_margin) { - ddx += boundary_force * static_cast(edge_margin - p_left); + ddx += boundary_force * (edge_margin - p_left); } if(p_right > screen_width - edge_margin) { - ddx += boundary_force * static_cast(screen_width - edge_margin - p_right); + ddx += boundary_force * (screen_width - edge_margin - p_right); } if(p_top < edge_margin) { - ddy += boundary_force * static_cast(edge_margin - p_top); + ddy += boundary_force * (edge_margin - p_top); } if(p_bottom > screen_height - edge_margin) { - ddy += boundary_force * static_cast(screen_height - edge_margin - p_bottom); + ddy += boundary_force * (screen_height - edge_margin - p_bottom); } @@ -194,17 +194,18 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { continue; } - 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; - int check_bottom = check_p->label->y + check_p->label->h; + float check_left = static_cast(check_p->label->x); + float check_right = static_cast(check_p->label->x + check_p->label->w); + float check_top = static_cast(check_p->label->y); + float check_bottom = static_cast(check_p->label->y + check_p->label->h); float icon_x = static_cast(check_p->x); float icon_y = static_cast(check_p->y); float checkboxmid_x = static_cast(check_left + check_right) / 2.0f; - float checkboxmid_y = static_cast(check_top + check_bottom) / 2.0f; + float checkboxmid_y = static_cast(check_top + check_bottom) / 2.0f; + /* float offset_x = boxmid_x - checkboxmid_x; float offset_y = boxmid_y - checkboxmid_y; @@ -213,16 +214,83 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { float x_mag = std::max(0.0f,(target_length_x - fabs(offset_x))); float y_mag = std::max(0.0f,(target_length_y - fabs(offset_y))); + + */ + + bool overlap = true; + + if (p_left >= check_right + 10 || check_left >= p_right + 10) + overlap = false; + + if (p_top >= check_bottom + 10|| check_top >= p_bottom + 10) + overlap = false; + + if(overlap) { + + float td = fabs(p_top - check_bottom); + float bd = fabs(p_bottom - check_top); + float ld = fabs(p_left - check_right); + float rd = fabs(p_right - check_left); + + float x_mag, y_mag; + + if(boxmid_y > checkboxmid_y) { + y_mag = check_bottom - p_top + 10; + } else { + y_mag = check_top - p_bottom - 10; + td = bd; + } + + if(boxmid_x > checkboxmid_x) { + x_mag = check_right - p_left + 10; + } else { + x_mag = check_left - p_right - 10; + ld = rd; + } + + if(td < ld) { + x_mag = 0; + } else { + y_mag = 0; + } + + ddx += label_force * x_mag; + ddy += label_force * y_mag; + } + + // stay at least label_dist away from other icons + if(p_right >= check_p->x && check_p->x >= p_left && p_bottom >= check_p->y && check_p->y >= p_top) { + float x_mag, y_mag; + + if(boxmid_x - check_p->x > 0) { + x_mag = check_p->x - p_left + 10; + } else { + x_mag = check_p->x - p_right - 10; + } + + if(boxmid_y - check_p->y > 0) { + y_mag = check_p->y - p_top + 10; + } else { + y_mag = check_p->y - p_bottom - 10; + } + + ddx += icon_force * x_mag; + ddy += icon_force * y_mag; + + } + /* if(x_mag > 0 && y_mag > 0) { ddx += sign(offset_x) * label_force * x_mag; ddy += sign(offset_y) * label_force * y_mag; } - // stay at least icon_dist away from other icons + */ + // stay at least icon_dist away from other icons + /* offset_x = boxmid_x - check_p->x; offset_y = boxmid_y - check_p->y; @@ -237,9 +305,10 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { ddy += sign(offset_y) * icon_force * y_mag; } + */ all_x += sign(boxmid_x - checkboxmid_x); all_y += sign(boxmid_y - checkboxmid_y); - + count++; check_p = check_p -> next; @@ -250,34 +319,63 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { ddy += density_force * all_y / count; // char buff[100]; - // snprintf(buff, sizeof(buff), "%2.2f", labelLevel); + // snprintf(buff, sizeof(buff), "l:%2.2f d:%2.2f", labelLevel, calculateDensity(head, labelLevel)); // debugLabel.setText(buff); - float density_mult = 0.5f; + float density_mult = 0.15f; float level_rate = 0.25f; - if(elapsed(lastLevelChange) > 1000.0) { - if(labelLevel < 0.8f * density_mult * calculateDensity(head, labelLevel + 1)) { - if(labelLevel <= 2) { - labelLevel += level_rate; - lastLevelChange = now(); - } - } else if (labelLevel > 1.2f * density_mult * calculateDensity(head, labelLevel - 1)) { - if(labelLevel >= 0) { + float randtime = 5000.0f + 5000.0f * static_cast (rand()) / static_cast (RAND_MAX); + if(elapsed(lastLevelChange) > randtime) { + if(labelLevel < -1.2f + density_mult * calculateDensity(head, labelLevel - 1)) { + if(labelLevel <= 2) { + if(ceil(labelLevel) - labelLevel <= level_rate) { + labelLevel += 0.5f; + } + + labelLevel += level_rate; + lastLevelChange = now(); + } + } else if (labelLevel > 1.2f + density_mult * calculateDensity(head, labelLevel + 1)) { + if(labelLevel >= 0) { + if(labelLevel - floor(labelLevel) <= level_rate) { + labelLevel -= 0.5f; + } + labelLevel -= level_rate; - lastLevelChange = now(); - } + lastLevelChange = now(); + } } } + + + //add drag force + ddx -= drag_force * dx * dx * sign(dx); + ddy -= drag_force * dy * dy * sign(dy); } void AircraftLabel::applyForces() { - dx += ddx; - dy += ddy; + float new_dx = dx + ddx; + float new_dy = dy + ddy; + + new_dx *= damping_force; + new_dy *= damping_force; + + /* + if(sign(new_dx) != sign(dx) && dx != 0) { + new_dx = 0; + } + + if(sign(new_dy) != sign(dy) && dy != 0) { + new_dy = 0; + } + */ + + //if(dx > 0 || dy > 0 || new_dx > 0.01 || new_dy > 0.01) { + dx = new_dx; + dy = new_dy; + //} - dx *= damping_force; - dy *= damping_force; - if(fabs(dx) > velocity_limit) { dx = sign(dx) * velocity_limit; } @@ -294,9 +392,33 @@ void AircraftLabel::applyForces() { dy = 0; } - x += dx; - y += dy; + float new_x = 0; + float new_y = 0; + for(int i = 0; i < buffer_length; i++) { + new_x += x_buffer[i] / static_cast(buffer_length); + new_y += y_buffer[i] / static_cast(buffer_length); + } + + x_buffer[buffer_idx] = new_x + dx; + y_buffer[buffer_idx] = new_y + dy; + + buffer_idx = (buffer_idx + 1) % buffer_length; + + //new_x += dx; + //new_y += dy; + + //new_x = x + dx; + //new_y = y + dy; + + //if(abs(new_x - x) > 1 || abs(new_y - y) > 1) { + x = new_x; + y = new_y; + //} + + //x += dx; + //y += dy; + if(isnan(x)) { x = 0; } @@ -347,6 +469,15 @@ void AircraftLabel::applyForces() { // } // } +void AircraftLabel::move(float dx, float dy) { + for(int i = 0; i < buffer_length; i++ ){ + x_buffer[i] += dx; + y_buffer[i] += dy; + } + + x+=dx; + y+=dy; +} void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) { if(x == 0 || y == 0) { @@ -374,9 +505,9 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) { target_opacity = 0.0f; } - opacity += 0.25f * (target_opacity - opacity); + opacity += 0.15f * (target_opacity - opacity); - if(opacity < 0.05f) { + if(opacity < 0.005f) { opacity = 0; } @@ -516,14 +647,20 @@ AircraftLabel::AircraftLabel(Aircraft *p, bool metric, int screen_width, int scr target_w = 0; target_h = 0; - opacity = 0; - target_opacity = 0; + opacity = 0.0f; + target_opacity = 0.0f; dx = 0; dy = 0; ddx = 0; ddy = 0; + for(int i = 0; i < buffer_length; i++) { + x_buffer[i] = x; + y_buffer[i] = y; + } + buffer_idx = 0; + this->screen_width = screen_width; this->screen_height = screen_height; @@ -535,4 +672,4 @@ AircraftLabel::AircraftLabel(Aircraft *p, bool metric, int screen_width, int scr debugLabel.setFont(font); lastLevelChange = now(); -} \ No newline at end of file +} diff --git a/AircraftLabel.h b/AircraftLabel.h index 79c9fa9..a6052e7 100644 --- a/AircraftLabel.h +++ b/AircraftLabel.h @@ -15,6 +15,7 @@ class AircraftLabel { void clearAcceleration(); void calculateForces(Aircraft *check_p); void applyForces(); + void move(float dx, float dy); void draw(SDL_Renderer *renderer, bool selected); @@ -45,6 +46,12 @@ class AircraftLabel { float dx; float dy; + + float x_buffer[15]; + float y_buffer[15]; + int buffer_idx; + int buffer_length = 15; + float ddx; float ddy; @@ -60,17 +67,19 @@ class AircraftLabel { /////////// - float label_force = 0.001f; + float label_force = 0.01f; float label_dist = 2.0f; - float density_force = 0.05f; - float attachment_force = 0.0015f; + float density_force = 0.01f; + float attachment_force = 0.01f; float attachment_dist = 10.0f; - float icon_force = 0.001f; + float icon_force = 0.01f; float icon_dist = 15.0f; float boundary_force = 0.01f; - float damping_force = 0.85f; - float velocity_limit = 2.0f; + float damping_force = 0.65f; + float velocity_limit = 1.0f; float edge_margin = 15.0f; + float drag_force = 0.00f; + Style style; }; diff --git a/Label.cpp b/Label.cpp index 91efb23..d3f3b5f 100644 --- a/Label.cpp +++ b/Label.cpp @@ -59,7 +59,7 @@ void Label::setColor(SDL_Color color) { } // Label::Label() { - this->color = {255,255,255,255}; + this->color = {0,0,0,0}; surface = NULL; } diff --git a/Style.h b/Style.h index a30eafc..cf0d7a1 100644 --- a/Style.h +++ b/Style.h @@ -68,20 +68,20 @@ typedef struct Style { blue = {0,0,255,255}; - backgroundColor = {200,200,200,255}; + backgroundColor = {0,0,0,255}; selectedColor = pink; - planeColor = black; + planeColor = {0,255,174}; planeGoneColor = grey; - trailColor = grey; + trailColor = {0,255,174}; geoColor = grey_dark; airportColor = grey; - labelColor = black; + labelColor = white; labelLineColor = grey_dark; subLabelColor = grey; - labelBackground = grey_light; + labelBackground = black; scaleBarColor = grey_light; buttonColor = grey_light; buttonBackground = black; @@ -91,4 +91,4 @@ typedef struct Style { } } Style; -#endif \ No newline at end of file +#endif diff --git a/View.cpp b/View.cpp index 5af6a27..f9f0913 100644 --- a/View.cpp +++ b/View.cpp @@ -450,12 +450,6 @@ void View::drawTrails(int left, int top, int right, int bottom) { return; } - SDL_Color color = lerpColor(style.trailColor, style.planeGoneColor, static_cast(elapsed_s(p->msSeen)) / DISPLAY_ACTIVE); - - if(p == selectedAircraft) { - color = style.selectedColor; - } - std::vector::iterator lon_idx = p->lonHistory.begin(); std::vector::iterator lat_idx = p->latHistory.begin(); std::vector::iterator heading_idx = p->headingHistory.begin(); @@ -474,6 +468,9 @@ void View::drawTrails(int left, int top, int right, int bottom) { continue; } + + SDL_Color color = lerpColor({255,0,0,255}, {255,200,0,255}, age / static_cast(p->lonHistory.size())); + uint8_t colorVal = (uint8_t)floor(127.0 * (age / static_cast(p->lonHistory.size()))); //thickLineRGBA(renderer, prevX, prevY, currentX, currentY, 2 * screen_uiscale, 255, 255, 255, colorVal); @@ -744,6 +741,19 @@ void View::drawPlaneText(Aircraft *p) { p->label->draw(renderer, (p == selectedAircraft)); } +void View::moveLabels(float dx, float dy) { + Aircraft *p = appData->aircraftList.head; + + while(p) { + if(p->label) { + p->label->move(dx,dy); + } + + p = p->next; + } +} + + float View::resolveLabelConflicts() { float maxV = 0.0f; @@ -855,6 +865,8 @@ void View::animateCenterAbsolute(float x, float y) { float dx = -1.0 * (0.75*(double)screen_width / (double)screen_height) * (x - screen_width/2) * maxDist / (0.95 * scale_factor * 0.5); float dy = 1.0 * (y - screen_height/2) * maxDist / (0.95 * scale_factor * 0.5); + moveLabels(x,y); + float outLat = dy * (1.0/6371.0) * (180.0f / M_PI); float outLon = dx * (1.0/6371.0) * (180.0f / M_PI) / cos(((centerLat)/2.0f) * M_PI / 180.0f); @@ -873,6 +885,8 @@ void View::moveCenterAbsolute(float x, float y) { float dx = -1.0 * (0.75*(double)screen_width / (double)screen_height) * (x - screen_width/2) * maxDist / (0.95 * scale_factor * 0.5); float dy = 1.0 * (y - screen_height/2) * maxDist / (0.95 * scale_factor * 0.5); + moveLabels(x,y); + float outLat = dy * (1.0/6371.0) * (180.0f / M_PI); float outLon = dx * (1.0/6371.0) * (180.0f / M_PI) / cos(((centerLat)/2.0f) * M_PI / 180.0f); @@ -891,6 +905,8 @@ void View::moveCenterRelative(float dx, float dy) { // need to make lonlat to screen conversion class - this is just the inverse of the stuff in draw.c, without offsets // + moveLabels(dx,dy); + float scale_factor = (screen_width > screen_height) ? screen_width : screen_height; dx = -1.0 * dx * maxDist / (0.95 * scale_factor * 0.5); diff --git a/View.h b/View.h index 2bf586d..0034dc8 100644 --- a/View.h +++ b/View.h @@ -85,6 +85,7 @@ class View { SDL_Rect drawStringBG(std::string text, int x, int y, TTF_Font *font, SDL_Color color, SDL_Color bgColor); void drawStatusBox(int *left, int *top, std::string label, std::string message, SDL_Color color); void drawStatus(); + void moveLabels(float dx, float dy); Aircraft *selectedAircraft; diff --git a/gmon.out b/gmon.out new file mode 100644 index 0000000..eb55a69 Binary files /dev/null and b/gmon.out differ diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..a1e5598 --- /dev/null +++ b/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +startx ./viz1090 --screensize 360 360 --fullscreen --server adsb --lat 47.6 --lon -122.3