maplibre-gl
Version:
BSD licensed community fork of mapbox-gl, a WebGL interactive maps library
151 lines (135 loc) • 5.02 kB
text/typescript
import {findOffsetIntersectionPoint, project, projectVertexToViewport, transformToOffsetNormal} from './projection';
import Point from '@mapbox/point-geometry';
import {mat4} from 'gl-matrix';
import {SymbolLineVertexArray} from '../data/array_types.g';
describe('Projection', () => {
test('matrix float precision', () => {
const point = new Point(10.000000005, 0);
const matrix = mat4.create();
expect(project(point, matrix).point.x).toBeCloseTo(point.x, 10);
});
});
describe('Vertex to viewport projection', () => {
// A three point line along the x axis
const lineVertexArray = new SymbolLineVertexArray();
lineVertexArray.emplaceBack(-10, 0, -10);
lineVertexArray.emplaceBack(0, 0, 0);
lineVertexArray.emplaceBack(10, 0, 10);
test('projecting with null matrix', () => {
const projectionArgs = {
projectionCache: {projections: {}, offsets: {}},
lineVertexArray,
labelPlaneMatrix: mat4.create(),
getElevation: (_x, _y) => 0,
// Only relevant in "behind the camera" case, can't happen with null projection matrix
tileAnchorPoint: new Point(0, 0),
distanceFromAnchor: 0,
previousVertex: new Point(0, 0),
direction: 1,
absOffsetX: 0
};
const first = projectVertexToViewport(0, projectionArgs);
const second = projectVertexToViewport(1, projectionArgs);
const third = projectVertexToViewport(2, projectionArgs);
expect(first.x).toBeCloseTo(-10);
expect(second.x).toBeCloseTo(0);
expect(third.x).toBeCloseTo(10);
});
});
describe('Find offset line intersections', () => {
const lineVertexArray = new SymbolLineVertexArray();
// A three point line along x axis, to origin, and then up y axis
lineVertexArray.emplaceBack(-10, 0, -10);
lineVertexArray.emplaceBack(0, 0, 0);
lineVertexArray.emplaceBack(0, 10, 10);
// A three point line along the x axis
lineVertexArray.emplaceBack(-10, 0, -10);
lineVertexArray.emplaceBack(0, 0, 0);
lineVertexArray.emplaceBack(10, 0, 10);
const projectionArgs = {
projectionCache: {projections: {}, offsets: {}},
lineVertexArray,
labelPlaneMatrix: mat4.create(),
getElevation: (_x, _y) => 0,
direction: 1,
// Only relevant in "behind the camera" case, can't happen with null projection matrix
tileAnchorPoint: new Point(0, 0),
distanceFromAnchor: 0,
previousVertex: new Point(0, 0),
absOffsetX: 0
};
test('concave', () => {
/*
| |
| |
________| |
__________| <- origin
*/
projectionArgs.projectionCache = {projections: {}, offsets: {}};
const lineOffsetY = 1;
const prevToCurrent = new Point(10, 0);
const normal = transformToOffsetNormal(prevToCurrent, lineOffsetY, projectionArgs.direction);
expect(normal.y).toBeCloseTo(1);
expect(normal.x).toBeCloseTo(0);
const intersectionPoint = findOffsetIntersectionPoint(
1,
normal,
new Point(0, 0),
0,
3,
new Point(-10, 1),
lineOffsetY,
projectionArgs
);
expect(intersectionPoint.y).toBeCloseTo(1);
expect(intersectionPoint.x).toBeCloseTo(-1);
});
test('convex', () => {
/*
| |
| |
origin \ | |
__________| |
____________|
*/
projectionArgs.projectionCache = {projections: {}, offsets: {}};
const lineOffsetY = -1;
const prevToCurrent = new Point(10, 0);
const normal = transformToOffsetNormal(prevToCurrent, lineOffsetY, projectionArgs.direction);
expect(normal.y).toBeCloseTo(-1);
expect(normal.x).toBeCloseTo(0);
const intersectionPoint = findOffsetIntersectionPoint(
1,
normal,
new Point(0, 0),
0,
3,
new Point(-10, -1),
lineOffsetY,
projectionArgs
);
expect(intersectionPoint.y).toBeCloseTo(-1);
expect(intersectionPoint.x).toBeCloseTo(1);
});
test('parallel', () => {
/*
______._____
______|_____
*/
projectionArgs.projectionCache = {projections: {}, offsets: {}};
const lineOffsetY = 1;
const prevToCurrent = new Point(10, 0);
const intersectionPoint = findOffsetIntersectionPoint(
1,
transformToOffsetNormal(prevToCurrent, lineOffsetY, projectionArgs.direction),
new Point(0, 0),
3,
5,
new Point(-10, 1),
lineOffsetY,
projectionArgs
);
expect(intersectionPoint.x).toBeCloseTo(0);
expect(intersectionPoint.y).toBeCloseTo(1);
});
});