From 7277f606f47621a79eb54601201886c7d690038f Mon Sep 17 00:00:00 2001 From: Andreew Gregory Date: Thu, 29 Jan 2026 19:05:10 +0300 Subject: [PATCH] I am gonna go insane --- src/l1/anne/geom.h | 42 ++++++++++++++++-------- src/l1_5/core/quaternion.h | 4 +++ src/l1_5/marie/prim_shape_geom.h | 55 ++++++++++++++++++++++++++++++++ src/l2/marie/shape_geom.h | 51 +---------------------------- 4 files changed, 88 insertions(+), 64 deletions(-) create mode 100644 src/l1_5/core/quaternion.h create mode 100644 src/l1_5/marie/prim_shape_geom.h diff --git a/src/l1/anne/geom.h b/src/l1/anne/geom.h index 0868971..689d1a4 100644 --- a/src/l1/anne/geom.h +++ b/src/l1/anne/geom.h @@ -55,6 +55,17 @@ NODISCARD VecU8 generate_xvecn_struct_and_base_methods(SpanU8 xvec, SpanU8 memb, VecU8_append_vec(&res, VecU8_fmt("-A.%s", vec_field_name(ci))); } VecU8_append_span(&res, cstr(" };\n}\n\n")); + /* xvecn_mul_scal method */ + VecU8_append_vec(&res, VecU8_fmt( + "%s %s_mul_scal(%s A, %s B) {\n" + SPACE "return (%s) { ", + xvecn, xvecn, xvecn, memb, xvecn)); + for (int ci = 0; ci < n; ci++) { + if (ci) + VecU8_append_span(&res, cstr(", ")); + VecU8_append_vec(&res, VecU8_fmt("A.%s * B", vec_field_name(ci))); + } + VecU8_append_span(&res, cstr(" };\n}\n\n")); VecU8_drop(g_xvecn); return res; @@ -75,17 +86,6 @@ NODISCARD VecU8 generate_xvecn_struct_and_cool_methods(SpanU8 xvec, SpanU8 memb, VecU8_append_vec(&res, VecU8_fmt("A.%s * A.%s", vec_field_name(i), vec_field_name(i))); } VecU8_append_span(&res, cstr(");\n}\n\n")); - /* xvecn_mul_scal method */ - VecU8_append_vec(&res, VecU8_fmt( - "%s %s_mul_scal(%s A, %s B) {\n" - SPACE "return (%s) { ", - xvecn, xvecn, xvecn, memb, xvecn)); - for (int ci = 0; ci < n; ci++) { - if (ci) - VecU8_append_span(&res, cstr(", ")); - VecU8_append_vec(&res, VecU8_fmt("A.%s * B", vec_field_name(ci))); - } - VecU8_append_span(&res, cstr(" };\n}\n\n")); /* xvecn_div_by_scal method */ VecU8_append_vec(&res, VecU8_fmt( "%s %s_div_by_scal(%s A, %s B) {\n" @@ -332,6 +332,12 @@ NODISCARD VecU8 generate_square_xmatn_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 m } VecU8_append_span(&res, cstr(" };\n\n")); + // VecU8_append_vec(&res, VecU8_fmt( + // "%s %s_det(%s a){\n" + // SPACE "return ", memb, xmatn, xmatn)); + // + // VecU8_append_span(&res, cstr(";\n}\n\n")); + VecU8_drop(g_xmatn); return res; } @@ -466,7 +472,7 @@ NODISCARD VecU8 generate_xvec234_structs_and_cool_methods(SpanU8 xvec, SpanU8 me return res; } -NODISCARD VecU8 generate_xmat234x234_structs_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int sizeof_member) { +NODISCARD VecU8 generate_xmat234x234_structs_and_base_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int sizeof_member){ VecU8 res = VecU8_new(); for (int cols = 2; cols <= 4; cols++) { for (int rows = 2; rows <= 4; rows++) { @@ -488,6 +494,12 @@ NODISCARD VecU8 generate_xmat234x234_structs_methods(SpanU8 xmat, SpanU8 xvec, S } } } + return res; +} + +NODISCARD VecU8 generate_xmat234x234_structs_and_cool_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int sizeof_member){ + VecU8 res = VecU8_new(); + VecU8_append_vec(&res, generate_xmat234x234_structs_and_base_methods(xmat, xvec, memb, sizeof_member)); VecU8_append_vec(&res, generate_xmat_inverse_methods(xmat, xvec, memb)); return res; } @@ -507,7 +519,9 @@ void generate_geom_header() { VecU8_append_vec(&res.result, generate_xvec234_structs_and_cool_methods(cstr("vec"), cstr("float"), cstr("sqrtf"))); VecU8_append_vec(&res.result, generate_xvec234_structs_and_cool_methods(cstr("dvec"), cstr("double"), cstr("sqrt"))); - VecU8_append_vec(&res.result, generate_xmat234x234_structs_methods(cstr("mat"), cstr("vec"), cstr("float"), sizeof(float))); - /* VecU8_append_vec(&res.result, generate_xmat234x234_structs_methods(cstr("dmat"), cstr("dvec"), cstr("double"), sizeof(double))); */ + + VecU8_append_vec(&res.result, generate_xmat234x234_structs_and_cool_methods(cstr("mat"), cstr("vec"), cstr("float"), sizeof(float))); + VecU8_append_vec(&res.result, generate_xmat234x234_structs_and_base_methods(cstr("s64mat"), cstr("s64vec"), cstr("S64"), sizeof(S64))); + finish_header(res); } diff --git a/src/l1_5/core/quaternion.h b/src/l1_5/core/quaternion.h new file mode 100644 index 0000000..3af0a23 --- /dev/null +++ b/src/l1_5/core/quaternion.h @@ -0,0 +1,4 @@ +#pragma once + +#include "../../../gen/l1/geom.h" + diff --git a/src/l1_5/marie/prim_shape_geom.h b/src/l1_5/marie/prim_shape_geom.h new file mode 100644 index 0000000..fd34789 --- /dev/null +++ b/src/l1_5/marie/prim_shape_geom.h @@ -0,0 +1,55 @@ +#pragma once + +#include "../../../gen/l1/geom.h" + +/* any inv exp q => any abs bitness a => + * vec2#(a)#.(q) -> vec2#(a)#.(q) -> vec2#(a)#.(q) -> vec2#(2a+3)#.(2q) */ +S64 marie_precise_surface(s64vec2 vi, s64vec2 vj, s64vec2 u){ + s64vec2 da = s64vec2_minus_s64vec2(vi, u); + s64vec2 db = s64vec2_minus_s64vec2(vj, u); + /* da, db are vec2#(a+1)#.(q) */ + return da.x * db.y - da.y * db.x; +} + +bool marie_precise_do_intersect_2d_interv_and_seg(s64vec2 a, s64vec2 b, s64vec2 c, s64vec2 d){ + s64vec2 alpha = s64vec2_minus_s64vec2(b, a); + s64vec2 beta = s64vec2_minus_s64vec2(c, d); + s64vec2 gamma = s64vec2_minus_s64vec2(c, a); + S64 det_alpha_beta = alpha.x * beta.y - alpha.y * beta.x; + S64 det_gamma_beta = gamma.x * beta.y - gamma.y * beta.x; + if (det_alpha_beta == 0) { + if (det_gamma_beta != 0) + return false; + if (a.x < b.x) { + return !(c.x <= a.x && d.x <= a.x) && !(b.x <= c.x && b.x <= d.x); + } else if (b.x < a.x) { + return !(c.x <= b.x && d.x <= b.x) && !(a.x <= c.x && a.x <= d.x); + } else if (a.y < b.y) { + return !(c.y <= a.y && d.y <= a.y) && !(b.y <= c.y && b.y <= d.y); + } else if (b.y < a.y) { + return !(c.y <= b.y && d.y <= b.y) && !(a.y <= c.y && a.y <= d.y); + } else + return false; /* This code is unreachable, actually */ + } + /* Return det_gamma_beta/det_alpha_beta in (0; 1) */ + return 0 < det_gamma_beta && det_gamma_beta < det_alpha_beta; +} + +/* Does not work for degenerate case where s(b_prev, b, b_next) = 0. + * Returns false if a is on the edge of angle(b_prev, b, b_next) */ +bool marie_precise_is_in_ccw_angle(s64vec2 b_prev, s64vec2 b, s64vec2 b_next, s64vec2 a){ + S64 sx = marie_precise_surface(b_prev, b, b_next); + S64 sy = marie_precise_surface(b_prev, b, a); + S64 sz = marie_precise_surface(b, b_next, a); + if (sx < 0) { + return sy > 0 || sz > 0; + } else { + return sy > 0 && sz > 0; + } +} + +/* Read source code to understand */ +bool marie_order_s64vec2_less(s64vec2 a, s64vec2 b){ + return a.x < b.x || (a.x == b.x && a.y < b.y); +} + diff --git a/src/l2/marie/shape_geom.h b/src/l2/marie/shape_geom.h index 7ea8294..5b89a60 100644 --- a/src/l2/marie/shape_geom.h +++ b/src/l2/marie/shape_geom.h @@ -8,57 +8,8 @@ #include "../../../gen/l1/VecAndSpan_VecU64.h" #include #include +#include "../../l1_5/marie/prim_shape_geom.h" -/* any inv exp q => any abs bitness a => - * vec2#(a)#.(q) -> vec2#(a)#.(q) -> vec2#(a)#.(q) -> vec2#(2a+3)#.(2q) */ -S64 marie_precise_surface(s64vec2 vi, s64vec2 vj, s64vec2 u){ - s64vec2 da = s64vec2_minus_s64vec2(vi, u); - s64vec2 db = s64vec2_minus_s64vec2(vj, u); - /* da, db are vec2#(a+1)#.(q) */ - return da.x * db.y - da.y * db.x; -} - -bool marie_precise_do_intersect_2d_interv_and_seg(s64vec2 a, s64vec2 b, s64vec2 c, s64vec2 d){ - s64vec2 alpha = s64vec2_minus_s64vec2(b, a); - s64vec2 beta = s64vec2_minus_s64vec2(c, d); - s64vec2 gamma = s64vec2_minus_s64vec2(c, a); - S64 det_alpha_beta = alpha.x * beta.y - alpha.y * beta.x; - S64 det_gamma_beta = gamma.x * beta.y - gamma.y * beta.x; - if (det_alpha_beta == 0) { - if (det_gamma_beta != 0) - return false; - if (a.x < b.x) { - return !(c.x <= a.x && d.x <= a.x) && !(b.x <= c.x && b.x <= d.x); - } else if (b.x < a.x) { - return !(c.x <= b.x && d.x <= b.x) && !(a.x <= c.x && a.x <= d.x); - } else if (a.y < b.y) { - return !(c.y <= a.y && d.y <= a.y) && !(b.y <= c.y && b.y <= d.y); - } else if (b.y < a.y) { - return !(c.y <= b.y && d.y <= b.y) && !(a.y <= c.y && a.y <= d.y); - } else - return false; /* This code is unreachable, actually */ - } - /* Return det_gamma_beta/det_alpha_beta in (0; 1) */ - return 0 < det_gamma_beta && det_gamma_beta < det_alpha_beta; -} - -/* Does not work for degenerate case where s(b_prev, b, b_next) = 0. - * Returns false if a is on the edge of angle(b_prev, b, b_next) */ -bool marie_precise_is_in_ccw_angle(s64vec2 b_prev, s64vec2 b, s64vec2 b_next, s64vec2 a){ - S64 sx = marie_precise_surface(b_prev, b, b_next); - S64 sy = marie_precise_surface(b_prev, b, a); - S64 sz = marie_precise_surface(b, b_next, a); - if (sx < 0) { - return sy > 0 || sz > 0; - } else { - return sy > 0 && sz > 0; - } -} - -/* Read source code to understand */ -bool marie_order_s64vec2_less(s64vec2 a, s64vec2 b){ - return a.x < b.x || (a.x == b.x && a.y < b.y); -} typedef struct{ U64 prev, next;