а почему не язык GO ?))) он очень похож, и думаю код и там и там будет работать…
https://ru.files.me/u/85hy676p9j
хотя нет не будет…)))
Использование float32 везде, как в ESP32 тоже мало…
https://ru.files.me/u/vfw3ksbx4s
файлы могут оказаться доступны через 10 минут!
исходный код последнего приложения
package main
import (
"math"
"math/rand"
"time"
"github.com/hajimehoshi/ebiten/v2"
)
// Константы
const (
screenWidth = 500
screenHeight = 500
centerX = 250
centerY = 250
numPoints = 150
pi = math.Pi
redrawSeconds = 5
)
// Game структура игры
type Game struct {
R [numPoints]uint8
G [numPoints]uint8
B [numPoints]uint8
xy [2 * numPoints]float32 // Используем float32 как в ESP32
lastTime int64
lastRedrawTime int64
z float32
pixels []byte
}
// Эмуляция ESP32 float вычислений
func esp32Float(x float64) float32 {
// ESP32 использует аппаратные 32-битные float с rounding to nearest
return float32(x)
}
// Функция вычисления метрики с float32 точностью
func dist(x1, y1, x2, y2 float32) float32 {
// Используем float32 арифметику как на ESP32
dx := x1 - x2
if dx < 0 {
dx = -dx
}
dy := y1 - y2
if dy < 0 {
dy = -dy
}
return dx + dy // Манхэттенская метрика
}
// Генерация точек сайтов
func (g *Game) ranSait(variant byte) {
rand.Seed(time.Now().UnixNano())
for i := 0; i < numPoints; i++ {
if variant == 1 || variant == 3 {
// Генерируем точки по всему экрану с float32 точностью
g.xy[i] = esp32Float(float64(rand.Intn(screenWidth)))
g.xy[i+1] = esp32Float(float64(rand.Intn(screenHeight)))
}
if variant == 2 || variant == 3 {
g.R[i] = uint8(rand.Intn(256))
g.G[i] = uint8(rand.Intn(256))
g.B[i] = uint8(rand.Intn(256))
}
}
}
// Очистка экрана
func (g *Game) clearScreen() {
for i := range g.pixels {
g.pixels[i] = 255
}
}
// Рисование секторов с эмуляцией ESP32
func (g *Game) drawRisSektor() {
g.clearScreen()
// Используем float32 для всех вычислений как на ESP32
var f1, r1 float32
for r1 = 0; r1 <= 250; r1 += 1.0 {
for f1 = 0; f1 <= pi/6.0; f1 += pi / g.z {
// Вычисления с float32 точностью
x := esp32Float(float64(centerX)) + esp32Float(math.Cos(float64(f1)))*r1
y := esp32Float(float64(centerY)) + esp32Float(math.Sin(float64(f1)))*r1
// Поиск ближайшей точки
closestPoint := 0
minDist := dist(x, y, g.xy[0], g.xy[1])
for i := 2; i < 2*numPoints; i += 2 {
d := dist(x, y, g.xy[i], g.xy[i+1])
if d < minDist {
minDist = d
closestPoint = i
}
}
// Условие отсечки
if minDist > 15.0 {
// Рисование 12 симметричных точек
for i := float32(0.01); i <= 2*pi; i += pi / 3.0 {
// Вычисляем координаты с float32 точностью
cos1 := esp32Float(math.Cos(float64(f1 + i)))
sin1 := esp32Float(math.Sin(float64(f1 + i)))
cos2 := esp32Float(math.Cos(float64(2*pi - f1 + i)))
sin2 := esp32Float(math.Sin(float64(2*pi - f1 + i)))
x1 := esp32Float(float64(centerX)) + cos1*r1
y1 := esp32Float(float64(centerY)) + sin1*r1
x2 := esp32Float(float64(centerX)) + cos2*r1
y2 := esp32Float(float64(centerY)) + sin2*r1
// Рисуем точки с анти-алиасингом
g.drawPoint(int(x1), int(y1), g.R[closestPoint], g.G[closestPoint], g.B[closestPoint])
g.drawPoint(int(x2), int(y2), g.R[closestPoint], g.G[closestPoint], g.B[closestPoint])
}
}
}
}
}
// Улучшенное рисование точки с заполнением промежутков
func (g *Game) drawPoint(x, y int, r, gr, b uint8) {
// Рисуем не только сам пиксель, но и соседние для заполнения пропусков
for dy := -1; dy <= 1; dy++ {
for dx := -1; dx <= 1; dx++ {
nx, ny := x+dx, y+dy
if nx >= 0 && nx < screenWidth && ny >= 0 && ny < screenHeight {
idx := (ny*screenWidth + nx) * 4
// Смешиваем цвета (простое среднее для заполнения пробелов)
if g.pixels[idx] == 255 && g.pixels[idx+1] == 255 && g.pixels[idx+2] == 255 {
// Если пиксель белый, просто ставим цвет
g.pixels[idx] = r
g.pixels[idx+1] = gr
g.pixels[idx+2] = b
} else {
// Если уже есть цвет, смешиваем (для плавности)
g.pixels[idx] = uint8((int(g.pixels[idx]) + int(r)) / 2)
g.pixels[idx+1] = uint8((int(g.pixels[idx+1]) + int(gr)) / 2)
g.pixels[idx+2] = uint8((int(g.pixels[idx+2]) + int(b)) / 2)
}
g.pixels[idx+3] = 255
}
}
}
}
// Layout
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return screenWidth, screenHeight
}
// Update
func (g *Game) Update() error {
currentTime := time.Now().UnixMilli()
if ebiten.IsKeyPressed(ebiten.KeySpace) {
g.lastRedrawTime = currentTime
g.ranSait(3)
}
if currentTime-g.lastTime > 90000 {
g.lastTime = currentTime
g.lastRedrawTime = currentTime
g.ranSait(3)
}
if currentTime-g.lastRedrawTime > redrawSeconds*1000 {
g.lastRedrawTime = currentTime
g.ranSait(3)
}
g.drawRisSektor()
return nil
}
// Draw
func (g *Game) Draw(screen *ebiten.Image) {
screen.WritePixels(g.pixels)
}
func main() {
rand.Seed(time.Now().UnixNano())
game := &Game{
z: 800.0,
pixels: make([]byte, screenWidth*screenHeight*4),
lastTime: time.Now().UnixMilli(),
lastRedrawTime: time.Now().UnixMilli(),
}
game.clearScreen()
game.ranSait(3)
ebiten.SetWindowSize(screenWidth, screenHeight)
ebiten.SetWindowTitle("ESP32 Pattern Emulator")
ebiten.SetTPS(10)
if err := ebiten.RunGame(game); err != nil {
panic(err)
}
}
а как это еще на вашем языке делать… бросайте это дело, и делайте на esp32!)))
а последние фото от куда ?))) с пк ?