@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
148 lines (134 loc) • 4.82 kB
text/typescript
import {LngLatLike, Vector2Like} from '../../types/GlobalTypes';
import {Vector3, Triangle} from 'three';
import {
degToRad as _degToRad,
radToDeg as _radToDeg,
smoothstep as _smoothstep,
smootherstep as _smootherstep,
} from 'three/src/math/MathUtils';
import {Easing} from './Easing';
import {isNumber} from '../Type';
const RAND_A = 12.9898;
const RAND_B = 78.233;
const RAND_C = 43758.5453;
export const degToRad = _degToRad;
export const radToDeg = _radToDeg;
export function clamp(val: number, min: number, max: number): number {
if (val < min) {
return min;
} else if (val > max) {
return max;
} else {
return val;
}
}
export const smoothstep = _smoothstep;
export const smootherstep = _smootherstep;
export function fit(val: number, srcMin: number, srcMax: number, destMin: number, destMax: number): number {
const src_range = srcMax - srcMin;
const dest_range = destMax - destMin;
const r = (val - srcMin) / src_range;
return r * dest_range + destMin;
}
export function fit01(val: number, destMin: number, destMax: number): number {
// const size = max - min;
// return (val - min) / size;
return fit(val, 0, 1, destMin, destMax);
}
export function fitClamp(val: number, srcMin: number, srcMax: number, destMin: number, destMax: number): number {
const r = fit(val, srcMin, srcMax, destMin, destMax);
return clamp(r, destMin, destMax);
}
export function mix(num0: number, num1: number, blend: number) {
return (1 - blend) * num0 + blend * num1;
}
export const fract = (number: number) => number - Math.floor(number);
const DEFAULT_Y = 136574;
const _vec = {x: 0, y: DEFAULT_Y};
export function randFloat(x: number, y: number = DEFAULT_Y): number {
_vec.x = x;
_vec.y = y;
return randVec2(_vec);
}
export function randVec2(uv: Vector2Like) {
const dt = uv.x * RAND_A + uv.y * RAND_B; //dot( uv.xy, vec2( a,b ) )
const sn = dt % Math.PI;
return fract(Math.sin(sn) * RAND_C);
}
export function rand(number: number | Vector2Like): number {
if (isNumber(number)) {
return randFloat(number);
} else {
return randVec2(number);
}
}
export function round(number: number, stepSize: number): number {
const stepsCount = number / stepSize;
const roundedStepsCount = number < 0 ? Math.ceil(stepsCount) : Math.floor(stepsCount);
return roundedStepsCount * stepSize;
}
export function mod(number: number, _mod: number) {
return ((number % _mod) + _mod) % _mod;
}
export function highestEven(number: number): number {
return 2 * Math.ceil(number * 0.5);
}
export function nearestPower2(num: number) {
return Math.pow(2, Math.ceil(Math.log(num) / Math.log(2)));
}
export function pow2Inverse(num: number) {
return Math.log(num) / Math.log(2);
}
// https://www.movable-type.co.uk/scripts/latlong.html
export function geodesicDistance(lnglat1: LngLatLike, lnglat2: LngLatLike): number {
var R = 6371e3; // metres
var d1 = degToRad(lnglat1.lat);
var d2 = degToRad(lnglat2.lat);
var ad1 = degToRad(lnglat2.lat - lnglat1.lat);
var ad2 = degToRad(lnglat2.lng - lnglat1.lng);
var a = Math.sin(ad1 / 2) * Math.sin(ad1 / 2) + Math.cos(d1) * Math.cos(d2) * Math.sin(ad2 / 2) * Math.sin(ad2 / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
}
const _triangleMid = new Vector3();
const _triangleMidToCorner = new Vector3();
export function expandTriangle(triangle: Triangle, margin: number) {
triangle.getMidpoint(_triangleMid);
// a
_triangleMidToCorner.copy(triangle.a).sub(_triangleMid);
_triangleMidToCorner.normalize().multiplyScalar(margin);
triangle.a.add(_triangleMidToCorner);
// b
_triangleMidToCorner.copy(triangle.b).sub(_triangleMid);
_triangleMidToCorner.normalize().multiplyScalar(margin);
triangle.b.add(_triangleMidToCorner);
// c
_triangleMidToCorner.copy(triangle.c).sub(_triangleMid);
_triangleMidToCorner.normalize().multiplyScalar(margin);
triangle.c.add(_triangleMidToCorner);
}
export function lerpFloat(current: number, target: number, blend: number) {
return current * (1 - blend) + target * blend;
}
export class CoreMath {
static Easing = Easing; // used in expressions
static degToRad = degToRad; // used in expressions
static radToDeg = radToDeg; // used in expressions
static clamp = clamp; // used in expressions
static smoothstep = smoothstep;
static smootherstep = smootherstep;
static fit01 = fit01; // used in expressions
static fit = fit; // used in expressions
static fitClamp = fitClamp; // used in expressions
static mix = mix; // used in expressions
static fract = fract; // used in expressions
static rand = rand; // from threejs glsl rand
static round = round;
static highestEven = highestEven;
static nearestPower2 = nearestPower2;
static pow2Inverse = pow2Inverse;
static randFloat = randFloat;
static randVec2 = randVec2;
static lerpFloat = lerpFloat;
}