UNPKG

@giro3d/giro3d

Version:

A JS/WebGL framework for 3D geospatial data visualization

98 lines (94 loc) 2.67 kB
/* * Copyright (c) 2015-2018, IGN France. * Copyright (c) 2018-2026, Giro3D team. * SPDX-License-Identifier: MIT */ /** * A rectangle. */ class Rect { constructor(xMin, xMax, yMin, yMax) { this.xMin = xMin; this.xMax = xMax; this.yMin = yMin; this.yMax = yMax; } get left() { return this.xMin; } get right() { return this.xMax; } get top() { return this.yMax; } get bottom() { return this.yMin; } get width() { return this.xMax - this.xMin; } get height() { return this.yMax - this.yMin; } get centerX() { return this.xMin + (this.xMax - this.xMin) * 0.5; } get centerY() { return this.yMin + (this.yMax - this.yMin) * 0.5; } static fromExtent(extent) { return new Rect(extent.minX, extent.maxX, extent.minY, extent.maxY); } /** * @param other - The other rect. * @param epsilon - The comparison epsilon. * @returns True if they are equal. */ equals(other, epsilon = 0.0001) { return Math.abs(other.xMin - this.xMin) <= epsilon && Math.abs(other.xMax - this.xMax) <= epsilon && Math.abs(other.yMin - this.yMin) <= epsilon && Math.abs(other.yMax - this.yMax) <= epsilon; } getIntersection(other) { const xMin = Math.max(this.xMin, other.xMin); const xMax = Math.min(this.xMax, other.xMax); const yMin = Math.max(this.yMin, other.yMin); const yMax = Math.min(this.yMax, other.yMax); return new Rect(xMin, xMax, yMin, yMax); } /** * Returns the equivalent rectangle of `source` normalized over the dimensions of `dest`. * * @param source - The source rect. * @param dest - The destination rect. */ static getNormalizedRect(source, dest) { const dstDim = { x: dest.width, y: dest.height }; const srcDim = { x: source.width, y: source.height }; let x = (source.left - dest.left) / dstDim.x; // We reverse north and south because canvas coordinates are top left corner based, // whereas extents are bottom left based. let y = (dest.top - source.top) / dstDim.y; let w = srcDim.x / dstDim.x; let h = srcDim.y / dstDim.y; // Necessary to avoid seams between tiles due to problems in // floating point precision when tile size is a multiple of the canvas size. const precision = 10 ** 10; x = Math.round((x + Number.EPSILON) * precision) / precision; y = Math.round((y + Number.EPSILON) * precision) / precision; w = Math.round((w + Number.EPSILON) * precision) / precision; h = Math.round((h + Number.EPSILON) * precision) / precision; return { x, y, w, h }; } } export default Rect;