Skip to content

Commit 515981d

Browse files
authored
Tweak warp parameters (#28)
1 parent 4a454f5 commit 515981d

4 files changed

Lines changed: 35 additions & 11 deletions

File tree

examples/website/area/app.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,24 @@ import {pentagonArea} from 'a5/core/utils';
1515
const H3_RESOLUTION = 1; // 1
1616
const A5_RESOLUTION = 4; // 4
1717

18+
const AUTHALIC_RADIUS = 6371.0072; // km
19+
const AUTHALIC_AREA = 4 * Math.PI * AUTHALIC_RADIUS * AUTHALIC_RADIUS;
20+
1821
// 'Bold' color scheme
1922
const COLORS = ['#7F3C8D', '#11A579', '#3969AC', '#F2B701', '#E73F74', '#80BA5A', '#E68310', '#008695', '#CF1C90', '#f97b72', '#4b4b8f', '#A5AA99'];
2023

2124
// Add Controls component
2225
const Controls: React.FC<{
2326
areaLimits: [number, number];
27+
authalicAverageArea: number;
2428
perimeterLimits: [number, number];
2529
tilingSystem: 'h3' | 'a5';
2630
onTilingSystemChange: (system: 'h3' | 'a5') => void;
27-
}> = ({areaLimits, perimeterLimits, tilingSystem, onTilingSystemChange}) => {
31+
}> = ({areaLimits, authalicAverageArea, perimeterLimits, tilingSystem, onTilingSystemChange}) => {
2832
const [minArea, maxArea] = areaLimits;
2933
const [minPerimeter, maxPerimeter] = perimeterLimits;
3034
const areaRatio = maxArea / minArea;
35+
const areaError = (maxArea / authalicAverageArea - 1) * 100; // Percent that largest cell is larger than authalic average
3136
const perimeterRatio = maxPerimeter / minPerimeter;
3237

3338
return (
@@ -59,6 +64,8 @@ const Controls: React.FC<{
5964
<div>Min Area: {minArea.toFixed(2)} km²</div>
6065
<div>Max Area: {maxArea.toFixed(2)} km²</div>
6166
<div>Area Ratio: {areaRatio.toFixed(4)}</div>
67+
<div>Authalic Average Area: {authalicAverageArea.toFixed(2)} km²</div>
68+
<div style={{fontWeight: 'bold'}}>Area Error: {areaError.toFixed(2)}%</div>
6269

6370
<h3 style={{margin: '12px 0 8px', fontSize: '14px'}}>Area Statistics</h3>
6471
<div>Min Perimeter: {minPerimeter.toFixed(2)} km</div>
@@ -668,6 +675,10 @@ const App: React.FC<{ isMobile?: boolean }> = ({ isMobile = false }) => {
668675
}
669676
}
670677

678+
// Cell count
679+
const cellCount = tilingSystem === 'h3' ? h3Output.length : a5Output.length;
680+
const authalicAverageArea = AUTHALIC_AREA / cellCount;
681+
671682
// Combine layers
672683
const layers = highlightLayer ? [baseLayer, highlightLayer] : [baseLayer];
673684

@@ -703,6 +714,7 @@ const App: React.FC<{ isMobile?: boolean }> = ({ isMobile = false }) => {
703714
</Map>
704715
<Controls
705716
areaLimits={areaLimits}
717+
authalicAverageArea={authalicAverageArea}
706718
perimeterLimits={perimeterLimits}
707719
tilingSystem={tilingSystem}
708720
onTilingSystemChange={handleTilingSystemChange}

modules/core/constants.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ export const distanceToEdge = φ - 1;
2323
export const distanceToVertex = distanceToEdge / Math.cos(PI_OVER_5);
2424

2525
// Warping parameters
26-
export const WARP_FACTOR = 0.515; // Set to near 0 to disable warping
26+
export const WARP_FACTORS = {
27+
BETA_SCALE: 0.5115918059668587,
28+
RHO_SHIFT: 0.9461616498962347,
29+
RHO_SCALE: 0.04001633808056544,
30+
RHO_SCALE2: 0.008305829720486808,
31+
}
2732

2833
// Dodecahedron sphere radii (normalized to unit radius for inscribed sphere)
2934
/**

modules/core/warp.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Copyright (c) A5 contributors
44

55
import type { Radians, Polar } from './coordinate-systems';
6-
import { distanceToEdge, PI_OVER_5, TWO_PI_OVER_5, WARP_FACTOR } from './constants';
6+
import { distanceToEdge, PI_OVER_5, TWO_PI_OVER_5, WARP_FACTORS } from './constants';
77

88
export function normalizeGamma(gamma: Radians): Radians {
99
const segment = gamma / TWO_PI_OVER_5;
@@ -16,13 +16,13 @@ export function normalizeGamma(gamma: Radians): Radians {
1616
}
1717

1818
function _warpBeta(beta: number) {
19-
const shiftedBeta = beta * WARP_FACTOR;
20-
return Math.tan(shiftedBeta);
19+
const x = beta * WARP_FACTORS.BETA_SCALE;
20+
return Math.tan(x);
2121
}
2222

2323
function _unwarpBeta(beta: number) {
2424
const shiftedBeta = Math.atan(beta);
25-
return shiftedBeta / WARP_FACTOR;
25+
return shiftedBeta / WARP_FACTORS.BETA_SCALE;
2626
}
2727

2828
const betaMax = PI_OVER_5;
@@ -33,25 +33,32 @@ export function warpBeta(beta: number): number {
3333
}
3434

3535
export function unwarpBeta(beta: number): number {
36+
const WARP_SCALER = _warpBeta(betaMax) / betaMax;
3637
return _unwarpBeta(beta * WARP_SCALER);
3738
}
3839

40+
function rhoScaleFactor(betaRatio: number) {
41+
const beta2 = betaRatio * betaRatio;
42+
const beta4 = beta2 * beta2;
43+
return (WARP_FACTORS.RHO_SHIFT - WARP_FACTORS.RHO_SCALE * beta2 - WARP_FACTORS.RHO_SCALE2 * beta4);
44+
}
45+
3946
function warpRho(rho: number, beta: number) {
4047
const betaRatio = Math.abs(beta) / betaMax;
41-
const shiftedRho = rho * (0.95 - 0.05 * betaRatio);
48+
const shiftedRho = rho * rhoScaleFactor(betaRatio);
4249
return Math.tan(shiftedRho);
4350
}
4451

4552
function unwarpRho(rho: number, beta: number) {
4653
const betaRatio = Math.abs(beta) / betaMax;
4754
const shiftedRho = Math.atan(rho);
48-
return shiftedRho / (0.95 - 0.05 * betaRatio);
55+
return shiftedRho / rhoScaleFactor(betaRatio);
4956
}
5057

5158
export function warpPolar([rho, gamma]: Polar): Polar {
5259
const beta = normalizeGamma(gamma);
5360

54-
const beta2 = warpBeta(normalizeGamma(gamma));
61+
const beta2 = warpBeta(beta);
5562
const deltaBeta = beta2 - beta;
5663

5764
// Distance to edge will change, so shift rho to match

tests/warp.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ describe('warpBeta', () => {
7676
const TEST_VALUES = [
7777
{input: 0, expected: 0},
7878
{input: 0.1, expected: 0.09657},
79-
{input: -0.2, expected: -0.19366},
80-
{input: PI_OVER_10, expected: 0.30579},
79+
{input: -0.2, expected: -0.193740},
80+
{input: PI_OVER_10, expected: 0.305902},
8181
{input: PI_OVER_5, expected: PI_OVER_5},
8282
];
8383

0 commit comments

Comments
 (0)