-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
normalization.ts
49 lines (41 loc) · 1.23 KB
/
normalization.ts
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
import { Coordinates, Extent } from "../types";
/**
* Factory returning a function normalizing the given node's position & size.
*/
export interface NormalizationFunction {
(data: Coordinates): Coordinates;
ratio: number;
inverse(data: Coordinates): Coordinates;
applyTo(data: Coordinates): void;
}
export function createNormalizationFunction(extent: { x: Extent; y: Extent }): NormalizationFunction {
const {
x: [minX, maxX],
y: [minY, maxY],
} = extent;
let ratio = Math.max(maxX - minX, maxY - minY),
dX = (maxX + minX) / 2,
dY = (maxY + minY) / 2;
if (ratio === 0 || Math.abs(ratio) === Infinity || isNaN(ratio)) ratio = 1;
if (isNaN(dX)) dX = 0;
if (isNaN(dY)) dY = 0;
const fn = (data: Coordinates): Coordinates => {
return {
x: 0.5 + (data.x - dX) / ratio,
y: 0.5 + (data.y - dY) / ratio,
};
};
// TODO: possibility to apply this in batch over array of indices
fn.applyTo = (data: Coordinates): void => {
data.x = 0.5 + (data.x - dX) / ratio;
data.y = 0.5 + (data.y - dY) / ratio;
};
fn.inverse = (data: Coordinates): Coordinates => {
return {
x: dX + ratio * (data.x - 0.5),
y: dY + ratio * (data.y - 0.5),
};
};
fn.ratio = ratio;
return fn;
}