Skip to content

Instantly share code, notes, and snippets.

@colek42
Created August 18, 2016 00:45
Show Gist options
  • Save colek42/651127a7925b36f176192749338979c6 to your computer and use it in GitHub Desktop.
Save colek42/651127a7925b36f176192749338979c6 to your computer and use it in GitHub Desktop.
penumbra line, sunlight
https://github.com/AnalyticalGraphicsInc/cesium/issues/4123
var viewer = new Cesium.Viewer('cesiumContainer');
var penumbraSunlightPolyline = viewer.entities.add({
name: 'sunlight/penumbra polygon',
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([
0, 0,
1, 0
]),
width: 2,
material: Cesium.Color.YELLOW,
show: true,
loop: true
}
});
var penumbraUmbraPolyline = viewer.entities.add({
name: 'sunlight/penumbra polygon',
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([
0, 0,
1, 0
]),
width: 2,
material: Cesium.Color.BLUE,
show: true,
loop: true
}
});
var penumbraVertexCount = 6;
var penumbraVertexRotation = 2*Cesium.Math.PI / penumbraVertexCount;
var simUpdateStep = 1; //update time step in seconds; will be scaled by clock multiplier
var sunRadius = 696.3; //mean radius in 10^6 meters
var earthRadius = 6.372797560856; //mean radius in 10^6 meters
var lastUpdateTime = new Cesium.JulianDate(0,0);
function updatePenumbraLines(clock) {
//updating too often brings cesium to a halt
if(Cesium.JulianDate.equalsEpsilon(lastUpdateTime, clock.currentTime, Math.abs(clock.multiplier)*simUpdateStep)) {return;}
//sun position
var spwc = viewer.scene.context.uniformState.sunPositionWC;
var D = Cesium.Cartesian3.magnitude(spwc)/1000000.0; //distance from earth to sun in 10^6 meters
if(D) {//prevent NaN errors
lastUpdateTime = clock.currentTime;
var sv = Cesium.Cartesian3.normalize(spwc, new Cesium.Cartesian3());
//vertex rotation
var q = Cesium.Quaternion.fromAxisAngle(sv, penumbraVertexRotation);
var R = Cesium.Matrix3.fromQuaternion(q);
//sunlight line
var angle = Math.acos((sunRadius+earthRadius)/D); //sunlight cone inner half-angle
var v = new Cesium.Cartesian3(0,0,1);
Cesium.Cartesian3.cross(sv, v, v); //get vector orthogonal to sv
var qs = Cesium.Quaternion.fromAxisAngle(v, angle);
var Rs = Cesium.Matrix3.fromQuaternion(qs);
Cesium.Matrix3.multiplyByVector(Rs, sv, v);
var pos = [];
var w;
for (var i=0; i<=penumbraVertexCount; ++i){
Cesium.Matrix3.multiplyByVector(R, v, v);
w = Cesium.Cartesian3.clone(v);
viewer.scene.globe.ellipsoid.scaleToGeocentricSurface(w, w);
pos.push(w);
}
penumbraSunlightPolyline.polyline.positions = pos;
//umbra line
Cesium.Cartesian3.negate(sv, sv); //umbra cone points away from sun
angle = Math.acos((sunRadius-earthRadius)/D); //umbra cone inner half-angle
v = new Cesium.Cartesian3(0,0,1);
Cesium.Cartesian3.cross(sv, v, v); //get vector orthogonal to sv
var qu = Cesium.Quaternion.fromAxisAngle(v, angle);
var Ru = Cesium.Matrix3.fromQuaternion(qu);
Cesium.Matrix3.multiplyByVector(Ru, sv, v);
pos = [];
for (i=0; i<=penumbraVertexCount; ++i){
Cesium.Matrix3.multiplyByVector(R, v, v);
w = Cesium.Cartesian3.clone(v);
viewer.scene.globe.ellipsoid.scaleToGeocentricSurface(w, w);
pos.push(w);
}
penumbraUmbraPolyline.polyline.positions = pos;;
}
}
//add the event handler
viewer.clock.onTick.addEventListener(updatePenumbraLines);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment