Files
cbase/math.c
T

139 lines
3.5 KiB
C

#include "all.h"
fn bool xyzEq(XYZ a, XYZ b) {
return a.x == b.x &&
a.y == b.y &&
a.z == b.z;
}
fn Range1u64 range1u64Create(u64 min, u64 max) {
Range1u64 result = {
.min = min,
.max = max
};
if (result.min > result.max) {
result.max = min;
result.min = max;
}
return result;
}
fn Range1u64 mRangeFromNIdxMCount(u64 n_idx, u64 n_count, u64 m_count) {
u64 main_idxes_per_lane = m_count / n_count;
u64 leftover_idxes_count = m_count - main_idxes_per_lane * n_count;
u64 leftover_idxes_before_this_lane_count = Min(n_idx, leftover_idxes_count);
u64 lane_base_idx = n_idx*main_idxes_per_lane + leftover_idxes_before_this_lane_count;
u64 lane_base_idx__clamped = Min(lane_base_idx, m_count);
u64 lane_opl_idx = lane_base_idx__clamped + main_idxes_per_lane + ((n_idx < leftover_idxes_count) ? 1 : 0);
u64 lane_opl_idx__clamped = Min(lane_opl_idx, m_count);
Range1u64 result = range1u64Create(lane_base_idx__clamped, lane_opl_idx__clamped);
return result;
}
void u32Swap(u32* a, u32* b) {
int t = *a;
*a = *b;
*b = t;
}
u32 u32ArrPartition(u32 arr[], u32 low, u32 high) {
u32 pivot = arr[high];
u32 i = low - 1;
for (u32 j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
u32Swap(&arr[i], &arr[j]);
}
}
u32Swap(&arr[i + 1], &arr[high]);
return i + 1;
}
fn void u32Quicksort(u32 arr[], u32 low, u32 high) {
if (low < high) {
u32 pi = u32ArrPartition(arr, low, high);
if (pi != 0) {
u32Quicksort(arr, low, pi - 1);
}
u32Quicksort(arr, pi + 1, high);
}
}
fn void u32ReverseArray(u32 arr[], u32 size) {
u32 start = 0;
u32 end = size - 1;
while (start < end) {
u32 temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
fn Vec2f32 vec2Add(Vec2 a, Vec2 b) {
Vec2f32 result = a;
result.x += b.x;
result.y += b.y;
return result;
}
fn Vec2f32 vec2Subtract(Vec2 a, Vec2 b) {
Vec2f32 result = a;
result.x -= b.x;
result.y -= b.y;
return result;
}
fn Vec2f32 vec2FromHexCube(Vec2 map_center, XYZ cube, f32 size, f32 border_thickness) {
f32 hex_height = SQRT_3 * size;
f32 hex_width = 2.0 * size;
f32 horiz_spacing = 0.75 * (hex_width - border_thickness);
f32 vert_spacing = (hex_height - border_thickness);
bool parity = cube.x & 1;
i32 use_y = cube.y * -1;
return (Vec2) {
.x = map_center.x + (cube.x * horiz_spacing),
.y = map_center.y + ((use_y + (f32)(cube.x + parity) / 2.0) * vert_spacing) - (parity ? 0.5*vert_spacing : 0),
};
}
/* from https://graphitemaster.github.io/aau/
T midpoint(T x, T y) {
// U is the unsigned version of your type T, or same as T if T already unsigned
// digits is the number of numeric digits (not including sign) in your type T.
// std::numeric_limits<T>::digits in C++ is helpful here.
U shift = digits - 1;
U difference = (U)x - (U)y;
U sign = y < x;
U half = (difference / 2) + (sign << shift) + (sign & difference);
T mid = (T)(x + half);
return mid;
}
*/
fn i32 i32Middle(i32 x, i32 y) {
u32 shift = 31 - 1;
u32 difference = (u32)x - (u32)y;
u32 sign = y < x;
u32 half = (difference / 2) + (sign << shift) + (sign & difference);
i32 mid = (i32)(x + half);
return mid;
}
fn u32 u32Middle(u32 x, u32 y) {
u32 shift = 32 - 1;
u32 difference = (u32)x - (u32)y;
u32 sign = y < x;
u32 half = (difference / 2) + (sign << shift) + (sign & difference);
u32 mid = (u32)(x + half);
return mid;
}
fn u64 u64SafeMul(u64 x, u64 y) {
assert(!(y && x > MAX_u64/y));
return x * y;
}