Skip to content

Instantly share code, notes, and snippets.

@jimfinnis
Created April 20, 2025 09:47
Show Gist options
  • Select an option

  • Save jimfinnis/352ccaa00caae9155c592e7b75c80528 to your computer and use it in GitHub Desktop.

Select an option

Save jimfinnis/352ccaa00caae9155c592e7b75c80528 to your computer and use it in GitHub Desktop.
Rendering the phase of the moon accurately on an ST7735 using Bodmer's TFT_eSPI library
void display_moon(float phase, int16_t x, int16_t y, int16_t r){
// phase here is 0-1, where 0 and 1 are new and 0.5 is full.
// The x and y are the centre of the moon, and size is the radius of the moon.
// Yes, there's a lot of duplication here. Could be tidied up.
float n; // generally means "amount illuminated" or "amount not illuminated"
if(phase<0.25){
// we fill a circle and then draw a black ellipse
n = phase * 2.0f;
int b = abs(2.0f * n - 1.0f) * r;
tft.fillCircle(x, y, r, TFT_WHITE);
tft.fillEllipse(x, y, abs(b), (int32_t)r, TFT_BLACK);
tft.fillRect(x-r, y-r, r, r*2, TFT_BLACK);
} else if(phase<0.5){
// first we draw a semicircle in white on the RHS by drawing a circle and overwriting with a rectangle. Ugly.
tft.fillCircle(x, y, r, TFT_WHITE);
tft.fillRect(x-r, y-r, r, r*2+1, TFT_BLACK);
// then we add a white ellipse.
n = (phase-0.25) * 2.0f;
int b = 2.0f * n * r;
tft.fillEllipse(x, y, b, (int32_t)r, TFT_WHITE);
} else if(phase<0.75){
// similar, but on the left side
tft.fillCircle(x, y, r, TFT_WHITE);
tft.fillRect(x, y-r, r+1, r*2+1, TFT_BLACK); // blanking the right
// then we add a white ellipse.
n = (phase-0.5) * 2.0f;
int b = 2.0f * n * r;
tft.fillEllipse(x, y, b, (int32_t)r, TFT_WHITE);
} else {
// last phase, similar to the first case
n = (phase-0.75) * 2.0f;
int b = 2.0f * n * r;
tft.fillCircle(x, y, r, TFT_WHITE);
tft.fillEllipse(x, y, abs(b), (int32_t)r, TFT_BLACK);
tft.fillRect(x, y-r, r+1, r*2+1, TFT_BLACK); // fill RHS
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment