Compare commits

..

6 Commits

6 changed files with 83 additions and 47 deletions

View File

@ -2,7 +2,7 @@
CC=clang CC=clang
CFLAGS="-g -Wall -Iinclude -Iintern $(pkg-config --cflags sdl2)" CFLAGS="-g -Wall -Iinclude -Iintern $(pkg-config --cflags sdl2)"
LIBS="$(pkg-config --libs sdl2)" LIBS="$(pkg-config --libs sdl2) -lm"
SRC=src/*.c SRC=src/*.c
OUT=main OUT=main

View File

@ -3,6 +3,8 @@
#include "aliases/aliases.h" #include "aliases/aliases.h"
#define square(x) (x * x)
i32 min(i32 a, i32 b); i32 min(i32 a, i32 b);
i32 max(i32 a, i32 b); i32 max(i32 a, i32 b);

View File

@ -8,6 +8,7 @@
#include <stdbool.h> #include <stdbool.h>
typedef struct point point; typedef struct point point;
typedef point vec2;
typedef struct line line; typedef struct line line;
typedef struct triangle triangle; typedef struct triangle triangle;
typedef struct quad quad; typedef struct quad quad;
@ -67,13 +68,17 @@ bool init_window(window *wnd, const char *title, u32 width, u32 height, i32 x,
void cleanup_window(window *wnd); void cleanup_window(window *wnd);
void clear_window(const window *wnd, colour colour); void clear_window(const window *wnd, colour colour);
void swap_buffers(const window *wnd); void swap_buffers(const window *wnd);
vec2 line_direction(const line *ln);
void draw_point(const window *wnd, point p, colour colour); void draw_point(const window *wnd, point p, colour colour);
void draw_line(const window *wnd, const line *ln, colour colour); void draw_line(const window *wnd, const line *ln, colour colour);
void draw_triangle(const window *wnd, triangle triangle, colour colour); void draw_triangle(const window *wnd, triangle triangle, colour colour);
void fill_triangle(const window *wnd, triangle triangle, colour colour);
void draw_quad(const window *wnd, quad qd, colour colour); void draw_quad(const window *wnd, quad qd, colour colour);
void fill_quad(const window *wnd, quad qd, colour colour);
void draw_rect(const window *wnd, rect rec, colour colour); void draw_rect(const window *wnd, rect rec, colour colour);
void fill_triangle(const window *wnd, triangle triangle, colour colour);
void fill_quad(const window *wnd, quad qd, colour colour);
void fill_rect(const window *wnd, rect rec, colour colour); void fill_rect(const window *wnd, rect rec, colour colour);
#endif // !WINDOW_H #endif // !WINDOW_H

View File

@ -77,8 +77,8 @@ i32 run_main_loop(void) {
i32 toolbox_button_x = (toolbox->width - BUTTON_WIDTH) / 2; i32 toolbox_button_x = (toolbox->width - BUTTON_WIDTH) / 2;
line ln = (line){ line ln = (line){
(point){20, 40}, (point){80, 100},
(point){60, 200}, (point){120, 300},
}; };
while (comp.running) { while (comp.running) {

View File

@ -3,10 +3,11 @@
#include "aliases/aliases.h" #include "aliases/aliases.h"
#include "math_utils.h" #include "math_utils.h"
#include "window.h" #include "window.h"
#include <math.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#define NOODLE_WIDTH 2 #define NOODLE_HALF_WIDTH 2
INTERNAL bool aabb(rect rec, i32 x, i32 y); INTERNAL bool aabb(rect rec, i32 x, i32 y);
@ -146,18 +147,37 @@ line ui_noodle(const window *wnd, ui_ctx *ctx, line ln,
if (horizontal) { if (horizontal) {
i32 x = min(ln.p0.x, ln.p1.x); i32 x = min(ln.p0.x, ln.p1.x);
bounding_box.topleft = (point){x, ln.p0.y}; bounding_box.topleft = (point){x, ln.p0.y - NOODLE_HALF_WIDTH};
bounding_box.w = abs(ln.p1.x - ln.p0.x); bounding_box.w = abs(ln.p1.x - ln.p0.x);
bounding_box.h = NOODLE_WIDTH; bounding_box.h = NOODLE_HALF_WIDTH * 2;
fill_rect(wnd, bounding_box, colours.fill); fill_rect(wnd, bounding_box, colours.fill);
} else { } else {
quad qd = (quad){ vec2 direction = line_direction(&ln);
.p0 = ln.p0,
.p1 = (point){ln.p0.x + NOODLE_WIDTH, ln.p0.y}, quad qd = (quad){0};
.p2 = ln.p1,
.p3 = (point){ln.p1.x + NOODLE_WIDTH, ln.p1.y}, if (direction.x == 0) {
qd = (quad){
.p0 = (point){ln.p0.x - NOODLE_HALF_WIDTH, ln.p0.y},
.p1 = (point){ln.p0.x + NOODLE_HALF_WIDTH, ln.p0.y},
.p2 = (point){ln.p1.x - NOODLE_HALF_WIDTH, ln.p1.y},
.p3 = (point){ln.p1.x + NOODLE_HALF_WIDTH, ln.p1.y},
}; };
} else {
f32 slope = (f32)(direction.y) / direction.x;
f32 perpendicular_dy =
sqrtf(square(NOODLE_HALF_WIDTH) / (square((f32)slope) + 1.0f));
f32 perpendicular_dx = -1.0f * slope * perpendicular_dy;
qd = (quad){
.p0 = (point){ln.p0.x - perpendicular_dx, ln.p0.y - perpendicular_dy},
.p1 = (point){ln.p0.x + perpendicular_dx, ln.p0.y + perpendicular_dy},
.p2 = (point){ln.p1.x - perpendicular_dx, ln.p1.y - perpendicular_dy},
.p3 = (point){ln.p1.x + perpendicular_dx, ln.p1.y + perpendicular_dy},
};
}
fill_quad(wnd, qd, colours.fill); fill_quad(wnd, qd, colours.fill);

View File

@ -6,6 +6,8 @@
#include <SDL2/SDL_video.h> #include <SDL2/SDL_video.h>
#include <stdbool.h> #include <stdbool.h>
INTERNAL inline bool inside_triangle(triangle tri, point p);
bool init_window(window *wnd, const char *title, u32 width, u32 height, i32 x, bool init_window(window *wnd, const char *title, u32 width, u32 height, i32 x,
i32 y) { i32 y) {
i32 pos_x = x >= 0 ? x : SDL_WINDOWPOS_CENTERED; i32 pos_x = x >= 0 ? x : SDL_WINDOWPOS_CENTERED;
@ -70,6 +72,13 @@ void clear_window(const window *wnd, colour colour) {
void swap_buffers(const window *wnd) { SDL_RenderPresent(wnd->renderer); } void swap_buffers(const window *wnd) { SDL_RenderPresent(wnd->renderer); }
vec2 line_direction(const line *ln) {
return (vec2){
.x = ln->p1.x - ln->p0.x,
.y = ln->p1.y - ln->p0.y,
};
}
void draw_point(const window *wnd, point p, colour colour) { void draw_point(const window *wnd, point p, colour colour) {
set_colour(wnd, colour); set_colour(wnd, colour);
SDL_RenderDrawPoint(wnd->renderer, p.x, p.y); SDL_RenderDrawPoint(wnd->renderer, p.x, p.y);
@ -90,21 +99,24 @@ void draw_triangle(const window *wnd, triangle triangle, colour colour) {
draw_line(wnd, &ln2, colour); draw_line(wnd, &ln2, colour);
} }
INTERNAL inline bool inside_triangle(triangle tri, point p) { void draw_rect(const window *wnd, rect rec, colour colour) {
// Based on the following video: set_colour(wnd, colour);
// https://www.youtube.com/watch?v=HYAgJN3x4GA
f32 cy_min_ay = tri.p2.y - tri.p0.y;
f32 cx_min_ax = tri.p2.x - tri.p0.x;
f32 by_min_ay = tri.p1.y - tri.p0.y;
f32 bx_min_ax = tri.p1.x - tri.p0.x;
f32 w1 = SDL_Rect dst = {rec.topleft.x, rec.topleft.y, rec.w, rec.h};
(tri.p0.x * cy_min_ay + (p.y - tri.p0.y) * cx_min_ax - p.x * cy_min_ay) /
(by_min_ay * cx_min_ax - bx_min_ax * cy_min_ay);
f32 w2 = (p.y - tri.p0.y - w1 * by_min_ay) / cy_min_ay; SDL_RenderDrawRect(wnd->renderer, &dst);
}
return w1 >= 0.0f && w2 >= 0.0f && (w1 + w2) <= 1.0f; void draw_quad(const window *wnd, quad qd, colour colour) {
line l0 = (line){qd.p0, qd.p1};
line l1 = (line){qd.p1, qd.p3};
line l2 = (line){qd.p3, qd.p2};
line l3 = (line){qd.p2, qd.p0};
draw_line(wnd, &l0, colour);
draw_line(wnd, &l1, colour);
draw_line(wnd, &l2, colour);
draw_line(wnd, &l3, colour);
} }
void fill_triangle(const window *wnd, triangle tri, colour colour) { void fill_triangle(const window *wnd, triangle tri, colour colour) {
@ -134,16 +146,12 @@ void fill_triangle(const window *wnd, triangle tri, colour colour) {
} }
} }
void draw_quad(const window *wnd, quad qd, colour colour) { void fill_rect(const window *wnd, rect rec, colour colour) {
line l0 = (line){qd.p0, qd.p1}; set_colour(wnd, colour);
line l1 = (line){qd.p1, qd.p3};
line l2 = (line){qd.p3, qd.p2};
line l3 = (line){qd.p2, qd.p0};
draw_line(wnd, &l0, colour); SDL_Rect dst = {rec.topleft.x, rec.topleft.y, rec.w, rec.h};
draw_line(wnd, &l1, colour);
draw_line(wnd, &l2, colour); SDL_RenderFillRect(wnd->renderer, &dst);
draw_line(wnd, &l3, colour);
} }
void fill_quad(const window *wnd, quad qd, colour colour) { void fill_quad(const window *wnd, quad qd, colour colour) {
@ -154,18 +162,19 @@ void fill_quad(const window *wnd, quad qd, colour colour) {
fill_triangle(wnd, t1, colour); fill_triangle(wnd, t1, colour);
} }
void draw_rect(const window *wnd, rect rec, colour colour) { INTERNAL inline bool inside_triangle(triangle tri, point p) {
set_colour(wnd, colour); // Based on the following video:
// https://www.youtube.com/watch?v=HYAgJN3x4GA
f32 cy_min_ay = tri.p2.y - tri.p0.y;
f32 cx_min_ax = tri.p2.x - tri.p0.x;
f32 by_min_ay = tri.p1.y - tri.p0.y;
f32 bx_min_ax = tri.p1.x - tri.p0.x;
SDL_Rect dst = {rec.topleft.x, rec.topleft.y, rec.w, rec.h}; f32 w1 =
(tri.p0.x * cy_min_ay + (p.y - tri.p0.y) * cx_min_ax - p.x * cy_min_ay) /
(by_min_ay * cx_min_ax - bx_min_ax * cy_min_ay);
SDL_RenderDrawRect(wnd->renderer, &dst); f32 w2 = (p.y - tri.p0.y - w1 * by_min_ay) / cy_min_ay;
}
return w1 >= 0.0f && w2 >= 0.0f && (w1 + w2) <= 1.0f;
void fill_rect(const window *wnd, rect rec, colour colour) {
set_colour(wnd, colour);
SDL_Rect dst = {rec.topleft.x, rec.topleft.y, rec.w, rec.h};
SDL_RenderFillRect(wnd->renderer, &dst);
} }