zoologist 发表于 2024-12-11 09:10:32

Firebeetle 2 ESP32-S3 旋转球体

上一次介绍了如何使用FireBeetle 2 ESP32S3 实现 VGA 输出,这次展示一下使用这块板子绘制一个球体。这个项目是根据 https://mp.weixin.qq.com/s/PDgzFQlmOjfZlXK_JpH24g文章设计的。对比原文,改动并不大,主要是实现了moveto() 和 lineto() 两个函数。前者的意思是相当于移动一个虚拟的画笔到画布上的某个位置;后者的意思是从当前虚拟的画笔位置绘制一条直线到画布上指定位置。
#include "VGA.h"
#include <GfxWrapper.h>

VGA vga;
//Mode mode = Mode::MODE_320x240x60;
Mode mode = Mode::MODE_640x480x60;//MODE_640x480x60;
GfxWrapper<VGA> gfx(vga, mode.hRes, mode.vRes);

int CurrentX, CurrentY;
void moveto(int X, int Y) {
CurrentX = X;
CurrentY = Y;
}
void lineto(int X, int Y) {
gfx.drawLine(CurrentX, CurrentY, X, Y, 0x700);
moveto(X, Y);
}

void HideSphere(float R, int alfa, int beta, int HideFlag)
{
int i, j, k;
float x, y, z, x1, y1, z1, sx, sy;
double a1, a2, b1, b2, c, d, xn, yn, zn, vn;
c = alfa * PI / 180.0;
d = beta * PI / 180.0;
for (j = 0; j < 180; j = j + 5)
{
    a1 = j * PI / 180.0;
    a2 = (j + 5) * PI / 180.0;
    for (i = 0; i < 360; i = i + 5)
    {
      b1 = i * PI / 180.0;
      b2 = (i + 5) * PI / 180.0;
      x = R * sin(a1) * cos(b1); y = R * sin(a1) * sin(b1); z = R * cos(a1);
      x = R * sin(a2) * cos(b1); y = R * sin(a2) * sin(b1); z = R * cos(a2);
      x = R * sin(a2) * cos(b2); y = R * sin(a2) * sin(b2); z = R * cos(a2);
      x = R * sin(a1) * cos(b2); y = R * sin(a1) * sin(b2); z = R * cos(a1);
      for (k = 0; k < 4; k++)
      {
      x1 = x * cos(c) - y * sin(c);
      y1 = x * sin(c) * cos(d) + y * cos(c) * sin(d) + z * sin(d);
      z1 = -x * sin(c) * sin(d) - y * cos(c) * sin(d) + z * cos(d);
      sx = 320 - x1;
      sy = 240 - z1;
      }
      xn = (y1 - y1) * (z1 - z1) - (y1 - y1) * (z1 - z1);
      yn = -(x1 - x1) * (z1 - z1) + (x1 - x1) * (z1 - z1);
      zn = (x1 - x1) * (y1 - y1) - (x1 - x1) * (y1 - y1);
      vn = sqrt(xn * xn + yn * yn + zn * zn);
      xn = xn / vn;
      yn = yn / vn;
      zn = zn / vn;
      if (!HideFlag || yn >= 0.0)
      {
      moveto(sx, sy);
      lineto(sx, sy);
      lineto(sx, sy);
      lineto(sx, sy);
      lineto(sx, sy);
      }
    }
}
}


void setup()
{
Serial.begin(115200);
delay(5000);
if (psramInit()) {
    log_d("Total heap: %d", ESP.getHeapSize());
    log_d("Free heap: %d", ESP.getFreeHeap());
    log_d("Total PSRAM: %d", ESP.getPsramSize());
    log_d("Free PSRAM: %d", ESP.getFreePsram());
}
//const PinConfig pins(4, 5, 6, 7, 8,9, 10, 11, 12, 13, 14,15, 16, 17, 18, 21,1, 2);
const PinConfig pins(-1,-1,6,7,8,-1,-1,-1,12,13,14,-1,-1,-1,18,21,1,2); // R G B h v


vga.bufferCount = 2;
if(!vga.init(pins, mode, 8)) while(1) delay(1);

vga.start();
}

void loop()
{

while (true)
{
    for (int i = 0; i < 180; i++)
    {
      HideSphere(200, 45 + i, 30 + i, 1);
      vga.show();
      delay(20);
      vga.clear(0);
    }
}
}

最终的效果还不错,有兴趣的朋友可以在下面看到:
https://www.bilibili.com/video/BV1wcizYVEUG/?share_source=copy_web&vd_source=5ca375392c3dd819bfc37d4672cb6d54
这次使用到的库
页: [1]
查看完整版本: Firebeetle 2 ESP32-S3 旋转球体