1/*
2 * LegacyClonk
3 *
4 * Copyright (c) 1998-2000, Matthes Bender (RedWolf Design)
5 * Copyright (c) 2017-2020, The LegacyClonk Team and contributors
6 *
7 * Distributed under the terms of the ISC license; see accompanying file
8 * "COPYING" for details.
9 *
10 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11 * See accompanying file "TRADEMARK" for details.
12 *
13 * To redistribute this file separately, substitute the full license texts
14 * for the above references.
15 */
16
17#include "C4Math.h"
18
19#include <cmath>
20#include <numbers>
21
22int32_t Distance(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2)
23{
24 int64_t dx = int64_t(iX1) - iX2, dy = int64_t(iY1) - iY2;
25 int64_t d2 = dx * dx + dy * dy;
26 if (d2 < 0) return -1;
27 int32_t dist = int32_t(sqrt(x: double(d2)));
28 if (int64_t(dist) * dist < d2) ++dist;
29 if (int64_t(dist) * dist > d2) --dist;
30 return dist;
31}
32
33int Angle(int iX1, int iY1, int iX2, int iY2)
34{
35 int iAngle = static_cast<int>(180.0 * atan2f(y: float(Abs(val: iY1 - iY2)), x: float(Abs(val: iX1 - iX2))) * std::numbers::inv_pi_v<float>);
36 if (iX2 > iX1)
37 {
38 if (iY2 < iY1) iAngle = 90 - iAngle; else iAngle = 90 + iAngle;
39 }
40 else
41 {
42 if (iY2 < iY1) iAngle = 270 + iAngle; else iAngle = 270 - iAngle;
43 }
44 return iAngle;
45}
46
47/* Fast integer exponentiation */
48int Pow(int base, int exponent)
49{
50 if (exponent < 0) return 0;
51
52 int result = 1;
53
54 if (exponent & 1) result = base;
55 exponent >>= 1;
56
57 while (exponent)
58 {
59 base *= base;
60 if (exponent & 1) result *= base;
61 exponent >>= 1;
62 }
63
64 return result;
65}
66