40 lines
1.2 KiB
Zig
40 lines
1.2 KiB
Zig
|
const std = @import("std");
|
||
|
|
||
|
pub fn add(a: anytype, b: anytype) ?@TypeOf(a + b) {
|
||
|
const result, const overflow = @addWithOverflow(a, b);
|
||
|
|
||
|
return if (overflow == 0) result else null;
|
||
|
}
|
||
|
|
||
|
pub fn fractional(value: anytype, fraction: anytype) ?@TypeOf(value) {
|
||
|
if (fraction < 0 or fraction > 1) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
const Fraction = @TypeOf(fraction);
|
||
|
|
||
|
return switch (@typeInfo(Fraction)) {
|
||
|
.Float => @intFromFloat(@as(Fraction, @floatFromInt(value)) * fraction),
|
||
|
else => @compileError("`fraction` expected float type, not " ++ @typeName(Fraction)),
|
||
|
};
|
||
|
}
|
||
|
|
||
|
pub fn lerp_angle(origin_angle: anytype, target_angle: anytype, weight: anytype) @TypeOf(origin_angle, target_angle, weight) {
|
||
|
const angle_difference = @mod(target_angle - origin_angle, std.math.tau);
|
||
|
const distance = @mod(2.0 * angle_difference, std.math.tau) - angle_difference;
|
||
|
|
||
|
return origin_angle + distance * weight;
|
||
|
}
|
||
|
|
||
|
pub fn mul(a: anytype, b: anytype) ?@TypeOf(a * b) {
|
||
|
const result, const overflow = @mulWithOverflow(a, b);
|
||
|
|
||
|
return if (overflow == 0) result else null;
|
||
|
}
|
||
|
|
||
|
pub fn sub(a: anytype, b: anytype) ?@TypeOf(a - b) {
|
||
|
const result, const overflow = @subWithOverflow(a, b);
|
||
|
|
||
|
return if (overflow == 0) result else null;
|
||
|
}
|