Last active
January 25, 2024 13:37
-
-
Save Kiterai/f604cb222aaa071e1080736cbed806eb to your computer and use it in GitHub Desktop.
syncronous world clock(WIP)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <math.h> | |
#include "GUI_Paint.h" | |
#include "utils.h" | |
#include "world.h" | |
#define SCALE_L1 105 | |
#define SCALE_L2 120 | |
#define DISPLAY_CENTERX 120 | |
#define DISPLAY_CENTERY 120 | |
// for test | |
void draw_world_mercator() { | |
for (int y = 0; y < 240; y++) { | |
for (int x = 0; x < 240; x++) { | |
Paint_DrawPoint(x, y, world[((y / 2) * IMG_WIDTH) + x], DOT_PIXEL_1X1, DOT_FILL_RIGHTUP); | |
} | |
} | |
} | |
// azimuthal equidistant projection | |
void draw_world(float rotate) { | |
for (int y = 0; y < 240; y++) { | |
for (int x = 0; x < 240; x++) { | |
float d = sqrtf((x - 120) * (x - 120) + (y - 120) * (y - 120)); | |
float worldy = d * (IMG_HEIGHT / 120.0f); | |
float worldx = atan2f(-(y - 120), x - 120) / (2.0f * 3.14159265) + 0.5f; // [0, 1] | |
worldx += rotate / 360.0f; | |
worldx *= IMG_WIDTH; | |
while(worldx >= IMG_WIDTH) worldx -= IMG_WIDTH; | |
uint16_t code = sampling_bilinear(worldx, worldy); | |
code = set_brightness_rgb565(code, clamp(115 - x, -10, 0) * 2); | |
Paint_SetPixel(x, y, code); | |
} | |
} | |
} | |
// azimuthal equidistant projection with till (WIP) | |
void draw_world_with_till(float rotate, float center_lat, float center_lon) { | |
const float sin_phi1 = sinf(center_lat); | |
const float cos_phi1 = cosf(center_lat); | |
for (int y = 0; y < 240; y++) { | |
for (int x = 0; x < 240; x++) { | |
// https://mathworld.wolfram.com/AzimuthalEquidistantProjection.html | |
const float nx = (x - DISPLAY_CENTERX) * (3.14159265f / 120); | |
const float ny = -(y - DISPLAY_CENTERY) * (3.14159265f / 120); | |
const float c = sqrtf(nx * nx + ny * ny); | |
const float sin_c = sinf(c); | |
const float cos_c = cosf(c); | |
const float phi = asinf(cos_c * sin_phi1 + (ny * sin_c * cos_phi1) / c); | |
const float lambda = center_lon + atan2f(c * cos_phi1 * cos_c - ny * sin_phi1 * sin_c, nx * sin_c); | |
float worldy = ((phi / 3.14159265f) + 0.5f) * IMG_HEIGHT; | |
float worldx = lambda / (2.0f * 3.14159265f) + 0.5f; // [0, 1] | |
worldx += rotate / 360.0f; | |
worldx *= IMG_WIDTH; | |
while(worldx >= IMG_WIDTH) worldx -= IMG_WIDTH; | |
uint16_t code = sampling_bilinear(worldx, worldy); | |
code = set_brightness_rgb565(code, clamp(115 - x, -10, 0) * 2); | |
Paint_SetPixel(x, y, code); | |
} | |
} | |
} | |
void draw_scale() { | |
char buf[4]; | |
for(uint16_t i = 0; i < 24; i++) { | |
float x1 = 110 * cosf((3.141592f / 12.0f) * (i + 0.65f)); | |
float y1 = 110 * sinf((3.141592f / 12.0f) * (i + 0.65f)); | |
uint16_t num = 23 - i; | |
buf[0] = num >= 10 ? (num / 10 + '0') : ' '; | |
buf[1] = num % 10 + '0'; | |
buf[2] = '\0'; | |
Paint_DrawString_EN((uint16_t)(DISPLAY_CENTERX + x1 - 7) + 1, DISPLAY_CENTERY + y1 - 6, buf, &Font12, WHITE, WHITE); | |
Paint_DrawString_EN(DISPLAY_CENTERX + x1 - 7, (uint16_t)(DISPLAY_CENTERY + y1 - 6) + 1, buf, &Font12, WHITE, WHITE); | |
Paint_DrawString_EN((uint16_t)(DISPLAY_CENTERX + x1 - 7) - 1, DISPLAY_CENTERY + y1 - 6, buf, &Font12, WHITE, WHITE); | |
Paint_DrawString_EN(DISPLAY_CENTERX + x1 - 7, (uint16_t)(DISPLAY_CENTERY + y1 - 6) - 1, buf, &Font12, WHITE, WHITE); | |
// Font12 is 7x12 sized font, 2 char->14x12, to centerize->(-7,-6)shift | |
Paint_DrawString_EN(DISPLAY_CENTERX + x1 - 7, DISPLAY_CENTERY + y1 - 6, buf, &Font12, BLACK, WHITE); | |
} | |
for(uint16_t i = 0; i < 24; i++) { | |
float x1 = SCALE_L1 * cosf(3.141592 / 12 * i); | |
float y1 = SCALE_L1 * sinf(3.141592 / 12 * i); | |
float x2 = SCALE_L2 * cosf(3.141592 / 12 * i); | |
float y2 = SCALE_L2 * sinf(3.141592 / 12 * i); | |
Paint_DrawLine( | |
DISPLAY_CENTERX + x1, DISPLAY_CENTERY + y1, | |
DISPLAY_CENTERX + x2, DISPLAY_CENTERY + y2, | |
BLACK, DOT_PIXEL_2X2, LINE_STYLE_SOLID); | |
Paint_DrawLine( | |
DISPLAY_CENTERX + x1, DISPLAY_CENTERY + y1, | |
DISPLAY_CENTERX + x2, DISPLAY_CENTERY + y2, | |
WHITE, DOT_PIXEL_1X1, LINE_STYLE_SOLID); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void draw_world_mercator(); | |
void draw_world(float rotate); | |
void draw_world_with_till(float rotate, float center_lat, float center_lon); | |
void draw_scale(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "DEV_Config.h" | |
#include "GUI_Paint.h" | |
#include "LCD_1in28.h" | |
#include "hardware/rtc.h" | |
#include "pico/stdlib.h" | |
#include "pico/util/datetime.h" | |
#include <stdio.h> | |
#include <math.h> | |
#include "draw.h" | |
#include "world.h" | |
int main(void) { | |
if (DEV_Module_Init() != 0) | |
return -1; | |
LCD_1IN28_Init(HORIZONTAL); | |
LCD_1IN28_Clear(WHITE); | |
DEV_SET_PWM(60); // set backlight | |
UDOUBLE Imagesize = LCD_1IN28_HEIGHT * LCD_1IN28_WIDTH * 2; | |
UWORD *BlackImage; | |
if ((BlackImage = (UWORD *)malloc(Imagesize)) == NULL) | |
{ | |
printf("Failed to apply for black memory...\r\n"); | |
exit(0); | |
} | |
Paint_NewImage((UBYTE *)BlackImage, LCD_1IN28.WIDTH, LCD_1IN28.HEIGHT, 0, WHITE); | |
Paint_SetScale(65); | |
Paint_Clear(WHITE); | |
datetime_t t = { | |
.year = 2024, | |
.month = 1, | |
.day = 24, | |
.dotw = 3, // 0 is Sunday, so 5 is Friday | |
.hour = 10, | |
.min = 0, | |
.sec = 0 | |
}; | |
rtc_init(); | |
rtc_set_datetime(&t); | |
sleep_us(64); | |
float rotate = 0.0; // degree | |
bool k = 0; | |
while (true) | |
{ | |
rtc_get_datetime(&t); | |
rotate = (86400 - t.hour * 3600 + t.min * 60 + t.sec) / 240.0f; // 240 = 86400 sec / 360 deg | |
draw_world_with_till(rotate, -3.14159265f / 2, 0); | |
draw_scale(); | |
LCD_1IN28_Display(BlackImage); | |
} | |
free(BlackImage); | |
BlackImage = NULL; | |
DEV_Module_Exit(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "world.h" | |
uint16_t gen_rgb565(uint16_t r, uint16_t g, uint16_t b) { | |
uint16_t code = 0; | |
code |= (r & 0b11111); | |
code <<= 6; | |
code |= (g & 0b111111); | |
code <<= 5; | |
code |= (b & 0b11111); | |
return code; | |
} | |
uint16_t get_r_rgb565(uint16_t code) { | |
return ((code >> 11) & 0b11111); | |
} | |
uint16_t get_g_rgb565(uint16_t code) { | |
return ((code >> 5) & 0b111111); | |
} | |
uint16_t get_b_rgb565(uint16_t code) { | |
return ((code >> 0) & 0b11111); | |
} | |
int clamp(int v, int min, int max) { | |
if(v < min) | |
return min; | |
if(v > max) | |
return max; | |
return v; | |
} | |
uint16_t set_brightness_rgb565(uint16_t code, int16_t brightness) { | |
return gen_rgb565( | |
clamp((get_r_rgb565(code) + brightness / 2), 0, 31), | |
clamp((get_g_rgb565(code) + brightness), 0, 63), | |
clamp((get_b_rgb565(code) + brightness / 2), 0, 31) | |
); | |
} | |
uint16_t sampling(uint16_t y, uint16_t x) { | |
y = clamp(y, 0, IMG_HEIGHT - 1); | |
if(x >= IMG_WIDTH) x -= 360; | |
if(x < 0) x += 360; | |
return world[y * IMG_WIDTH + x]; | |
} | |
uint16_t sampling_bilinear(float worldx, float worldy) { | |
uint16_t worldx0 = worldx; | |
uint16_t worldy0 = worldy; | |
uint16_t worldx1 = worldx0 + 1; | |
uint16_t worldy1 = worldy0 + 1; | |
float dx0 = worldx - worldx0; | |
float dy0 = worldy - worldy0; | |
float dx1 = 1 - dx0; | |
float dy1 = 1 - dy0; | |
uint16_t c00 = sampling(worldy0, worldx0); | |
uint16_t c01 = sampling(worldy0, worldx1); | |
uint16_t c10 = sampling(worldy1, worldx0); | |
uint16_t c11 = sampling(worldy1, worldx1); | |
return gen_rgb565( | |
get_r_rgb565(c00) * dy1 * dx1 + get_r_rgb565(c01) * dy1 * dx0 + get_r_rgb565(c10) * dy0 * dx1 + get_r_rgb565(c11) * dy0 * dx0, | |
get_g_rgb565(c00) * dy1 * dx1 + get_g_rgb565(c01) * dy1 * dx0 + get_g_rgb565(c10) * dy0 * dx1 + get_g_rgb565(c11) * dy0 * dx0, | |
get_b_rgb565(c00) * dy1 * dx1 + get_b_rgb565(c01) * dy1 * dx0 + get_b_rgb565(c10) * dy0 * dx1 + get_b_rgb565(c11) * dy0 * dx0 | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
uint16_t gen_rgb565(uint16_t r, uint16_t g, uint16_t b); | |
uint16_t get_r_rgb565(uint16_t code); | |
uint16_t get_g_rgb565(uint16_t code); | |
uint16_t get_b_rgb565(uint16_t code); | |
int clamp(int v, int min, int max); | |
uint16_t set_brightness_rgb565(uint16_t code, int16_t brightness); | |
uint16_t sampling(uint16_t y, uint16_t x); | |
uint16_t sampling_bilinear(float worldx, float worldy); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment