Skip to content

Commit

Permalink
lib: add bitmap rotation by an arbitrary angle
Browse files Browse the repository at this point in the history
  • Loading branch information
and3rson committed Feb 29, 2024
1 parent 6717c7c commit 102986b
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
1 change: 1 addition & 0 deletions sdk/lib/lilka/src/lilka.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "lilka/loader.h"
#include "lilka/sys.h"
#include "lilka/resources.h"
#include "lilka/fmath.h"
#include "lua/luarunner.h"
#include "mjs/mjsrunner.h"

Expand Down
30 changes: 30 additions & 0 deletions sdk/lib/lilka/src/lilka/resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,39 @@
#include "stdio.h"
#include "display.h"
#include "serial.h"
#include "fmath.h"

namespace lilka {

Bitmap::Bitmap(uint32_t width, uint32_t height, int32_t transparentColor)
: width(width), height(height), transparentColor(transparentColor) {
pixels = new uint16_t[width * height];
}

Bitmap::~Bitmap() {
delete[] pixels;
}

void Bitmap::rotate(int16_t angle, Bitmap* dest, int32_t blankColor) {
// Rotate the bitmap
int cx = width / 2;
int cy = height / 2;

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int dx = x - cx;
int dy = y - cy;
int x2 = cx + dx * fCos360(angle) - dy * fSin360(angle);
int y2 = cy + dx * fSin360(angle) + dy * fCos360(angle);
if (x2 >= 0 && x2 < width && y2 >= 0 && y2 < height) {
dest->pixels[x + y * width] = pixels[x2 + y2 * width];
} else {
dest->pixels[x + y * width] = blankColor;
}
}
}
}

Bitmap* Resources::loadBitmap(String filename, int32_t transparentColor) {
FILE* file = fopen(filename.c_str(), "r");
if (!file) {
Expand Down
29 changes: 22 additions & 7 deletions sdk/lib/lilka/src/lilka/resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,28 @@ namespace lilka {
/// Пікселі зберігаються в рядку зліва направо, зверху вниз.
class Bitmap {
public:
inline Bitmap(uint32_t width, uint32_t height, int32_t transparentColor = -1)
: width(width), height(height), transparentColor(transparentColor) {
pixels = new uint16_t[width * height];
}
inline ~Bitmap() {
delete[] pixels;
}
Bitmap(uint32_t width, uint32_t height, int32_t transparentColor = -1);
~Bitmap();
/// Повертає зображення, яке отримане обертанням поточного зображення на заданий кут (в градусах), і записує його в `dest`.
///
/// @param angle Кут обертання в градусах.
/// @param dest Вказівник на зображення, в яке буде записано обернуте зображення.
/// @param blankColor 16-бітний колір (5-6-5), який буде використаний для заповнення пікселів, які виходять за межі зображення.
/// @warning `dest` повинен бути ініціалізований заздалегідь.
///
/// Приклад:
///
/// @code
/// lilka::Bitmap *bitmap = lilka::resources.loadBitmap("image.bmp");
/// if (!bitmap) {
/// Serial.println("Failed to load image");
/// return;
/// }
/// lilka::Bitmap *rotatedBitmap = new lilka::Bitmap(bitmap->width, bitmap->height);
/// // Повертаємо на 30 градусів, заповнюючи пікселі, які виходять за межі зображення, білим кольором:
/// bitmap->rotate(30, rotatedBitmap, lilka::display.color565(255, 255, 255));
/// @endcode
void rotate(int16_t angle, Bitmap *dest, int32_t blankColor);
uint32_t width;
uint32_t height;
/// 16-бітний колір (5-6-5), який буде прозорим. За замовчуванням -1 (прозорість відсутня).
Expand Down

0 comments on commit 102986b

Please sign in to comment.