Skip to content

Instantly share code, notes, and snippets.

@bit-hack
Created April 7, 2020 12:14
Show Gist options
  • Select an option

  • Save bit-hack/557d9e5d7d55bc232a93fa6b954270bc to your computer and use it in GitHub Desktop.

Select an option

Save bit-hack/557d9e5d7d55bc232a93fa6b954270bc to your computer and use it in GitHub Desktop.
Quick and dirty triangle geometry drawing tool
#include <cassert>
#include <cstdint>
#include <cmath>
#include <algorithm>
#include <array>
#define _SDL_main_h
#include <SDL/SDL.h>
struct app_t {
app_t()
: _screen(nullptr)
, _active(false)
, _width(0)
, _height(0)
, _color(0xffffff)
{
}
// quick and dirty circle plotter (i know its ugly)
void circle(float x, float y, float r) {
const float pi = 3.14159265359f;
const float circ = 2.f * r * pi;
const float step = (2.f * pi) / circ;
for (float a = 0.f; a < 2.f*pi; a += step) {
float px = sinf(a) * r;
float py = cosf(a) * r;
plot(x + px, y + py);
}
}
// quick and dirty line plotter (i know its also ugly)
void line(float x0, float y0, float x1, float y1) {
const float step = 1.f / std::max(std::abs(x1-x0),
std::abs(y1-y0));
if (step > 0.f) {
for (float i = 0.f; i <= 1.f; i += step) {
const float x = x0 + (x1 - x0) * i;
const float y = y0 + (y1 - y0) * i;
plot(x, y);
}
}
}
// quick and dirty point plotter (you get the idea)
void plot(float x, float y) {
const int32_t ix = int32_t(x);
const int32_t iy = int32_t(y);
if (ix >= 0 && iy >= 0 && ix < _width && iy < _height) {
uint32_t *pix = (uint32_t*)_screen->pixels;
pix[ ix + iy * _width ] = _color;
}
}
virtual bool init(uint32_t w, uint32_t h) {
const uint32_t mode = SDL_INIT_VIDEO;
if (SDL_WasInit(mode)) {
return false;
}
if (SDL_Init(mode)) {
return false;
}
assert(!_screen);
_screen = SDL_SetVideoMode(w, h, 32, 0);
if (!_screen) {
return false;
}
_active = true;
_width = w;
_height = h;
return true;
}
virtual void on_event(const SDL_Event &event) {
switch (event.type) {
case SDL_QUIT:
_active = false;
break;
}
}
virtual void tick() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
on_event(event);
}
}
bool active() const {
return _active;
}
protected:
SDL_Surface *_screen;
bool _active;
int32_t _width, _height;
uint32_t _color;
};
struct my_app_t : public app_t {
std::array<float, 3> point_x;
std::array<float, 3> point_y;
int point_picked;
my_app_t()
: point_x({179, 249, 51})
, point_y({34, 191, 143})
, point_picked(-1) {
}
void on_event(const SDL_Event &event) override {
switch (event.type) {
case SDL_MOUSEBUTTONDOWN: {
float mx = event.button.x;
float my = event.button.y;
point_picked = -1;
float dist = 32 * 32;
for (int i = 0; i < 3; ++i) {
float dx = (mx - point_x[i]);
float dy = (my - point_y[i]);
float ndist = dx * dx + dy * dy;
if (ndist < dist) {
point_picked = i;
dist = ndist;
}
}
} break;
case SDL_MOUSEBUTTONUP:
point_picked = -1;
break;
case SDL_MOUSEMOTION:
if (point_picked >= 0) {
point_x[point_picked] = event.motion.x;
point_y[point_picked] = event.motion.y;
}
break;
}
// main handler
app_t::on_event(event);
}
void tick() override {
app_t::tick();
// clear the screen
SDL_FillRect(_screen, nullptr, 0x202020);
// draw control handles
for (int i = 0; i < 3; ++i) {
switch (i) {
case 0: _color = 0xFF0000; break;
case 1: _color = 0x00FF00; break;
case 2: _color = 0x0000FF; break;
}
circle(point_x[i], point_y[i], 7.5);
}
// draw triangle outline
_color = (-1 != point_picked) ? 0xd0d0d0 : 0x909090;
line(point_x[0], point_y[0], point_x[1], point_y[1]);
line(point_x[1], point_y[1], point_x[2], point_y[2]);
line(point_x[2], point_y[2], point_x[0], point_y[0]);
// present to the screen
SDL_Delay(1);
SDL_Flip(_screen);
}
};
int main(int argc, const char **args) {
my_app_t app;
if (!app.init(320, 240)) {
return 1;
}
while (app.active()) {
app.tick();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment