Skip to content

Instantly share code, notes, and snippets.

@bynect
Last active June 20, 2022 16:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bynect/c4ed0693b9f0667e0be867f7dfe1780a to your computer and use it in GitHub Desktop.
Save bynect/c4ed0693b9f0667e0be867f7dfe1780a to your computer and use it in GitHub Desktop.
Grid with 2d rotation example in SDL2
#!/bin/sh
set -xe
gcc -o main main.c -lSDL2
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_rect.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_stdinc.h>
#include <SDL2/SDL_surface.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <SDL2/SDL.h>
#ifdef DEBUG
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
#define error() do { printf("%s:%s:%d ERROR: %s\n", __FILE__, __func__, __LINE__, SDL_GetError()); abort(); } while (false)
#define cn(...) if ((__VA_ARGS__) == NULL) error();
#define cz(...) if ((__VA_ARGS__) < 0) error();
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 800
#define LINE_SPACE 20
#define LINE_LENGHT 10
typedef struct {
int x, y;
} vec2i;
// Angle in degrees
vec2i rotate(vec2i pos, vec2i orig, double angle)
{
double radians = (3.14159265 / 180) * angle;
int px = pos.x - orig.x;
int py = pos.y - orig.y;
vec2i new = {
.x = px*SDL_cos(radians) - py*SDL_sin(radians),
.y = px*SDL_sin(radians) + py*SDL_cos(radians),
};
new.x += orig.x;
new.y += orig.y;
return new;
}
int main()
{
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_TIMER) != 0)
{
printf("Unable to initialize SDL2: %s\n", SDL_GetError());
return 1;
}
SDL_Window *window = SDL_CreateWindow("rotation", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
cn(window);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
cn(renderer);
cz(SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND));
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_UNKNOWN, SDL_TEXTUREACCESS_TARGET, 128, 128);
cn(texture);
cz(SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND));
cz(SDL_SetRenderTarget(renderer, texture));
cz(SDL_SetRenderDrawColor(renderer, 255, 255, 255, 150));
cz(SDL_RenderClear(renderer));
cz(SDL_SetRenderTarget(renderer, NULL));
cz(SDL_SetRenderDrawColor(renderer, 18, 18, 18, 255));
cz(SDL_RenderClear(renderer));
cz(SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255));
cz(SDL_RenderDrawLine(renderer, 0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
cz(SDL_RenderDrawLine(renderer, SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2, SCREEN_HEIGHT));
cz(SDL_RenderDrawLine(renderer, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
cz(SDL_RenderDrawLine(renderer, 0, SCREEN_HEIGHT, SCREEN_WIDTH, 0));
for (int i = 0; i < SCREEN_HEIGHT / LINE_SPACE; ++i)
{
cz(SDL_RenderDrawLine(renderer, SCREEN_WIDTH / 2 - LINE_LENGHT / 2, i * LINE_SPACE, SCREEN_WIDTH / 2 + LINE_LENGHT / 2, i * LINE_SPACE));
}
for (int i = 0; i < SCREEN_WIDTH / LINE_SPACE; ++i)
{
cz(SDL_RenderDrawLine(renderer, i * LINE_SPACE, SCREEN_HEIGHT / 2 - LINE_LENGHT / 2, i * LINE_SPACE, SCREEN_HEIGHT / 2 + LINE_LENGHT / 2));
}
double deg_angle = 45;
SDL_Rect rect = {
.x = SCREEN_WIDTH / 2 - 200,
.y = SCREEN_HEIGHT / 2 - 25,
.w = 400,
.h = 50,
};
cz(SDL_RenderCopyEx(renderer, texture, NULL, &rect, 0, NULL, SDL_FLIP_NONE));
cz(SDL_RenderCopyEx(renderer, texture, NULL, &rect, deg_angle, NULL, SDL_FLIP_NONE));
cz(SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255));
cz(SDL_RenderDrawLine(renderer, rect.x, rect.y + rect.h / 2, rect.x + rect.w, rect.y + rect.h / 2));
vec2i orig = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2};
vec2i pos11 = {rect.x, rect.y + rect.h / 2};
vec2i pos21 = {rect.x + rect.w, rect.y + rect.h / 2};
vec2i pos12 = rotate(pos11, orig, deg_angle);
vec2i pos22 = rotate(pos21, orig, deg_angle);
cz(SDL_RenderDrawLine(renderer, pos12.x, pos12.y, pos22.x, pos22.y));
printf("x1=%d, y1=%d, x2=%d, y2=%d\n", pos12.x, pos12.y, pos22.x, pos22.y);
vec2i v11 = {rect.x, rect.y};
vec2i v21 = {rect.x, rect.y + rect.h};
vec2i v31 = {rect.x + rect.w, rect.y};
vec2i v41 = {rect.x + rect.w, rect.y + rect.h};
vec2i v12 = rotate(v11, orig, deg_angle);
vec2i v22 = rotate(v21, orig, deg_angle);
vec2i v32 = rotate(v31, orig, deg_angle);
vec2i v42 = rotate(v41, orig, deg_angle);
SDL_Rect bounding_rect = {
.x = v22.x,
.y = v12.y,
.w = v32.x - v22.x,
.h = v42.y - v12.y,
};
SDL_RenderDrawRect(renderer, &bounding_rect);
SDL_RenderPresent(renderer);
SDL_Event event;
while (SDL_WaitEvent(&event))
{
if (event.type == SDL_QUIT) break;
else if (event.type == SDL_MOUSEBUTTONDOWN)
{
int x = event.button.x;
int y = event.button.y;
printf("x=%d, y=%d\n", x, y);
}
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment