-
Notifications
You must be signed in to change notification settings - Fork 6
/
MathHelpers.js
120 lines (109 loc) · 3.24 KB
/
MathHelpers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
class MathHelpers {
static getRandomNumberBetweenTwoNumbers(min, max, round = true) {
const randomNumber = Math.random() * (max - min) + min;
return round ? Math.floor(randomNumber) : randomNumber;
}
static getSometimesNegativeRandomNumber(min, max, round = true) {
let randomNumber = this.getRandomNumberBetweenTwoNumbers(min, max, round);
return randomNumber *= Math.round(Math.random()) ? 1 : -1;
}
static sortNumbers(numberArray) {
return numberArray.sort((a, b) => a - b)
}
static getAngle(x1, y1, x2, y2) {
let result = Math.atan2(y2 - y1, x2 - x1) * (180 / Math.PI);
return result < 0 ? 360 + result : result; // range [0, 360)
}
static normalizeAngle(newAngle) {
if (newAngle > 360) {
return Math.abs(360 - newAngle);
}
else if (newAngle < 0) {
return 360 - Math.abs(newAngle);
}
return newAngle;
}
static getRadians(angle) {
return angle * Math.PI / 180;
}
static getDistanceBetween2Objects(obj1, obj2) {
var a = obj1.x - obj2.x;
var b = obj1.y - obj2.y;
return Math.sqrt(a * a + b * b);
}
static raycastFindEdge(angle, origin, lineSightInTiles) {
const { x, y } = origin;
let x2 = x + Math.cos(angle);
let y2 = y + Math.sin(angle);
const tan = Math.tan(angle);
let rx, ry, xo, yo, vx, vy;
let disV = Number.MAX_VALUE;
let disH = Number.MAX_VALUE;
let dof = 0;
const tileWidth = tileMapHandler.tileSize;
// check horizontally, intersection against vertical, ie left or right of the tile
if (y === y2) {
rx = x;
ry = y;
dof = Number.MAX_VALUE;
} else {
if (x2 > x) { // looking right
rx = Math.ceil(x / tileWidth) * tileWidth;
ry = y + (rx - x) * tan;
yo = tileWidth * tan;
xo = tileWidth;
} else {
rx = Math.floor(x / tileWidth) * tileWidth - 1;
ry = y + (rx - x) * tan;
yo = -tileWidth * tan;
xo = -tileWidth;
}
}
while (dof < lineSightInTiles) {
const tileValue = tileMapHandler.getTileTypeByPosition(rx, ry);
if (tileValue !== 0 && tileValue !== 5) {
disV = this.getDistanceBetween2Objects({ x, y }, { x: rx, y: ry });
break;
} else {
dof++;
ry += yo;
rx += xo;
}
}
vx = rx; vy = ry;
// check vertically, intersection against horizontal, ie bottom or top of the tile
if (x === x2) {
rx = x;
ry = y;
dof = Number.MAX_VALUE;
} else {
if (y2 > y) { // if looking downwards
ry = Math.ceil(y / tileWidth) * tileWidth;
rx = x + (ry - y) / tan;
xo = tileWidth / tan;
yo = tileWidth;
} else {
ry = Math.floor(y / tileWidth) * tileWidth - 1;
rx = x + (ry - y) / tan;
xo = -tileWidth / tan;
yo = -tileWidth;
}
dof = 0;
}
while (dof < lineSightInTiles) {
const tileValue = tileMapHandler.getTileTypeByPosition(rx, ry);
if (tileValue !== 0 && tileValue !== 5) {
disH = this.getDistanceBetween2Objects({ x, y }, { x: rx, y: ry });
break;
} else {
dof++;
rx += xo;
ry += yo;
}
}
if (disV < disH) {
rx = vx; ry = vy; disH = disV;
}
return { x: rx, y: ry }
}
}