Skip to content

Commit

Permalink
fix(🐛): fix bugs in atan2() (#244)
Browse files Browse the repository at this point in the history
  • Loading branch information
wcandillon authored Apr 27, 2020
1 parent 5e0b7c3 commit 4c495ce
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
28 changes: 20 additions & 8 deletions packages/core/src/Math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const {
eq,
set,
cond,
atan,
add,
multiply,
lessThan,
Expand Down Expand Up @@ -89,17 +90,28 @@ export const toDeg = proc(
// https://en.wikipedia.org/wiki/Atan2
// https://www.gamedev.net/forums/topic/441464-manually-implementing-atan2-or-atan/
// https://developer.download.nvidia.com/cg/atan2.html
// https://www.medcalc.org/manual/atan2_function.php
export const atan2 = proc(
(y: Animated.Adaptable<number>, x: Animated.Adaptable<number>) => {
const coeff1 = Math.PI / 4;
const coeff2 = 3 * coeff1;
const absY = abs(y);
const angle = cond(
greaterOrEq(x, 0),
[sub(coeff1, multiply(coeff1, divide(sub(x, absY), add(x, absY))))],
[sub(coeff2, multiply(coeff1, divide(add(x, absY), sub(absY, x))))]
const a = atan(divide(y, x));
const { PI } = Math;
return cond(
greaterThan(x, 0),
a,
cond(
and(lessThan(x, 0), greaterOrEq(y, 0)),
add(a, PI),
cond(
and(lessThan(x, 0), lessThan(y, 0)),
sub(a, PI),
cond(
and(eq(x, 0), greaterThan(y, 0)),
PI / 2,
cond(and(eq(x, 0), lessThan(y, 0)), -PI / 2, 0)
)
)
)
);
return cond(lessThan(y, 0), multiply(angle, -1), cond(eq(y, 0), 0, angle));
}
);

Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/__tests__/Coordinates.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ test("cartesian2Polar 1", () => {
const y = 100;
const center = { x: 100, y: 100 };
const { theta, radius } = cartesian2Polar(canvas2Cartesian({ x, y }, center));
expect(theta[" __value"]).toBe(0);
expect(theta[" __value"]).toBe(Math.PI);
expect(radius[" __value"]).toBe(100);
const { x: x1, y: y1 } = cartesian2Canvas(
polar2Cartesian({ theta, radius }),
center
);
expect(x1[" __value"]).toBe(200);
expect(x1[" __value"]).toBe(0);
expect(Math.round(y1[" __value"])).toBe(100);
});

Expand All @@ -71,12 +71,12 @@ test("cartesian2Polar 2", () => {
const y = 100;
const center = { x: 100, y: 100 };
const { theta, radius } = canvas2Polar({ x, y }, center);
expect(theta[" __value"]).toBe(0);
expect(theta[" __value"]).toBe(Math.PI);
expect(radius[" __value"]).toBe(100);
const { x: x1, y: y1 } = polar2Canvas(
{ theta, radius },
{ x: radius, y: radius }
);
expect(x1[" __value"]).toBe(200);
expect(x1[" __value"]).toBe(0);
expect(Math.round(y1[" __value"])).toBe(100);
});
6 changes: 6 additions & 0 deletions packages/core/src/__tests__/Math.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ test("atan2()", () => {
expect(atan2(0, 0)[" __value"]).toBe(Math.atan2(0, 0));
expect(atan2(0, 100)[" __value"]).toBe(Math.atan2(0, 100));
expect(atan2(100, 0)[" __value"]).toBe(Math.atan2(100, 0));
expect(atan2(50, 25)[" __value"]).toBe(Math.atan2(50, 25));
expect(atan2(25, 50)[" __value"]).toBe(Math.atan2(25, 50));
expect(atan2(-1, 0)[" __value"]).toBe(Math.atan2(-1, 0));
expect(atan2(-3, -4)[" __value"]).toBe(Math.atan2(-3, -4));
expect(atan2(0, 3)[" __value"]).toBe(Math.atan2(0, 3));
expect(atan2(0, -3)[" __value"]).toBe(Math.atan2(0, -3));
});

test("round()", () => {
Expand Down

0 comments on commit 4c495ce

Please sign in to comment.