mirror of
https://github.com/StepanovPlaton/C3DGraphicEngine.git
synced 2026-04-03 20:30:42 +04:00
Add micro build
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -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
19
.vscode/settings.json
vendored
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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] =
|
||||||
|
(2 * camera->max_distance * camera->min_distance) /
|
||||||
(camera->min_distance - camera->max_distance);
|
(camera->min_distance - camera->max_distance);
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
@@ -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];
|
||||||
|
|||||||
@@ -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
|
||||||
37
src/main.c
37
src/main.c
@@ -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(¢er_of_object, -1);
|
point_mult_number(¢er_of_object, -1);
|
||||||
point_add_point(¢er_of_object, objects[i].position);
|
point_add_point(¢er_of_object, objects[i].position);
|
||||||
|
|
||||||
float translate_matrix[4][4];
|
float translate_matrix[4 * 4];
|
||||||
point_create_translate_matrix(¢er_of_object, translate_matrix, 1);
|
point_create_translate_matrix(¢er_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); }
|
||||||
@@ -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}};
|
||||||
|
|||||||
73
src/platforms/micro/lib/I2C/I2C.c
Normal file
73
src/platforms/micro/lib/I2C/I2C.c
Normal 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;
|
||||||
|
}
|
||||||
15
src/platforms/micro/lib/I2C/I2C.h
Normal file
15
src/platforms/micro/lib/I2C/I2C.h
Normal 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
|
||||||
111
src/platforms/micro/lib/MPU6050/MPU6050.c
Normal file
111
src/platforms/micro/lib/MPU6050/MPU6050.c
Normal 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;
|
||||||
|
}
|
||||||
21
src/platforms/micro/lib/MPU6050/MPU6050.h
Normal file
21
src/platforms/micro/lib/MPU6050/MPU6050.h
Normal 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
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
const Color *const color) {
|
||||||
|
HPEN hPen =
|
||||||
|
CreatePen(PS_SOLID, 1, RGB(color->red, color->green, color->blue));
|
||||||
HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
|
HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
|
||||||
|
|
||||||
void draw_line(const ScreenPoint *sp1, const ScreenPoint *sp2) {
|
|
||||||
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
138
src/utils/cos_table.h
Normal 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
|
||||||
53
src/utils/create_trig_table.py
Normal file
53
src/utils/create_trig_table.py
Normal 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")
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user