basic label physics setup
Former-commit-id: 0433115ef4f22f0fcd0a9e278992cc238e408176 Former-commit-id: f406ea69b05a5865c48132eec23e129d3066aac4
This commit is contained in:
parent
07c2dc4902
commit
42f1f8d5b5
|
@ -12,6 +12,10 @@
|
|||
|
||||
###HARDWARE
|
||||
|
||||
best option seems to be pi4 + pijuice zero (w/ rewired i2c) + hyperpixel 4. RTLSDR (stratux) sticks down or needs u shaped adapter.
|
||||
For future tuner, need to test audio phat w/ little speaker, i2c knob, etc.
|
||||
|
||||
|
||||
Notes:
|
||||
Pi 3b+ and below are a little underpowerd for unoptimized map drawing
|
||||
Pi 4 is smooth, may have USB issues with RTLSDR?
|
||||
|
|
310
draw.c
310
draw.c
|
@ -235,11 +235,11 @@ void drawTrail(double *oldDx, double *oldDy, double *oldHeading, time_t * oldSee
|
|||
screenCoords(&prevX, &prevY, dx, dy);
|
||||
|
||||
if(outOfBounds(currentX,currentY)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(outOfBounds(prevX,prevY)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
double age = pow(1.0 - (double)(now - oldSeen[currentIdx]) / TRAIL_TTL, 2.2);
|
||||
|
@ -250,7 +250,7 @@ void drawTrail(double *oldDx, double *oldDy, double *oldHeading, time_t * oldSee
|
|||
|
||||
uint8_t colorVal = (uint8_t)floor(255.0 * age);
|
||||
|
||||
//thickLineRGBA(appData.renderer, prevX, prevY, currentX, currentY, 4 * appData.screen_uiscale, colorVal, colorVal, colorVal, 127);
|
||||
thickLineRGBA(appData.renderer, prevX, prevY, currentX, currentY, 2 * appData.screen_uiscale, colorVal, colorVal, colorVal, 64);
|
||||
|
||||
//tick marks
|
||||
|
||||
|
@ -350,27 +350,6 @@ void drawGeography() {
|
|||
}
|
||||
}
|
||||
|
||||
void drawPlaneText(struct planeObj *p, int x, int y) {
|
||||
|
||||
drawStringBG(p->flight, x + 5, y + appData.mapFontHeight, appData.mapBoldFont, white, black);
|
||||
|
||||
char alt[10] = " ";
|
||||
if (Modes.metric) {
|
||||
snprintf(alt,10,"%dm", (int) (p->altitude / 3.2828));
|
||||
} else {
|
||||
snprintf(alt,10,"%d'", p->altitude);
|
||||
}
|
||||
drawStringBG(alt, x + 5, y + 2*appData.mapFontHeight, appData.mapFont, grey, black);
|
||||
|
||||
char speed[10] = " ";
|
||||
if (Modes.metric) {
|
||||
snprintf(speed,10,"%dkm/h", (int) (p->speed * 1.852));
|
||||
} else {
|
||||
snprintf(speed,10,"%dmph", p->speed);
|
||||
}
|
||||
drawStringBG(speed, x + 5, y + 3*appData.mapFontHeight, appData.mapFont, grey, black);
|
||||
}
|
||||
|
||||
void drawSignalMarks(struct planeObj *p, int x, int y) {
|
||||
unsigned char * pSig = p->signalLevel;
|
||||
unsigned int signalAverage = (pSig[0] + pSig[1] + pSig[2] + pSig[3] +
|
||||
|
@ -380,14 +359,256 @@ void drawSignalMarks(struct planeObj *p, int x, int y) {
|
|||
|
||||
Uint8 seenFade = (Uint8) (255.0 - (mstime() - p->msSeen) / 4.0);
|
||||
|
||||
circleRGBA(appData.renderer, x + 5 * appData.screen_uiscale, y + 10 * appData.screen_uiscale, 2 * appData.screen_uiscale, barColor.r, barColor.g, barColor.b, seenFade);
|
||||
circleRGBA(appData.renderer, x, y - 5, 2 * appData.screen_uiscale, barColor.r, barColor.g, barColor.b, seenFade);
|
||||
|
||||
seenFade = (Uint8) (255.0 - (mstime() - p->msSeenLatLon) / 4.0);
|
||||
|
||||
hlineRGBA(appData.renderer, x + 10 * appData.screen_uiscale, x + 14 * appData.screen_uiscale, y + 10 * appData.screen_uiscale, barColor.r, barColor.g, barColor.b, seenFade);
|
||||
vlineRGBA(appData.renderer, x + 12 * appData.screen_uiscale, y + 8 * appData.screen_uiscale, y + 12 * appData.screen_uiscale, barColor.r, barColor.g, barColor.b, seenFade);
|
||||
hlineRGBA(appData.renderer, x + 5 * appData.screen_uiscale, x + 9 * appData.screen_uiscale, y - 5, barColor.r, barColor.g, barColor.b, seenFade);
|
||||
vlineRGBA(appData.renderer, x + 7 * appData.screen_uiscale, y - 2 * appData.screen_uiscale - 5, y + 2 * appData.screen_uiscale - 5, barColor.r, barColor.g, barColor.b, seenFade);
|
||||
}
|
||||
|
||||
|
||||
void drawPlaneText(struct planeObj *p) {
|
||||
|
||||
drawSignalMarks(p, p->x, p->y);
|
||||
|
||||
int maxCharCount;
|
||||
int currentCharCount;
|
||||
|
||||
int currentLine = 0;
|
||||
|
||||
char flight[10] = " ";
|
||||
maxCharCount = snprintf(flight,10,"%s", p->flight);
|
||||
|
||||
if(maxCharCount > 0) {
|
||||
drawStringBG(flight, p->x, p->y, appData.mapBoldFont, white, black);
|
||||
currentLine++;
|
||||
}
|
||||
|
||||
char alt[10] = " ";
|
||||
if (Modes.metric) {
|
||||
currentCharCount = snprintf(alt,10,"%dm", (int) (p->altitude / 3.2828));
|
||||
} else {
|
||||
currentCharCount = snprintf(alt,10,"%d'", p->altitude);
|
||||
}
|
||||
|
||||
if(currentCharCount > 0) {
|
||||
drawStringBG(alt, p->x, p->y + currentLine * appData.mapFontHeight, appData.mapFont, grey, black);
|
||||
currentLine++;
|
||||
}
|
||||
|
||||
if(currentCharCount > maxCharCount) {
|
||||
maxCharCount = currentCharCount;
|
||||
}
|
||||
|
||||
char speed[10] = " ";
|
||||
if (Modes.metric) {
|
||||
currentCharCount = snprintf(speed,10,"%dkm/h", (int) (p->speed * 1.852));
|
||||
} else {
|
||||
currentCharCount = snprintf(speed,10,"%dmph", p->speed);
|
||||
}
|
||||
|
||||
if(currentCharCount > 0) {
|
||||
drawStringBG(speed, p->x, p->y + currentLine * appData.mapFontHeight, appData.mapFont, grey, black);
|
||||
currentLine++;
|
||||
}
|
||||
|
||||
if(currentCharCount > maxCharCount) {
|
||||
maxCharCount = currentCharCount;
|
||||
}
|
||||
|
||||
p->w = maxCharCount * appData.mapFontWidth;
|
||||
p->h = currentLine * appData.mapFontHeight;
|
||||
}
|
||||
|
||||
float sign(float x) {
|
||||
return (x > 0) - (x < 0);
|
||||
}
|
||||
|
||||
|
||||
void resolveLabelConflicts() {
|
||||
struct planeObj *p = planes;
|
||||
|
||||
while(p) {
|
||||
|
||||
struct planeObj *check_p = planes;
|
||||
|
||||
int p_left = p->x - 10 * appData.screen_uiscale;
|
||||
int p_right = p->x + p->w + 10 * appData.screen_uiscale;
|
||||
int p_top = p->y - 10 * appData.screen_uiscale;
|
||||
int p_bottom = p->y + p->h + 10 * appData.screen_uiscale;
|
||||
|
||||
//debug box
|
||||
//rectangleRGBA(appData.renderer, p->x, p->y, p->x + p->w, p->y + p->h, 255,0,0, SDL_ALPHA_OPAQUE);
|
||||
//lineRGBA(appData.renderer, p->cx, p->cy, p->x, p->y, 0,255,0, SDL_ALPHA_OPAQUE);
|
||||
|
||||
//apply damping
|
||||
|
||||
p->ddox -= 0.7f * p->dox;
|
||||
p->ddoy -= 0.7f * p->doy;
|
||||
|
||||
//spring back to origin
|
||||
p->ddox -= 0.05f * p->ox;
|
||||
p->ddoy -= 0.05f * p->oy;
|
||||
|
||||
// // //screen edge
|
||||
|
||||
if(p_left < 10 * appData.screen_uiscale) {
|
||||
p->ox += (float)(10 * appData.screen_uiscale - p_left);
|
||||
}
|
||||
|
||||
if(p_right > (appData.screen_width - 10 * appData.screen_uiscale)) {
|
||||
p->ox -= (float)(p_right - (appData.screen_width - 10 * appData.screen_uiscale));
|
||||
}
|
||||
|
||||
if(p_top < 10 * appData.screen_uiscale) {
|
||||
p->oy += (float)(10 * appData.screen_uiscale - p_top);
|
||||
}
|
||||
|
||||
if(p_bottom > (appData.screen_height - 10 * appData.screen_uiscale)) {
|
||||
p->oy -= (float)(p_bottom - (appData.screen_height - 10 * appData.screen_uiscale));
|
||||
}
|
||||
|
||||
|
||||
//check against other labels
|
||||
|
||||
while(check_p) {
|
||||
if(check_p->addr != p->addr) {
|
||||
|
||||
int check_left = check_p->x - 5 * appData.screen_uiscale;
|
||||
int check_right = check_p->x + check_p->w + 5 * appData.screen_uiscale;
|
||||
int check_top = check_p->y - 5 * appData.screen_uiscale;
|
||||
int check_bottom = check_p->y + check_p->h + 5 * appData.screen_uiscale;
|
||||
|
||||
//if(check_left > (p_right + 10) || check_right < (p_left - 10)) {
|
||||
if(check_left > p_right || check_right < p_left) {
|
||||
check_p = check_p -> next;
|
||||
continue;
|
||||
}
|
||||
|
||||
//if(check_top > (p_bottom + 10) || check_bottom < (p_top - 10)) {
|
||||
if(check_top > p_bottom || check_bottom < p_top) {
|
||||
check_p = check_p -> next;
|
||||
continue;
|
||||
}
|
||||
|
||||
//left collision
|
||||
if(check_left > p_left && check_left < p_right) {
|
||||
check_p->ddox -= 0.1f * (float)(check_left - p_right);
|
||||
}
|
||||
|
||||
//right collision
|
||||
if(check_right > p_left && check_right < p_right) {
|
||||
check_p->ddox -= 0.1f * (float)(check_right - p_left);
|
||||
}
|
||||
|
||||
//top collision
|
||||
if(check_top > p_top && check_top < p_bottom) {
|
||||
check_p->ddoy -= 0.1f * (float)(check_top - p_bottom);
|
||||
}
|
||||
|
||||
//bottom collision
|
||||
if(check_bottom > p_top && check_bottom < p_bottom) {
|
||||
check_p->ddoy -= 0.1f * (float)(check_bottom - p_top);
|
||||
}
|
||||
}
|
||||
check_p = check_p -> next;
|
||||
}
|
||||
|
||||
check_p = planes;
|
||||
|
||||
//check against plane icons (include self)
|
||||
|
||||
p_left = p->x - 5 * appData.screen_uiscale;
|
||||
p_right = p->x + 5 * appData.screen_uiscale;
|
||||
p_top = p->y - 5 * appData.screen_uiscale;
|
||||
p_bottom = p->y + 5 * appData.screen_uiscale;
|
||||
|
||||
while(check_p) {
|
||||
|
||||
int check_left = check_p->x - 5 * appData.screen_uiscale;
|
||||
int check_right = check_p->x + check_p->w + 5 * appData.screen_uiscale;
|
||||
int check_top = check_p->y - 5 * appData.screen_uiscale;
|
||||
int check_bottom = check_p->y + check_p->h + 5 * appData.screen_uiscale;
|
||||
|
||||
if(check_left > p_right || check_right < p_left) {
|
||||
check_p = check_p -> next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(check_top > p_bottom || check_bottom < p_top) {
|
||||
check_p = check_p -> next;
|
||||
continue;
|
||||
}
|
||||
|
||||
//left collision
|
||||
if(check_left > p_left && check_left < p_right) {
|
||||
check_p->ddox -= 0.1f * (float)(check_left - p_right);
|
||||
}
|
||||
|
||||
//right collision
|
||||
if(check_right > p_left && check_right < p_right) {
|
||||
check_p->ddox -= 0.1f * (float)(check_right - p_left);
|
||||
}
|
||||
|
||||
//top collision
|
||||
if(check_top > p_top && check_top < p_bottom) {
|
||||
check_p->ddoy -= 0.1f * (float)(check_top - p_bottom);
|
||||
}
|
||||
|
||||
//bottom collision
|
||||
if(check_bottom > p_top && check_bottom < p_bottom) {
|
||||
check_p->ddoy -= 0.1f * (float)(check_bottom - p_top);
|
||||
}
|
||||
|
||||
check_p = check_p -> next;
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
//update
|
||||
|
||||
p = planes;
|
||||
|
||||
while(p) {
|
||||
//incorporate accelerate from label conflict resolution
|
||||
|
||||
p->dox += p->ddox;
|
||||
p->doy += p->ddoy;
|
||||
|
||||
if(fabs(p->dox) > 10.0f) {
|
||||
p->dox = sign(p->dox) * 10.0f;
|
||||
}
|
||||
|
||||
if(fabs(p->doy) > 10.0f) {
|
||||
p->doy = sign(p->doy) * 10.0f;
|
||||
}
|
||||
|
||||
if(fabs(p->dox) < 1.0f) {
|
||||
p->dox = 0;
|
||||
}
|
||||
|
||||
if(fabs(p->doy) < 1.0f) {
|
||||
p->doy = 0;
|
||||
}
|
||||
|
||||
p->ox += p->dox;
|
||||
p->oy += p->doy;
|
||||
|
||||
//printf("p_ox: %f, p_oy %f\n",p->ox, p->oy);
|
||||
|
||||
p->ddox = 0;
|
||||
p->ddoy = 0;
|
||||
|
||||
p->x = p->cx + (int)round(p->ox);
|
||||
p->y = p->cy + (int)round(p->oy);
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawMap() {
|
||||
struct planeObj *p = planes;
|
||||
time_t now = time(NULL);
|
||||
|
@ -396,12 +617,17 @@ void drawMap() {
|
|||
|
||||
drawGrid();
|
||||
|
||||
//for(int i = 0; i < 2; i++) {
|
||||
resolveLabelConflicts();
|
||||
//}
|
||||
|
||||
//draw all trails first so they don't cover up planes and text
|
||||
|
||||
while(p) {
|
||||
if ((now - p->seen) < Modes.interactive_display_ttl) {
|
||||
drawTrail(p->oldLon, p->oldLat, p->oldHeading, p->oldSeen, p->oldIdx);
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
|
@ -424,13 +650,6 @@ void drawMap() {
|
|||
planeColor = white;
|
||||
}
|
||||
|
||||
if(outOfBounds(x,y)) {
|
||||
int outx, outy;
|
||||
drawPlaneOffMap(x, y, &outx, &outy, planeColor);
|
||||
drawPlaneText(p, outx, outy);
|
||||
}
|
||||
|
||||
|
||||
if(p->created == 0) {
|
||||
p->created = mstime();
|
||||
}
|
||||
|
@ -457,13 +676,28 @@ void drawMap() {
|
|||
usey = y + (mstime() - p->msSeenLatLon) * vely;
|
||||
}
|
||||
|
||||
|
||||
if(outOfBounds(x,y)) {
|
||||
drawPlaneOffMap(x, y, &(p->cx), &(p->cy), planeColor);
|
||||
thickLineRGBA(appData.renderer, p->cx, p->cy, p->x+(p->w>>2), p->y, appData.screen_uiscale, 200,200,200,SDL_ALPHA_OPAQUE);
|
||||
} else {
|
||||
drawPlaneHeading(usex, usey, p->track, planeColor);
|
||||
drawSignalMarks(p, usex, usey);
|
||||
drawPlaneText(p, usex, usey);
|
||||
lineRGBA(appData.renderer, usex, usey, usex, usey + 4*appData.mapFontHeight, grey.r, grey.g, grey.b, SDL_ALPHA_OPAQUE);
|
||||
|
||||
p->cx = usex;// + 5;
|
||||
p->cy = usey;// + 10 * appData.screen_uiscale;
|
||||
|
||||
if(p->cx != 0 && p->cy != 0 && p->x != 0 && p->y != 0) {
|
||||
|
||||
thickLineRGBA(appData.renderer, usex, usey, p->x+(p->w>>2), p->y, appData.screen_uiscale, 200,200,200, SDL_ALPHA_OPAQUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drawPlaneText(p);
|
||||
|
||||
|
||||
} else {
|
||||
drawPlane(x, y, planeColor);
|
||||
//drawPlane(x, y, planeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
3329d96b9e8da09d38ac06e8cfcb2c9227d0593e
|
||||
a17d06a73e34e6e65d1ff9ed411da79667154ca6
|
|
@ -1 +1 @@
|
|||
2c4ed2ab46ef6a542479d8c3c9ea7de7298325c1
|
||||
2305764a62eb8dd80a5f71e908a04bfaa9bc3cc9
|
6
mapbox_testing
Normal file
6
mapbox_testing
Normal file
|
@ -0,0 +1,6 @@
|
|||
curl "https://api.mapbox.com/v4/mapbox.mapbox-streets-v8/8/40/89.mvt?access_token=pk.eyJ1Ijoibm1hdHN1ZGEiLCJhIjoiY2swazhrdGNjMGZ3NzNvcmE0OGxoaGd2byJ9.PAYHqO3any_6vLdjQ44RGw"
|
||||
|
||||
mapbox://styles/nmatsuda/ck0k7rvvt3rkv1cq6l74wjda2
|
||||
|
||||
|
||||
47.695,-123.489
|
12
planeObj.c
12
planeObj.c
|
@ -31,6 +31,18 @@ struct planeObj *createPlaneObj(struct aircraft *a) {
|
|||
p->oldIdx = 0;
|
||||
p->prev_seen = 0;
|
||||
|
||||
p->x = 0;
|
||||
p->y = 0;
|
||||
p->cx = 0;
|
||||
p->cy = 0;
|
||||
|
||||
p->ox = 0;
|
||||
p->oy = 0;
|
||||
p->dox = 0;
|
||||
p->doy = 0;
|
||||
p->ddox = 0;
|
||||
p->ddoy = 0;
|
||||
|
||||
memset(p->oldLon, 0, sizeof(p->oldLon));
|
||||
memset(p->oldLat, 0, sizeof(p->oldLat));
|
||||
memset(p->oldHeading, 0, sizeof(p->oldHeading));
|
||||
|
|
BIN
planeObj.o
BIN
planeObj.o
Binary file not shown.
|
@ -1 +1 @@
|
|||
e28b70359d329c69b61d0da196a74552ba4f6f8f
|
||||
30a2da16b88ee34ce3413fff471b01c956184f32
|
|
@ -72,6 +72,12 @@ struct planeObj {
|
|||
int live;
|
||||
|
||||
struct planeObj *next; // Next aircraft in our linked list
|
||||
|
||||
//// label stuff
|
||||
|
||||
int x, y, cx, cy, w, h;
|
||||
float ox, oy, dox, doy, ddox, ddoy;
|
||||
|
||||
};
|
||||
|
||||
struct planeObj *planes;
|
||||
|
|
|
@ -1 +1 @@
|
|||
ae65e041076e061971bc7b3d686bee6c5f471abd
|
||||
8994067f92a4d800070c11716a732a5636bb6e5b
|
|
@ -1 +1 @@
|
|||
566004a350fc256a0bc6ab112a14b09c91e6cc18
|
||||
a549061b45cd62ae3ca46ebf3b8e29c4956b9641
|
Loading…
Reference in a new issue