RationalAngleAccumulator = () => {
const
running_angle = Ratio(0, 1),
running_angle_int = running_angle[int32buffer],
angle = Ratio(0, 1),
angle_int = angle[int32buffer],
compose_angle = (numerator, denominator=1, half_turns=0) => {
angle[0] = numerator;
angle[1] = denominator;
angle_int[4] = half_turns;
normalize_ratio(angle);
const rp = running_angle[0], rq = running_angle[1];
running_angle[0] = angle[0] * rq + rp * angle[1];
running_angle[1] = rq * angle[1] - angle[0] * rp;
running_angle_int[4] += angle_int[4];
normalize_ratio(running_angle);
},
unit_complex = () => {
const
out = new Float64Array(2),
half_turn = 1 - ((running_angle_int[4] & 1) << 1),
scale = half_turn / Math.hypot(running_angle[0], running_angle[1]);
out[0] = running_angle[1] * scale, out[1] = running_angle[0] * scale;
return out;
},
tangent = () => {
return running_angle[0] / running_angle[1];
},
angle_measure = () => {
return (
Math.PI * running_angle_int[4] +
Math.atan2(running_angle[0], running_angle[1]));
},
angle_measure_degrees = () => {
return (
180 * running_angle_int[4] +
DEGREES * Math.atan2(running_angle[0], running_angle[1]));
};
return {
running_angle,
compose_angle,
unit_complex,
tangent,
angle_measure,
angle_measure_degrees,
}
}