Add micro build

This commit is contained in:
2025-10-16 11:18:44 +04:00
parent 2245ece777
commit e3849ecded
25 changed files with 641 additions and 149 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,7 @@
src/main.exe src/main.exe
src/main src/main
src/main.elf
src/main.hex
*.wo *.wo
*.uo *.uo
*.mo *.mo

19
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,19 @@
{
"files.associations": {
"array": "c",
"string_view": "c",
"format": "c",
"initializer_list": "c",
"ranges": "c",
"span": "c",
"micro.h": "c",
"MP6050.C": "cpp",
"MPU6050.C": "cpp",
"mpu6050.h": "c",
"st7789.h": "c",
"i2c_unit_conf.h": "c",
"mpu6050_conf.h": "c",
"i2c_unit.h": "c",
"variant": "c"
}
}

View File

@@ -26,7 +26,7 @@ UNIX_SOURCES = $(BASE_SOURCES) platforms/unix.c
UNIX_OBJECTS = $(UNIX_SOURCES:.c=.uo) UNIX_OBJECTS = $(UNIX_SOURCES:.c=.uo)
UNIX_TARGET = $(TARGET) UNIX_TARGET = $(TARGET)
MICRO_SOURCES = $(BASE_SOURCES) platforms/micro/micro.c platforms/micro/lib/ST7789/ST7789.c MICRO_SOURCES = $(BASE_SOURCES) platforms/micro/micro.c platforms/micro/lib/ST7789/ST7789.c platforms/micro/lib/MPU6050/MPU6050.c platforms/micro/lib/I2C/I2C.c
MICRO_OBJECTS = $(MICRO_SOURCES:.c=.mo) MICRO_OBJECTS = $(MICRO_SOURCES:.c=.mo)
MICRO_TARGET = $(TARGET) MICRO_TARGET = $(TARGET)
ELF = $(TARGET).elf ELF = $(TARGET).elf
@@ -35,7 +35,7 @@ HEX = $(TARGET).hex
win: $(WIN_TARGET) win: $(WIN_TARGET)
$(WIN_TARGET): $(WIN_OBJECTS) $(WIN_TARGET): $(WIN_OBJECTS)
$(GCC) -o $@ $^ $(LIBS) $(CC) -o $@ $^ $(LIBS)
micro: $(HEX) micro: $(HEX)
@@ -53,7 +53,7 @@ $(ELF): $(MICRO_OBJECTS)
$(CC) $(CFLAGS) -DUNIX -c $< -o $@ $(CC) $(CFLAGS) -DUNIX -c $< -o $@
%.mo: %.c %.mo: %.c
$(MICRO_CC) $(MICRO_CFLAGS) -DMICRO -c $< -o $@ $(MICRO_CC) $(MICRO_CFLAGS) -DMICRO -c $< -o $@
run_win: $(WIN_TARGET) run_win: $(WIN_TARGET)
.\$(WIN_TARGET) .\$(WIN_TARGET)

View File

@@ -3,8 +3,7 @@
#include "../utils/math.h" #include "../utils/math.h"
#include "vector.h" #include "vector.h"
void camera_get_view_matrix(const Camera *const camera, void camera_get_view_matrix(const Camera *const camera, float *view_matrix) {
float view_matrix[4][4]) {
float forward[3]; float forward[3];
vector_substruct(3, camera->position->coordinates, vector_substruct(3, camera->position->coordinates,
camera->target->coordinates, forward); camera->target->coordinates, forward);
@@ -23,32 +22,33 @@ void camera_get_view_matrix(const Camera *const camera,
float *vectors[] = {normal_right, normal_up, normal_forward}; float *vectors[] = {normal_right, normal_up, normal_forward};
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
view_matrix[i][j] = 0; view_matrix[i * 4 + j] = 0;
if (i == 3) { if (i == 3) {
if (j == 3) if (j == 3)
view_matrix[i][j] = 1; view_matrix[i * 4 + j] = 1;
} else if (j == 3) { } else if (j == 3) {
view_matrix[i][j] = view_matrix[i * 4 + j] =
-1 * vector_dot_product(vectors[i], camera->position->coordinates); -1 * vector_dot_product(vectors[i], camera->position->coordinates);
} else { } else {
view_matrix[i][j] = vectors[i][j]; view_matrix[i * 4 + j] = vectors[i][j];
} }
} }
} }
} }
void camera_get_projection_matrix(const Camera *const camera, void camera_get_projection_matrix(const Camera *const camera,
float projection_matrix[4][4]) { float *projection_matrix) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
projection_matrix[i][j] = 0; projection_matrix[i * 4 + j] = 0;
} }
} }
float f = 1 / e_tan(camera->fov / 2); float f = 1 / e_tan(camera->fov / 2);
projection_matrix[0][0] = f / camera->aspect_ratio; projection_matrix[0 * 4 + 0] = f / camera->aspect_ratio;
projection_matrix[1][1] = f; projection_matrix[1 * 4 + 1] = f;
projection_matrix[2][2] = (camera->max_distance + camera->min_distance) / projection_matrix[2 * 4 + 2] = (camera->max_distance + camera->min_distance) /
(camera->min_distance - camera->max_distance); (camera->min_distance - camera->max_distance);
projection_matrix[3][2] = -1; projection_matrix[3 * 4 + 2] = -1;
projection_matrix[2][3] = (2 * camera->max_distance * camera->min_distance) / projection_matrix[2 * 4 + 3] =
(camera->min_distance - camera->max_distance); (2 * camera->max_distance * camera->min_distance) /
(camera->min_distance - camera->max_distance);
} }

View File

@@ -13,9 +13,8 @@ typedef struct Camera {
const float aspect_ratio; const float aspect_ratio;
} Camera; } Camera;
void camera_get_view_matrix(const Camera *const camera, void camera_get_view_matrix(const Camera *const camera, float *view_matrix);
float view_matrix[4][4]);
void camera_get_projection_matrix(const Camera *const camera, void camera_get_projection_matrix(const Camera *const camera,
float projection_matrix[4][4]); float *projection_matrix);
#endif #endif

View File

@@ -1,37 +1,35 @@
#include "matrix.h" #include "matrix.h"
#include "../utils/math.h" #include "../utils/math.h"
void matrix_mult_matrix(int size, const float matrix1[size][size], void matrix_mult_matrix(int size, const float *matrix1, const float *matrix2,
const float matrix2[size][size], float *result) {
float result[size][size]) {
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) { for (int j = 0; j < size; j++) {
result[i][j] = 0; result[i * size + j] = 0;
} }
} }
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) { for (int j = 0; j < size; j++) {
for (int k = 0; k < size; k++) { for (int k = 0; k < size; k++) {
result[i][j] += matrix1[i][k] * matrix2[k][j]; result[i * size + j] += matrix1[i * size + k] * matrix2[k * size + j];
} }
} }
} }
} }
void matrix_mult_vector(int size, const float matrix[size][size], void matrix_mult_vector(int size, const float *matrix, const float vector[size],
const float vector[size], float result[size]) { float result[size]) {
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
result[i] = 0; result[i] = 0;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) { for (int j = 0; j < size; j++) {
result[i] += matrix[i][j] * vector[j]; result[i] += matrix[i * size + j] * vector[j];
} }
} }
} }
void create_axis_rotate_matrix(int axis, float angle, void create_axis_rotate_matrix(int axis, float angle, float *rotate_matrix) {
float rotate_matrix[3][3]) {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
rotate_matrix[i][j] = 0; rotate_matrix[i * 3 + j] = 0;
} }
} }
@@ -42,17 +40,17 @@ void create_axis_rotate_matrix(int axis, float angle,
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
if (i == axis || j == axis) { if (i == axis || j == axis) {
if (i == j) if (i == j)
rotate_matrix[i][j] = 1; rotate_matrix[i * 3 + j] = 1;
else else
rotate_matrix[i][j] = 0; rotate_matrix[i * 3 + j] = 0;
} else { } else {
if (i == j) { if (i == j) {
rotate_matrix[i][j] = cos_angle; rotate_matrix[i * 3 + j] = cos_angle;
} else { } else {
if ((i < j && axis == 2) || (i > j && axis != 2)) { if ((i < j && axis == 2) || (i > j && axis != 2)) {
rotate_matrix[i][j] = sin_angle; rotate_matrix[i * 3 + j] = sin_angle;
} else { } else {
rotate_matrix[i][j] = -sin_angle; rotate_matrix[i * 3 + j] = -sin_angle;
} }
} }
} }
@@ -60,15 +58,14 @@ void create_axis_rotate_matrix(int axis, float angle,
} }
} }
void create_rotate_matrix(const float rotate_speed[3], void create_rotate_matrix(const float rotate_speed[3], float *rotate_matrix) {
float rotate_matrix[3][3]) { float x_rotate[3 * 3];
float x_rotate[3][3];
create_axis_rotate_matrix(0, rotate_speed[0], x_rotate); create_axis_rotate_matrix(0, rotate_speed[0], x_rotate);
float y_rotate[3][3]; float y_rotate[3 * 3];
create_axis_rotate_matrix(1, rotate_speed[1], y_rotate); create_axis_rotate_matrix(1, rotate_speed[1], y_rotate);
float z_rotate[3][3]; float z_rotate[3 * 3];
create_axis_rotate_matrix(2, rotate_speed[2], z_rotate); create_axis_rotate_matrix(2, rotate_speed[2], z_rotate);
float xy_rotate[3][3]; float xy_rotate[3 * 3];
matrix_mult_matrix(3, x_rotate, y_rotate, xy_rotate); matrix_mult_matrix(3, x_rotate, y_rotate, xy_rotate);
matrix_mult_matrix(3, xy_rotate, z_rotate, rotate_matrix); matrix_mult_matrix(3, xy_rotate, z_rotate, rotate_matrix);
} }

View File

@@ -1,16 +1,13 @@
#ifndef MATRIX_H #ifndef MATRIX_H
#define MATRIX_H #define MATRIX_H
void matrix_mult_matrix(int size, const float matrix1[size][size], void matrix_mult_matrix(int size, const float *matrix1, const float *matrix2,
const float matrix2[size][size], float *result);
float result[size][size]); void matrix_mult_vector(int size, const float *matrix, const float vector[size],
void matrix_mult_vector(int size, const float matrix[size][size], float result[size]);
const float vector[size], float result[size]);
void create_axis_rotate_matrix(int axis, float angle, void create_axis_rotate_matrix(int axis, float angle, float *rotate_matrix);
float rotate_matrix[3][3]); void create_rotate_matrix(const float rotate_speed[3], float *rotate_matrix);
void create_rotate_matrix(const float rotate_speed[3],
float rotate_matrix[3][3]);
// void print_matrix(int size, float matrix[size][size]); // void print_matrix(int size, float matrix[size][size]);
#endif #endif

View File

@@ -3,8 +3,7 @@
#include "../utils/screen.h" #include "../utils/screen.h"
#include "vector.h" #include "vector.h"
void object_transform(Object *const object, int size, void object_transform(Object *const object, int size, float *translate_matrix) {
float translate_matrix[size][size]) {
for (int i = 0; i < object->number_of_points; i++) { for (int i = 0; i < object->number_of_points; i++) {
point_transform(&(object->points[i]), size, translate_matrix); point_transform(&(object->points[i]), size, translate_matrix);
} }
@@ -27,13 +26,13 @@ Point object_get_centroid(const Object *const object) {
return centroid; return centroid;
} }
void object_draw(const Object *object, Screen *screen, void object_draw(const Object *object, const Screen *const screen,
const float render_matrix[4][4]) { const float *render_matrix, const Color *const color) {
for (int i = 0; i < object->number_of_edges; i++) { for (int i = 0; i < object->number_of_edges; i++) {
ScreenPoint screen_point1 = point_to_screen_point( ScreenPoint screen_point1 = point_to_screen_point(
&object->points[object->edges[i][0]], screen, render_matrix); &object->points[object->edges[i][0]], screen, render_matrix);
ScreenPoint screen_point2 = point_to_screen_point( ScreenPoint screen_point2 = point_to_screen_point(
&object->points[object->edges[i][1]], screen, render_matrix); &object->points[object->edges[i][1]], screen, render_matrix);
screen->draw_line(&screen_point1, &screen_point2); screen->draw_line(&screen_point1, &screen_point2, color);
} }
} }

View File

@@ -14,10 +14,9 @@ typedef struct Object {
const float (*const rotate_speed)[3]; const float (*const rotate_speed)[3];
} Object; } Object;
void object_transform(Object *const object, int size, void object_transform(Object *const object, int size, float *translate_matrix);
float translate_matrix[size][size]);
Point object_get_centroid(const Object *const object); Point object_get_centroid(const Object *const object);
void object_draw(const Object *object, Screen *screen, void object_draw(const Object *object, const Screen *const screen,
const float render_matrix[4][4]); const float *render_matrix, const Color *const color);
#endif #endif

View File

@@ -14,8 +14,8 @@ void point_mult_number(Point *const point, const int k) {
} }
void point_transform(Point *const point, int size, void point_transform(Point *const point, int size,
const float translate_matrix[size][size]) { const float *translate_matrix) {
float new_coordinates[3]; float new_coordinates[size];
float old_coordinates[] = {point->coordinates[0], point->coordinates[1], float old_coordinates[] = {point->coordinates[0], point->coordinates[1],
point->coordinates[2], 1.0f}; point->coordinates[2], 1.0f};
matrix_mult_vector(size, translate_matrix, old_coordinates, new_coordinates); matrix_mult_vector(size, translate_matrix, old_coordinates, new_coordinates);
@@ -23,20 +23,20 @@ void point_transform(Point *const point, int size,
point->coordinates[i] = new_coordinates[i]; point->coordinates[i] = new_coordinates[i];
} }
void point_create_translate_matrix(const Point *const position, void point_create_translate_matrix(const Point *const position,
float translate_matrix[4][4], int k) { float *translate_matrix, int k) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
translate_matrix[i][j] = 0; translate_matrix[i * 4 + j] = 0;
if (i == j) if (i == j)
translate_matrix[i][j] = 1; translate_matrix[i * 4 + j] = 1;
else if (j == 3) else if (j == 3)
translate_matrix[i][j] = position->coordinates[i] * k; translate_matrix[i * 4 + j] = position->coordinates[i] * k;
} }
} }
} }
ScreenPoint point_to_screen_point(Point *point, Screen *screen, ScreenPoint point_to_screen_point(Point *point, const Screen *const screen,
const float render_matrix[4][4]) { const float *render_matrix) {
float tmp[] = {point->coordinates[0], point->coordinates[1], float tmp[] = {point->coordinates[0], point->coordinates[1],
point->coordinates[2], 1.0f}; point->coordinates[2], 1.0f};
float point_projection_view[4]; float point_projection_view[4];

View File

@@ -10,10 +10,10 @@ typedef struct Point {
void point_add_point(Point *const point, const Point *const other_point); void point_add_point(Point *const point, const Point *const other_point);
void point_mult_number(Point *const point, const int k); void point_mult_number(Point *const point, const int k);
void point_transform(Point *const point, int size, void point_transform(Point *const point, int size,
const float translate_matrix[size][size]); const float *translate_matrix);
void point_create_translate_matrix(const Point *const position, void point_create_translate_matrix(const Point *const position,
float translate_matrix[4][4], int k); float *translate_matrix, int k);
ScreenPoint point_to_screen_point(Point *point, Screen *screen, ScreenPoint point_to_screen_point(Point *point, const Screen *const screen,
const float render_matrix[4][4]); const float *render_matrix);
#endif #endif

View File

@@ -9,18 +9,21 @@
#include "objects.h" #include "objects.h"
float render_matrix[4][4]; float *render_matrix;
void init_engine() { void init_engine() {
logff(BLUE ITALIC, "Engine init..."); logff(BLUE ITALIC, "Engine init...");
float view_matrix[4][4]; render_matrix = (float *)malloc(4 * 4 * sizeof(float));
float view_matrix[4 * 4];
camera_get_view_matrix(&camera, view_matrix); camera_get_view_matrix(&camera, view_matrix);
logf("View matrix created\n"); logf("View matrix created\n");
float projection_matrix[4][4]; float projection_matrix[4 * 4];
camera_get_projection_matrix(&camera, projection_matrix); camera_get_projection_matrix(&camera, projection_matrix);
logf("Projection matrix created\n"); logf("Projection matrix created\n");
matrix_mult_matrix(4, projection_matrix, view_matrix, render_matrix); matrix_mult_matrix(4, projection_matrix, view_matrix, render_matrix);
logf("Render matrix created\n"); logf("Render matrix created\n");
@@ -29,7 +32,7 @@ void init_engine() {
point_mult_number(&center_of_object, -1); point_mult_number(&center_of_object, -1);
point_add_point(&center_of_object, objects[i].position); point_add_point(&center_of_object, objects[i].position);
float translate_matrix[4][4]; float translate_matrix[4 * 4];
point_create_translate_matrix(&center_of_object, translate_matrix, 1); point_create_translate_matrix(&center_of_object, translate_matrix, 1);
object_transform(&(objects[i]), 4, translate_matrix); object_transform(&(objects[i]), 4, translate_matrix);
@@ -42,19 +45,33 @@ void init_engine() {
logff(BLUE BOLD UNDERLINE, "Engine init complete!"); logff(BLUE BOLD UNDERLINE, "Engine init complete!");
} }
void render(Screen screen) { void render(const Screen *const screen, const Color *const color) {
for (int i = 0; i < number_of_objects; i++) { for (int i = 0; i < number_of_objects; i++) {
object_draw(&(objects[i]), &screen, render_matrix); object_draw(&(objects[i]), screen, render_matrix, color);
} }
} }
void tic() { void rotate(const float angles_speed[3]) {
for (int i = 0; i < number_of_objects; i++) { for (int i = 0; i < number_of_objects; i++) {
float translate_matrix[4][4]; float translate_matrix[4 * 4];
point_create_translate_matrix(objects[i].position, translate_matrix, -1); point_create_translate_matrix(objects[i].position, translate_matrix, -1);
object_transform(&(objects[i]), 4, translate_matrix); object_transform(&(objects[i]), 4, translate_matrix);
float rotate_matrix[3][3]; float rotate_matrix[3 * 3];
create_rotate_matrix(angles_speed, rotate_matrix);
object_transform(&(objects[i]), 3, rotate_matrix);
point_create_translate_matrix(objects[i].position, translate_matrix, 1);
object_transform(&(objects[i]), 4, translate_matrix);
}
}
void tic() {
for (int i = 0; i < number_of_objects; i++) {
float translate_matrix[4 * 4];
point_create_translate_matrix(objects[i].position, translate_matrix, -1);
object_transform(&(objects[i]), 4, translate_matrix);
float rotate_matrix[3 * 3];
create_rotate_matrix(*(objects[i].rotate_speed), rotate_matrix); create_rotate_matrix(*(objects[i].rotate_speed), rotate_matrix);
object_transform(&(objects[i]), 3, rotate_matrix); object_transform(&(objects[i]), 3, rotate_matrix);
@@ -63,4 +80,4 @@ void tic() {
} }
} }
void destroy() {} void destroy() { free(render_matrix); }

View File

@@ -21,43 +21,41 @@ const Object cube = {.name = "cube",
.position = &cube_position, .position = &cube_position,
.rotate_speed = &cube_speed}; .rotate_speed = &cube_speed};
// Point pyramid_points[] = {{.coordinates = {-1.0f, 0.0f, -1.0f}}, Point pyramid_points[] = {{.coordinates = {-1.0f, 0.0f, -1.0f}},
// {.coordinates = {1.0f, 0.0f, -1.0f}}, {.coordinates = {1.0f, 0.0f, -1.0f}},
// {.coordinates = {1.0f, 0.0f, 1.0f}}, {.coordinates = {1.0f, 0.0f, 1.0f}},
// {.coordinates = {-1.0f, 0.0f, 1.0f}}, {.coordinates = {-1.0f, 0.0f, 1.0f}},
// {.coordinates = {0.0f, 1.5f, 0.0f}}}; {.coordinates = {0.0f, 1.5f, 0.0f}}};
// Point pyramid_position = {.coordinates = {6.0f, 3.0f, 5.0f}}; Point pyramid_position = {.coordinates = {6.0f, 3.0f, 5.0f}};
// const int pyramid_edges[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 0}, const int pyramid_edges[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 0},
// {0, 4}, {1, 4}, {2, 4}, {3, 4}}; {0, 4}, {1, 4}, {2, 4}, {3, 4}};
// const float pyramid_speed[] = {0.0f, 0.0f, 0.03f}; const float pyramid_speed[] = {0.0f, 0.0f, 0.03f};
// const Object pyramid = {.name = "pyramid", const Object pyramid = {.name = "pyramid",
// .points = pyramid_points, .points = pyramid_points,
// .edges = pyramid_edges, .edges = pyramid_edges,
// .number_of_points = 5, .number_of_points = 5,
// .number_of_edges = 8, .number_of_edges = 8,
// .position = &pyramid_position, .position = &pyramid_position,
// .rotate_speed = &pyramid_speed}; .rotate_speed = &pyramid_speed};
// Point prism_points[] = { Point prism_points[] = {
// {.coordinates = {0.0f, 0.0f, 0.0f}}, {.coordinates = {1.0f, 0.0f, 0.0f}}, {.coordinates = {0.0f, 0.0f, 0.0f}}, {.coordinates = {1.0f, 0.0f, 0.0f}},
// {.coordinates = {0.5f, 0.0f, 1.0f}}, {.coordinates = {0.0f, 1.0f, 0.0f}}, {.coordinates = {0.5f, 0.0f, 1.0f}}, {.coordinates = {0.0f, 1.0f, 0.0f}},
// {.coordinates = {1.0f, 1.0f, 0.0f}}, {.coordinates = {.coordinates = {1.0f, 1.0f, 0.0f}}, {.coordinates = {0.5f, 1.0f, 1.0f}}};
// {0.5f, 1.0f, 1.0f}}}; Point prism_position = {.coordinates = {10.0f, 10.0f, 10.0f}};
// Point prism_position = {.coordinates = {10.0f, 10.0f, 10.0f}}; const int prism_edges[][2] = {{0, 1}, {1, 2}, {2, 0}, {3, 4}, {4, 5},
// const int prism_edges[][2] = {{0, 1}, {1, 2}, {2, 0}, {3, 4}, {4, 5}, {5, 3}, {0, 3}, {1, 4}, {2, 5}};
// {5, 3}, {0, 3}, {1, 4}, {2, 5}}; const float prism_speed[] = {0.0f, 0.03f, 0.0f};
// const float prism_speed[] = {0.0f, 0.03f, 0.0f}; const Object prism = {.name = "prism",
// const Object prism = {.name = "prism", .points = prism_points,
// .points = prism_points, .edges = prism_edges,
// .edges = prism_edges, .number_of_points = 6,
// .number_of_points = 6, .number_of_edges = 9,
// .number_of_edges = 9, .position = &prism_position,
// .position = &prism_position, .rotate_speed = &prism_speed};
// .rotate_speed = &prism_speed};
const int number_of_objects = 1; const int number_of_objects = 3;
// Object objects[] = {cube, pyramid, prism}; Object objects[] = {cube, pyramid, prism};
Object objects[] = {cube};
Point camera_position = {.coordinates = {0.0f, 0.0f, 0.0f}}; Point camera_position = {.coordinates = {0.0f, 0.0f, 0.0f}};
Point camera_target = {.coordinates = {1.0f, 1.0f, 1.0f}}; Point camera_target = {.coordinates = {1.0f, 1.0f, 1.0f}};

View File

@@ -0,0 +1,73 @@
#include "I2C.h"
#include <avr/io.h>
#include <util/twi.h>
// Тайм-аут для ожидания TWINT (подберите под вашу частоту)
#define I2C_TIMEOUT 30000
void i2c_init(void) {
TWSR = 0; // Предделитель = 1
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
}
static uint8_t i2c_wait_for_completion(void) {
uint16_t timeout = I2C_TIMEOUT;
while (!(TWCR & (1 << TWINT))) {
if (--timeout == 0)
return 1; // Тайм-аут
}
return 0;
}
uint8_t i2c_start(uint8_t address) {
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
if (i2c_wait_for_completion())
return 1;
uint8_t status = TWSR & 0xF8;
if (status != TW_START && status != TW_REP_START)
return 1;
TWDR = address;
TWCR = (1 << TWINT) | (1 << TWEN);
if (i2c_wait_for_completion())
return 1;
status = TWSR & 0xF8;
if (status == TW_MT_SLA_ACK || status == TW_MR_SLA_ACK)
return 0;
else
return 1;
}
void i2c_stop(void) {
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
// TWSTO автоматически сбрасывается, но не виснем навсегда
uint16_t timeout = I2C_TIMEOUT;
while ((TWCR & (1 << TWSTO)) && --timeout) {
// Ждём завершения STOP
}
}
uint8_t i2c_write(uint8_t data) {
TWDR = data;
TWCR = (1 << TWINT) | (1 << TWEN);
if (i2c_wait_for_completion())
return 1;
return ((TWSR & 0xF8) == TW_MT_DATA_ACK) ? 0 : 1;
}
uint8_t i2c_read_ack(void) {
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
if (i2c_wait_for_completion())
return 0; // Возвращаем 0 при ошибке
return TWDR;
}
uint8_t i2c_read_nack(void) {
TWCR = (1 << TWINT) | (1 << TWEN);
if (i2c_wait_for_completion())
return 0;
return TWDR;
}

View File

@@ -0,0 +1,15 @@
#ifndef I2C_H
#define I2C_H
#include <stdint.h>
#define TWI_FREQ 400000UL // 400 kHz
void i2c_init(void);
uint8_t i2c_start(uint8_t address);
void i2c_stop(void);
uint8_t i2c_write(uint8_t data);
uint8_t i2c_read_ack(void);
uint8_t i2c_read_nack(void);
#endif

View File

@@ -0,0 +1,111 @@
#include "../I2C/I2C.h"
#include "MPU6050.h"
#include <avr/io.h>
#include <util/delay.h>
void mpu6050_init(void) {
i2c_init();
// Отправляем: START + ADDR(W) + REG + DATA + STOP
if (i2c_start(MPU6050_ADDR))
goto error;
if (i2c_write(MPU6050_REG_PWR_MGMT_1))
goto error;
if (i2c_write(0x00))
goto error; // Wake up
i2c_stop();
return;
int16_t gx_off, gy_off, gz_off;
mpu6050_calibrate_gyro(&gx_off, &gy_off, &gz_off);
mpu6050_set_gyro_offsets(gx_off, gy_off, gz_off);
error:
i2c_stop(); // На всякий случай
// Можно добавить обработку ошибки (мигание LED и т.п.)
}
static void mpu6050_read_burst(uint8_t reg, uint8_t *buf, uint8_t len) {
// Запись адреса регистра БЕЗ STOP
if (i2c_start(MPU6050_ADDR))
goto error;
if (i2c_write(reg))
goto error;
// Repeated START для чтения
if (i2c_start(MPU6050_ADDR | 0x01))
goto error;
for (uint8_t i = 0; i < len - 1; i++) {
buf[i] = i2c_read_ack();
}
buf[len - 1] = i2c_read_nack();
i2c_stop();
return;
error:
i2c_stop();
// При ошибке заполняем нулями (или обрабатываем иначе)
for (uint8_t i = 0; i < len; i++)
buf[i] = 0;
}
void mpu6050_read_accel(float *ax, float *ay, float *az) {
uint8_t buf[6];
mpu6050_read_burst(MPU6050_REG_ACCEL_XOUT_H, buf, 6);
// Данные в формате Big-Endian, знаковые 16-битные
int16_t x = (buf[0] << 8) | buf[1];
int16_t y = (buf[2] << 8) | buf[3];
int16_t z = (buf[4] << 8) | buf[5];
// Масштаб: по умолчанию ±2g → 16384 LSB/g
const float accel_scale = 16384.0f;
*ax = (float)x / accel_scale;
*ay = (float)y / accel_scale;
*az = (float)z / accel_scale;
}
// Глобальные переменные для смещений (лучше сделать static в .c файле)
static int16_t gyro_offset_x = 0;
static int16_t gyro_offset_y = 0;
static int16_t gyro_offset_z = 0;
void mpu6050_set_gyro_offsets(int16_t x, int16_t y, int16_t z) {
gyro_offset_x = x;
gyro_offset_y = y;
gyro_offset_z = z;
}
void mpu6050_read_gyro(float *gx, float *gy, float *gz) {
uint8_t buf[6];
mpu6050_read_burst(MPU6050_REG_GYRO_XOUT_H, buf, 6);
int16_t raw_x = ((buf[0] << 8) | buf[1]) - gyro_offset_x;
int16_t raw_y = ((buf[2] << 8) | buf[3]) - gyro_offset_y;
int16_t raw_z = ((buf[4] << 8) | buf[5]) - gyro_offset_z;
const float gyro_scale = 131.0f;
*gx = (float)raw_x / gyro_scale;
*gy = (float)raw_y / gyro_scale;
*gz = (float)raw_z / gyro_scale;
}
void mpu6050_calibrate_gyro(int16_t *gx_offset, int16_t *gy_offset,
int16_t *gz_offset) {
const int samples = 1000;
int32_t sum_x = 0, sum_y = 0, sum_z = 0;
for (int i = 0; i < samples; i++) {
uint8_t buf[6];
mpu6050_read_burst(MPU6050_REG_GYRO_XOUT_H, buf, 6);
sum_x += (buf[0] << 8) | buf[1];
sum_y += (buf[2] << 8) | buf[3];
sum_z += (buf[4] << 8) | buf[5];
_delay_ms(2); // небольшая пауза
}
*gx_offset = sum_x / samples;
*gy_offset = sum_y / samples;
*gz_offset = sum_z / samples;
}

View File

@@ -0,0 +1,21 @@
#ifndef MPU6050_H
#define MPU6050_H
#include <stdint.h>
// Адрес по умолчанию: AD0 = GND → 0x68 → сдвинутый = 0xD0
// Если AD0 = VCC → 0x69 → 0xD2
#define MPU6050_ADDR 0xD0
#define MPU6050_REG_PWR_MGMT_1 0x6B
#define MPU6050_REG_ACCEL_XOUT_H 0x3B
#define MPU6050_REG_GYRO_XOUT_H 0x43
void mpu6050_init(void);
void mpu6050_read_accel(float *ax, float *ay, float *az);
void mpu6050_read_gyro(float *gx, float *gy, float *gz);
void mpu6050_set_gyro_offsets(int16_t x, int16_t y, int16_t z);
void mpu6050_calibrate_gyro(int16_t *gx_offset, int16_t *gy_offset,
int16_t *gz_offset);
#endif

View File

@@ -1,26 +1,39 @@
#include "./lib/MPU6050/MPU6050.h"
#include "./lib/ST7789/ST7789.h" #include "./lib/ST7789/ST7789.h"
#include "../platform.h" #include "../platform.h"
#include "micro.h" #include "micro.h"
void draw_line(const ScreenPoint *sp1, const ScreenPoint *sp2) { void draw_line(const ScreenPoint *sp1, const ScreenPoint *sp2,
st7789_draw_line(0, 0, 160, 128, COLOR_WHITE); const Color *const color) {
st7789_draw_line(sp1->coordinates[0], sp1->coordinates[1], st7789_draw_line(sp1->coordinates[0], sp1->coordinates[1],
sp2->coordinates[0], sp2->coordinates[1], COLOR_WHITE); sp2->coordinates[0], sp2->coordinates[1],
RGB565(color->red, color->green, color->blue));
}; };
Screen screen = { const Screen screen = {
.width = DISPLAY_WIDTH, .height = DISPLAY_HEIGHT, .draw_line = &draw_line}; .width = DISPLAY_WIDTH, .height = DISPLAY_HEIGHT, .draw_line = &draw_line};
const Color white = {255, 255, 255};
const Color black = {0, 0, 0};
float gx, gy, gz;
int main(void) { int main(void) {
st7789_init();
mpu6050_init();
init_engine(); init_engine();
st7789_init(); st7789_fill_screen(RGB565(0, 0, 0));
while (1) { while (1) {
st7789_fill_screen(COLOR_BLACK); render(&screen, &black);
render(screen);
_delay_ms(1000 / FPS); mpu6050_read_gyro(&gx, &gy, &gz);
float angles_speed[3] = {gx / 255.0f, gy / 255.0f, gz / 255.0f};
rotate(angles_speed);
render(&screen, &white);
} }
return 0; return 0;

View File

@@ -2,5 +2,6 @@
#define MICRO_H #define MICRO_H
#include "./lib/ST7789/ST7789.h" #include "./lib/ST7789/ST7789.h"
#include <stdlib.h>
#endif #endif

View File

@@ -17,7 +17,7 @@
#ifdef MICRO #ifdef MICRO
#define FPS 5 #define FPS 25
#include "micro/micro.h" #include "micro/micro.h"
#define DISPLAY_WIDTH 160 #define DISPLAY_WIDTH 160
@@ -28,8 +28,9 @@
#endif // MICRO #endif // MICRO
void init_engine(); void init_engine();
void render(Screen screen); void render(const Screen *const screen, const Color *const color);
void tic(); void tic();
void rotate(const float angles_speed[3]);
void destroy(); void destroy();
#endif #endif

View File

@@ -1,7 +1,9 @@
#include "platform.h" #include "../platform.h"
#include "win.h" #include "win.h"
const Color white = {255, 255, 255};
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam) { LPARAM lParam) {
switch (uMsg) { switch (uMsg) {
@@ -19,20 +21,20 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
float width = rect.right - rect.left; float width = rect.right - rect.left;
float height = rect.bottom - rect.top; float height = rect.bottom - rect.top;
HPEN hPen = CreatePen(PS_SOLID, 1, COLOR); void draw_line(const ScreenPoint *sp1, const ScreenPoint *sp2,
HPEN hOldPen = (HPEN)SelectObject(hdc, hPen); const Color *const color) {
HPEN hPen =
void draw_line(const ScreenPoint *sp1, const ScreenPoint *sp2) { CreatePen(PS_SOLID, 1, RGB(color->red, color->green, color->blue));
HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
MoveToEx(hdc, sp1->coordinates[0], sp1->coordinates[1], NULL); MoveToEx(hdc, sp1->coordinates[0], sp1->coordinates[1], NULL);
LineTo(hdc, sp2->coordinates[0], sp2->coordinates[1]); LineTo(hdc, sp2->coordinates[0], sp2->coordinates[1]);
SelectObject(hdc, hOldPen);
DeleteObject(hPen);
}; };
Screen screen = {.width = width, .height = height, .draw_line = &draw_line}; Screen screen = {.width = width, .height = height, .draw_line = &draw_line};
render(screen); render(&screen, &white);
SelectObject(hdc, hOldPen);
DeleteObject(hPen);
EndPaint(hwnd, &ps); EndPaint(hwnd, &ps);
return 0; return 0;
@@ -44,7 +46,6 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
case WM_TIMER: case WM_TIMER:
tic(); tic();
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);
return 0; return 0;

138
src/utils/cos_table.h Normal file
View File

@@ -0,0 +1,138 @@
#ifndef COS_TABLE_H
#define COS_TABLE_H
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846f
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923f
#endif
#define COS_TABLE_SIZE 256
static float cos_table_angles[COS_TABLE_SIZE] = {
0.0000000000f, 0.0245436926f, 0.0490873852f, 0.0736310778f, 0.0981747704f,
0.1227184630f, 0.1472621556f, 0.1718058482f, 0.1963495408f, 0.2208932335f,
0.2454369261f, 0.2699806187f, 0.2945243113f, 0.3190680039f, 0.3436116965f,
0.3681553891f, 0.3926990817f, 0.4172427743f, 0.4417864669f, 0.4663301595f,
0.4908738521f, 0.5154175447f, 0.5399612373f, 0.5645049299f, 0.5890486225f,
0.6135923152f, 0.6381360078f, 0.6626797004f, 0.6872233930f, 0.7117670856f,
0.7363107782f, 0.7608544708f, 0.7853981634f, 0.8099418560f, 0.8344855486f,
0.8590292412f, 0.8835729338f, 0.9081166264f, 0.9326603190f, 0.9572040116f,
0.9817477042f, 1.0062913969f, 1.0308350895f, 1.0553787821f, 1.0799224747f,
1.1044661673f, 1.1290098599f, 1.1535535525f, 1.1780972451f, 1.2026409377f,
1.2271846303f, 1.2517283229f, 1.2762720155f, 1.3008157081f, 1.3253594007f,
1.3499030933f, 1.3744467859f, 1.3989904786f, 1.4235341712f, 1.4480778638f,
1.4726215564f, 1.4971652490f, 1.5217089416f, 1.5462526342f, 1.5707963268f,
1.5953400194f, 1.6198837120f, 1.6444274046f, 1.6689710972f, 1.6935147898f,
1.7180584824f, 1.7426021750f, 1.7671458676f, 1.7916895603f, 1.8162332529f,
1.8407769455f, 1.8653206381f, 1.8898643307f, 1.9144080233f, 1.9389517159f,
1.9634954085f, 1.9880391011f, 2.0125827937f, 2.0371264863f, 2.0616701789f,
2.0862138715f, 2.1107575641f, 2.1353012567f, 2.1598449493f, 2.1843886419f,
2.2089323346f, 2.2334760272f, 2.2580197198f, 2.2825634124f, 2.3071071050f,
2.3316507976f, 2.3561944902f, 2.3807381828f, 2.4052818754f, 2.4298255680f,
2.4543692606f, 2.4789129532f, 2.5034566458f, 2.5280003384f, 2.5525440310f,
2.5770877236f, 2.6016314163f, 2.6261751089f, 2.6507188015f, 2.6752624941f,
2.6998061867f, 2.7243498793f, 2.7488935719f, 2.7734372645f, 2.7979809571f,
2.8225246497f, 2.8470683423f, 2.8716120349f, 2.8961557275f, 2.9206994201f,
2.9452431127f, 2.9697868053f, 2.9943304980f, 3.0188741906f, 3.0434178832f,
3.0679615758f, 3.0925052684f, 3.1170489610f, 3.1415926536f, 3.1661363462f,
3.1906800388f, 3.2152237314f, 3.2397674240f, 3.2643111166f, 3.2888548092f,
3.3133985018f, 3.3379421944f, 3.3624858870f, 3.3870295797f, 3.4115732723f,
3.4361169649f, 3.4606606575f, 3.4852043501f, 3.5097480427f, 3.5342917353f,
3.5588354279f, 3.5833791205f, 3.6079228131f, 3.6324665057f, 3.6570101983f,
3.6815538909f, 3.7060975835f, 3.7306412761f, 3.7551849687f, 3.7797286614f,
3.8042723540f, 3.8288160466f, 3.8533597392f, 3.8779034318f, 3.9024471244f,
3.9269908170f, 3.9515345096f, 3.9760782022f, 4.0006218948f, 4.0251655874f,
4.0497092800f, 4.0742529726f, 4.0987966652f, 4.1233403578f, 4.1478840504f,
4.1724277430f, 4.1969714357f, 4.2215151283f, 4.2460588209f, 4.2706025135f,
4.2951462061f, 4.3196898987f, 4.3442335913f, 4.3687772839f, 4.3933209765f,
4.4178646691f, 4.4424083617f, 4.4669520543f, 4.4914957469f, 4.5160394395f,
4.5405831321f, 4.5651268247f, 4.5896705174f, 4.6142142100f, 4.6387579026f,
4.6633015952f, 4.6878452878f, 4.7123889804f, 4.7369326730f, 4.7614763656f,
4.7860200582f, 4.8105637508f, 4.8351074434f, 4.8596511360f, 4.8841948286f,
4.9087385212f, 4.9332822138f, 4.9578259064f, 4.9823695991f, 5.0069132917f,
5.0314569843f, 5.0560006769f, 5.0805443695f, 5.1050880621f, 5.1296317547f,
5.1541754473f, 5.1787191399f, 5.2032628325f, 5.2278065251f, 5.2523502177f,
5.2768939103f, 5.3014376029f, 5.3259812955f, 5.3505249881f, 5.3750686808f,
5.3996123734f, 5.4241560660f, 5.4486997586f, 5.4732434512f, 5.4977871438f,
5.5223308364f, 5.5468745290f, 5.5714182216f, 5.5959619142f, 5.6205056068f,
5.6450492994f, 5.6695929920f, 5.6941366846f, 5.7186803772f, 5.7432240698f,
5.7677677625f, 5.7923114551f, 5.8168551477f, 5.8413988403f, 5.8659425329f,
5.8904862255f, 5.9150299181f, 5.9395736107f, 5.9641173033f, 5.9886609959f,
6.0132046885f, 6.0377483811f, 6.0622920737f, 6.0868357663f, 6.1113794589f,
6.1359231515f, 6.1604668441f, 6.1850105368f, 6.2095542294f, 6.2340979220f,
6.2586416146f,
};
static float cos_table_values[COS_TABLE_SIZE] = {
1.0000000000f, 0.9996988187f, 0.9987954562f, 0.9972904567f,
0.9951847267f, 0.9924795346f, 0.9891765100f, 0.9852776424f,
0.9807852804f, 0.9757021300f, 0.9700312532f, 0.9637760658f,
0.9569403357f, 0.9495281806f, 0.9415440652f, 0.9329927988f,
0.9238795325f, 0.9142097557f, 0.9039892931f, 0.8932243012f,
0.8819212643f, 0.8700869911f, 0.8577286100f, 0.8448535652f,
0.8314696123f, 0.8175848132f, 0.8032075315f, 0.7883464276f,
0.7730104534f, 0.7572088465f, 0.7409511254f, 0.7242470830f,
0.7071067812f, 0.6895405447f, 0.6715589548f, 0.6531728430f,
0.6343932842f, 0.6152315906f, 0.5956993045f, 0.5758081914f,
0.5555702330f, 0.5349976199f, 0.5141027442f, 0.4928981922f,
0.4713967368f, 0.4496113297f, 0.4275550934f, 0.4052413140f,
0.3826834324f, 0.3598950365f, 0.3368898534f, 0.3136817404f,
0.2902846773f, 0.2667127575f, 0.2429801799f, 0.2191012402f,
0.1950903220f, 0.1709618888f, 0.1467304745f, 0.1224106752f,
0.0980171403f, 0.0735645636f, 0.0490676743f, 0.0245412285f,
0.0000000000f, -0.0245412285f, -0.0490676743f, -0.0735645636f,
-0.0980171403f, -0.1224106752f, -0.1467304745f, -0.1709618888f,
-0.1950903220f, -0.2191012402f, -0.2429801799f, -0.2667127575f,
-0.2902846773f, -0.3136817404f, -0.3368898534f, -0.3598950365f,
-0.3826834324f, -0.4052413140f, -0.4275550934f, -0.4496113297f,
-0.4713967368f, -0.4928981922f, -0.5141027442f, -0.5349976199f,
-0.5555702330f, -0.5758081914f, -0.5956993045f, -0.6152315906f,
-0.6343932842f, -0.6531728430f, -0.6715589548f, -0.6895405447f,
-0.7071067812f, -0.7242470830f, -0.7409511254f, -0.7572088465f,
-0.7730104534f, -0.7883464276f, -0.8032075315f, -0.8175848132f,
-0.8314696123f, -0.8448535652f, -0.8577286100f, -0.8700869911f,
-0.8819212643f, -0.8932243012f, -0.9039892931f, -0.9142097557f,
-0.9238795325f, -0.9329927988f, -0.9415440652f, -0.9495281806f,
-0.9569403357f, -0.9637760658f, -0.9700312532f, -0.9757021300f,
-0.9807852804f, -0.9852776424f, -0.9891765100f, -0.9924795346f,
-0.9951847267f, -0.9972904567f, -0.9987954562f, -0.9996988187f,
-1.0000000000f, -0.9996988187f, -0.9987954562f, -0.9972904567f,
-0.9951847267f, -0.9924795346f, -0.9891765100f, -0.9852776424f,
-0.9807852804f, -0.9757021300f, -0.9700312532f, -0.9637760658f,
-0.9569403357f, -0.9495281806f, -0.9415440652f, -0.9329927988f,
-0.9238795325f, -0.9142097557f, -0.9039892931f, -0.8932243012f,
-0.8819212643f, -0.8700869911f, -0.8577286100f, -0.8448535652f,
-0.8314696123f, -0.8175848132f, -0.8032075315f, -0.7883464276f,
-0.7730104534f, -0.7572088465f, -0.7409511254f, -0.7242470830f,
-0.7071067812f, -0.6895405447f, -0.6715589548f, -0.6531728430f,
-0.6343932842f, -0.6152315906f, -0.5956993045f, -0.5758081914f,
-0.5555702330f, -0.5349976199f, -0.5141027442f, -0.4928981922f,
-0.4713967368f, -0.4496113297f, -0.4275550934f, -0.4052413140f,
-0.3826834324f, -0.3598950365f, -0.3368898534f, -0.3136817404f,
-0.2902846773f, -0.2667127575f, -0.2429801799f, -0.2191012402f,
-0.1950903220f, -0.1709618888f, -0.1467304745f, -0.1224106752f,
-0.0980171403f, -0.0735645636f, -0.0490676743f, -0.0245412285f,
-0.0000000000f, 0.0245412285f, 0.0490676743f, 0.0735645636f,
0.0980171403f, 0.1224106752f, 0.1467304745f, 0.1709618888f,
0.1950903220f, 0.2191012402f, 0.2429801799f, 0.2667127575f,
0.2902846773f, 0.3136817404f, 0.3368898534f, 0.3598950365f,
0.3826834324f, 0.4052413140f, 0.4275550934f, 0.4496113297f,
0.4713967368f, 0.4928981922f, 0.5141027442f, 0.5349976199f,
0.5555702330f, 0.5758081914f, 0.5956993045f, 0.6152315906f,
0.6343932842f, 0.6531728430f, 0.6715589548f, 0.6895405447f,
0.7071067812f, 0.7242470830f, 0.7409511254f, 0.7572088465f,
0.7730104534f, 0.7883464276f, 0.8032075315f, 0.8175848132f,
0.8314696123f, 0.8448535652f, 0.8577286100f, 0.8700869911f,
0.8819212643f, 0.8932243012f, 0.9039892931f, 0.9142097557f,
0.9238795325f, 0.9329927988f, 0.9415440652f, 0.9495281806f,
0.9569403357f, 0.9637760658f, 0.9700312532f, 0.9757021300f,
0.9807852804f, 0.9852776424f, 0.9891765100f, 0.9924795346f,
0.9951847267f, 0.9972904567f, 0.9987954562f, 0.9996988187f,
};
#endif

View File

@@ -0,0 +1,53 @@
import math
import json
def generate_cos_table(size=360, output_file="cos_table.h"):
angles = [2 * math.pi * i / size for i in range(size)]
cos_values = [math.cos(angle) for angle in angles]
with open(output_file, 'w') as f:
f.write("#ifndef COS_TABLE_H\n")
f.write("#define COS_TABLE_H\n\n")
f.write("#include <math.h>\n\n")
f.write("#ifndef M_PI\n")
f.write("#define M_PI 3.14159265358979323846f\n")
f.write("#endif\n\n")
f.write("#ifndef M_PI_2\n")
f.write("#define M_PI_2 1.57079632679489661923f\n")
f.write("#endif\n\n")
f.write("#define COS_TABLE_SIZE {}\n\n".format(size))
f.write("static float cos_table_angles[COS_TABLE_SIZE] = {\n")
for i in range(0, size, 8):
line_values = []
for j in range(i, min(i+8, size)):
line_values.append(f"{angles[j]:.10f}f")
f.write(" " + ", ".join(line_values) + ",\n")
f.write("};\n\n")
f.write("static float cos_table_values[COS_TABLE_SIZE] = {\n")
for i in range(0, size, 8):
line_values = []
for j in range(i, min(i+8, size)):
line_values.append(f"{cos_values[j]:.10f}f")
f.write(" " + ", ".join(line_values) + ",\n")
f.write("};\n\n")
f.write("#endif\n")
print(f"Таблица косинусов размером {size} точек сохранена в {output_file}")
return {
'size': size,
'angles': angles,
'cos': cos_values
}
if __name__ == "__main__":
n = int(input("Размер таблицы:"))
print("Генерация таблиц косинусов...")
generate_cos_table(n, "cos_table.h")

View File

@@ -2,7 +2,6 @@
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
#define FMATH
#ifdef FMATH #ifdef FMATH
float e_rsqrt(float x) { float e_rsqrt(float x) {
@@ -17,9 +16,43 @@ float e_rsqrt(float x) {
return conv.f; return conv.f;
} }
float e_cos(float x) { return cosf(x); } #include "cos_table.h"
float e_sin(float x) { return sinf(x); } // Вспомогательная функция для нормализации угла в [0, 2π)
float e_tan(float x) { return tanf(x); } static inline float normalize_angle(float angle) {
// Используем fmodf для быстрой нормализации
angle = fmodf(angle, 2.0f * M_PI);
if (angle < 0.0f)
angle += 2.0f * M_PI;
return angle;
}
float e_cos(float angle) {
angle = normalize_angle(angle);
float step = (2.0f * M_PI) / (COS_TABLE_SIZE - 1); // если таблица включает 2π
int index = (int)(angle / step);
if (index >= COS_TABLE_SIZE - 1)
index = COS_TABLE_SIZE - 2;
if (fabsf(angle - cos_table_angles[index]) < 1e-6f)
return cos_table_values[index];
float x0 = cos_table_angles[index];
float x1 = cos_table_angles[index + 1];
float y0 = cos_table_values[index];
float y1 = cos_table_values[index + 1];
if (x1 == x0)
return y0;
float t = (angle - x0) / (x1 - x0);
return y0 + t * (y1 - y0);
}
float e_sin(float angle) { return e_cos(angle - M_PI_2); }
float e_tan(float angle) {
float c = e_cos(angle);
if (fabsf(c) < 1e-6f)
return (e_sin(angle) > 0) ? HUGE_VALF : -HUGE_VALF;
return e_sin(angle) / c;
}
#else #else

View File

@@ -1,16 +1,21 @@
#ifndef UTILS_H #ifndef UTILS_H
#define UTILS_H #define UTILS_H
struct ScreenPoint { typedef struct ScreenPoint {
int coordinates[2]; int coordinates[2];
}; } ScreenPoint;
typedef struct ScreenPoint ScreenPoint;
struct Screen { typedef struct Color {
char red;
char green;
char blue;
} Color;
typedef struct Screen {
int width; int width;
int height; int height;
void (*draw_line)(const ScreenPoint *sp1, const ScreenPoint *sp2); void (*draw_line)(const ScreenPoint *sp1, const ScreenPoint *sp2,
}; const Color *const color);
typedef struct Screen Screen; } Screen;
#endif #endif