☀️ Adds sun elevation calculator
This commit is contained in:
@@ -25,6 +25,7 @@ import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
|
|||||||
import { TransformControls } from 'three/examples/jsm/controls/TransformControls';
|
import { TransformControls } from 'three/examples/jsm/controls/TransformControls';
|
||||||
import { type URDFJoint, type URDFMimicJoint, type URDFRobot } from 'urdf-loader';
|
import { type URDFJoint, type URDFMimicJoint, type URDFRobot } from 'urdf-loader';
|
||||||
import { PointerURDFDragControls } from 'urdf-loader/src/URDFDragControls';
|
import { PointerURDFDragControls } from 'urdf-loader/src/URDFDragControls';
|
||||||
|
import { sunCalculator } from './utilities/position-utilities';
|
||||||
|
|
||||||
export const addScene = () => new Scene();
|
export const addScene = () => new Scene();
|
||||||
|
|
||||||
@@ -55,13 +56,6 @@ type directionalLight = position & light;
|
|||||||
|
|
||||||
type gridHelperOptions = gridOptions & position;
|
type gridHelperOptions = gridOptions & position;
|
||||||
|
|
||||||
function calculateCurrentSunElevation() {
|
|
||||||
let now = new Date();
|
|
||||||
let decimalTime = now.getHours() + now.getMinutes() / 60;
|
|
||||||
let normalizedTime = (decimalTime % 12) / 6 - 1;
|
|
||||||
return 10 * Math.sin(normalizedTime * Math.PI);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class SceneBuilder {
|
export default class SceneBuilder {
|
||||||
public scene: Scene;
|
public scene: Scene;
|
||||||
public camera!: PerspectiveCamera;
|
public camera!: PerspectiveCamera;
|
||||||
@@ -107,7 +101,7 @@ export default class SceneBuilder {
|
|||||||
rayleigh: 3,
|
rayleigh: 3,
|
||||||
mieCoefficient: 0.005,
|
mieCoefficient: 0.005,
|
||||||
mieDirectionalG: 0.7,
|
mieDirectionalG: 0.7,
|
||||||
elevation: calculateCurrentSunElevation(),
|
elevation: sunCalculator.calculateSunElevation(),
|
||||||
azimuth: 180,
|
azimuth: 180,
|
||||||
exposure: this.renderer.toneMappingExposure
|
exposure: this.renderer.toneMappingExposure
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
class SunCalculator {
|
||||||
|
calculateSunElevation(lat: number = 55, lon: number = 12) {
|
||||||
|
const now = new Date();
|
||||||
|
const JD = this.getJulianDate(now);
|
||||||
|
const solarDec = this.getSolarDeclination(JD);
|
||||||
|
const solarTime = this.getSolarTime(now, lon);
|
||||||
|
|
||||||
|
const hourAngle = (solarTime - 12) * 15;
|
||||||
|
const elevation = Math.asin(
|
||||||
|
Math.sin(this.degToRad(lat)) * Math.sin(solarDec) +
|
||||||
|
Math.cos(this.degToRad(lat)) * Math.cos(solarDec) * Math.cos(this.degToRad(hourAngle))
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.radToDeg(elevation);
|
||||||
|
}
|
||||||
|
|
||||||
|
getJulianDate(date: Date) {
|
||||||
|
const Y = date.getUTCFullYear();
|
||||||
|
const M = date.getUTCMonth() + 1;
|
||||||
|
const D =
|
||||||
|
date.getUTCDate() +
|
||||||
|
date.getUTCHours() / 24 +
|
||||||
|
date.getUTCMinutes() / 1440 +
|
||||||
|
date.getUTCSeconds() / 86400;
|
||||||
|
const A = Math.floor((14 - M) / 12);
|
||||||
|
const Y1 = Y + 4800 - A;
|
||||||
|
const M1 = M + 12 * A - 3;
|
||||||
|
return (
|
||||||
|
D +
|
||||||
|
Math.floor((153 * M1 + 2) / 5) +
|
||||||
|
365 * Y1 +
|
||||||
|
Math.floor(Y1 / 4) -
|
||||||
|
Math.floor(Y1 / 100) +
|
||||||
|
Math.floor(Y1 / 400) -
|
||||||
|
32045
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSolarDeclination(JulianDate: number) {
|
||||||
|
const n = JulianDate - 2451545;
|
||||||
|
const L = (280.46 + 0.9856474 * n) % 360;
|
||||||
|
const g = this.degToRad((357.528 + 0.9856003 * n) % 360);
|
||||||
|
const lambda = this.degToRad(L + 1.915 * Math.sin(g) + 0.02 * Math.sin(2 * g));
|
||||||
|
return Math.asin(Math.sin(lambda) * Math.sin(this.degToRad(23.44)));
|
||||||
|
}
|
||||||
|
|
||||||
|
getSolarTime(date: Date, lon: number) {
|
||||||
|
const EoT = this.getEquationOfTime(date);
|
||||||
|
const offset = date.getTimezoneOffset() / 60;
|
||||||
|
const standardMeridian = Math.round(lon / 15) * 15;
|
||||||
|
const solarTime =
|
||||||
|
date.getUTCHours() +
|
||||||
|
(date.getUTCMinutes() + (4 * (standardMeridian - lon) + EoT)) / 60 -
|
||||||
|
offset;
|
||||||
|
return (solarTime + 24) % 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEquationOfTime(date: Date) {
|
||||||
|
const JD = this.getJulianDate(date);
|
||||||
|
const n = JD - 2451545;
|
||||||
|
const g = this.degToRad((357.528 + 0.9856003 * n) % 360);
|
||||||
|
const q = this.degToRad((280.46 + 0.9856474 * n) % 360);
|
||||||
|
return (
|
||||||
|
4 *
|
||||||
|
this.radToDeg(
|
||||||
|
0.000075 +
|
||||||
|
0.001868 * Math.cos(q) -
|
||||||
|
0.032077 * Math.sin(g) -
|
||||||
|
0.014615 * Math.cos(2 * q) -
|
||||||
|
0.040849 * Math.sin(2 * g)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
degToRad(deg: number) {
|
||||||
|
return deg * (Math.PI / 180);
|
||||||
|
}
|
||||||
|
|
||||||
|
radToDeg(rad: number) {
|
||||||
|
return rad * (180 / Math.PI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sunCalculator = new SunCalculator();
|
||||||
Reference in New Issue
Block a user