//gps, heading //get permissions if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) { function requestOrientationPermission() { DeviceOrientationEvent .requestPermission() .then(response => { if (response == 'granted') { window.addEventListener("deviceorientation", (event) => { if (event.webkitCompassHeading) { heading = (event.webkitCompassHeading + 180) % 360 - 180; // EAST == +90, WEST == -90 } }, true); } }) .catch(console.error) } } else { window.addEventListener("deviceorientationabsolute", (event) => { heading = ((360 - event.alpha) + 180) % 360 - 180; // EAST == +90, WEST == -90 }, true); } const watchID = navigator.geolocation.watchPosition( (position) => { latitude = position.coords.latitude; longitude = position.coords.longitude; }, (error) => {}, { enableHighAccuracy: true, maximumAge: 30000, timeout: 27000, } ); //distance between 2 locations (lat/lon) function getDistance(lat1, lon1, lat2, lon2) { var R = 6371; // Radius of the earth in km var dLat = deg2rad(lat2 - lat1); // deg2rad below var dLon = deg2rad(lon2 - lon1); var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); var d = R * c; // Distance in km return d; } function deg2rad(deg) { return deg * (Math.PI / 180) } //bearing between 2 locations (lat/lon) // Converts from degrees to radians. function toRadians(degrees) { return degrees * Math.PI / 180; }; // Converts from radians to degrees. function toDegrees(radians) { return radians * 180 / Math.PI; } // const y = Math.sin(λ2-λ1) * Math.cos(φ2); // const x = Math.cos(φ1)*Math.sin(φ2) - // Math.sin(φ1)*Math.cos(φ2)*Math.cos(λ2-λ1); // const θ = Math.atan2(y, x); // const brng = (θ*180/Math.PI + 360) % 360; in degrees function getBearing(startLat, startLng, destLat, destLng) { startLat = toRadians(startLat); startLng = toRadians(startLng); destLat = toRadians(destLat); destLng = toRadians(destLng); y = Math.sin(destLng - startLng) * Math.cos(destLat); x = Math.cos(startLat) * Math.sin(destLat) - Math.sin(startLat) * Math.cos(destLat) * Math.cos(destLng - startLng); brng = Math.atan2(y, x); brng = toDegrees(brng); return (brng + 360) % 360; } //promisify -> new Tone.Player function AudioImport(url) { return new Promise((resolve, reject) => { var audio = new Tone.Player(url, () => resolve(audio)); }); } //promisified 'setTimeout' from https://stackoverflow.com/a/74004853 const asyncTimeout = ms => new Promise(resolve => setTimeout(resolve, ms)); // some p5 tools class Textline { static #lines = 0; static #linestep = 20; static restart() { Textline.#lines = 0; } static put(t) { Textline.#lines = Textline.#lines + 1; text(t, 0, Textline.#linestep * Textline.#lines); } }