UNPKG

photo-sphere-viewer

Version:

A JavaScript library to display Photo Sphere panoramas

90 lines (76 loc) 2.69 kB
import { CONSTANTS, utils } from '../..'; /** * Returns intermediary point between two points on the sphere * {@link http://www.movable-type.co.uk/scripts/latlong.html} * @param {number[]} p1 * @param {number[]} p2 * @param {number} f * @returns {number[]} * @private */ export function greatArcIntermediaryPoint(p1, p2, f) { const1, φ1] = p1; const2, φ2] = p2; const r = utils.greatArcDistance(p1, p2); const a = Math.sin((1 - f) * r) / Math.sin(r); const b = Math.sin(f * r) / Math.sin(r); const x = a * Math.cos1) * Math.cos1) + b * Math.cos2) * Math.cos2); const y = a * Math.cos1) * Math.sin1) + b * Math.cos2) * Math.sin2); const z = a * Math.sin1) + b * Math.sin2); return [ Math.atan2(y, x), Math.atan2(z, Math.sqrt(x * x + y * y)), ]; } /** * @summary Computes the center point of a polygon * @todo Get "visual center" (https://blog.mapbox.com/a-new-algorithm-for-finding-a-visual-center-of-a-polygon-7c77e6492fbc) * @param {number[][]} polygon * @returns {number[]} * @private */ export function getPolygonCenter(polygon) { // apply offsets to avoid crossing the origin const workPoints = [polygon[0]]; let k = 0; for (let i = 1; i < polygon.length; i++) { const d = polygon[i - 1][0] - polygon[i][0]; if (d > Math.PI) { // crossed the origin left to right k += 1; } else if (d < -Math.PI) { // crossed the origin right to left k -= 1; } workPoints.push([polygon[i][0] + k * 2 * Math.PI, polygon[i][1]]); } const sum = workPoints.reduce((intermediary, point) => [intermediary[0] + point[0], intermediary[1] + point[1]]); return [utils.parseAngle(sum[0] / polygon.length), sum[1] / polygon.length]; } /** * @summary Computes the middle point of a polyline * @param {number[][]} polyline * @returns {number[]} * @private */ export function getPolylineCenter(polyline) { // compute each segment length + total length let length = 0; const lengths = []; for (let i = 0; i < polyline.length - 1; i++) { const l = utils.greatArcDistance(polyline[i], polyline[i + 1]) * CONSTANTS.SPHERE_RADIUS; lengths.push(l); length += l; } // iterate until length / 2 let consumed = 0; for (let j = 0; j < polyline.length - 1; j++) { // once the segment containing the middle point is found, computes the intermediary point if (consumed + lengths[j] > length / 2) { const r = (length / 2 - consumed) / lengths[j]; return greatArcIntermediaryPoint(polyline[j], polyline[j + 1], r); } consumed += lengths[j]; } // this never happens return polyline[Math.round(polyline.length / 2)]; }