SHIFT + SCROLL : camera pan
CTRL + SCROLL : camera zoom
ALT + SCROLL : camera rotate
S + SCROLL : scale point size
A + SCROLL : spherical coord rotation
1,2,3 : view face,right,top

forceAnimation(true); let φ = measure => {}; console.log(data.length) data = data.filter(x => !Number.isNaN(x[index_radial_velocity])) data = data.filter(x => x[index_radial_velocity]!=0) data = data.filter(x => x[index_radial_velocity]!=undefined) console.log(data.length) let splot; { let uniforms = {}; let positions = []; let velocities = []; let angles = []; let angleVelocities = []; data.map( (measure,index) => { //////////////////////////////////////////////////////////////////////////// // ρφθ position let α = measure[index_ra] /180*π; // [radian] let δ = measure[index_dec]/180*π; // [radian] let ρ = 1000/measure[index_parallax]; // [pc] let μαstar = measure[index_pmra]; // [mas.yr⁻¹] let μα = μαstar/cos(δ); // [mas.yr⁻¹] let μδ = measure[index_pmdec]; // [mas.yr⁻¹] let μρ = measure[index_radial_velocity] || 0; // [km.s⁻¹] default amplitude to 0 if absent from DB μρ = μρ * 3.24078e-14; // [pc.s⁻¹] μρ = μρ / 3.17098e-8 ; // [pc.yr⁻¹] // let k = 4.74 * 1000; // VT [km s-1] = 4.74 1000 mu [ pc mas yr⁻¹] // μρ /= k; // [ pc mas yr⁻¹] //////////////////////////////////////////////////////////////////////////// // xyz position let x = ρ*cos(δ)*cos(α); // [pc] let y = ρ*cos(δ)*sin(α); // [pc] let z = ρ*sin(δ); // [pc] let mas_2_rad = 2*π/ (360 * 3600 * 1000) ; let Giga = 10**9; let vx = (μρ*cos(δ)*cos(α) + (- ρ*μδ*sin(δ)*cos(α) - ρ*μα*cos(δ)*sin(α)) * mas_2_rad ) * Giga; // [pc Gyr⁻¹] let vy = (μρ*cos(δ)*cos(α) + (- ρ*μδ*sin(δ)*sin(α) + ρ*μα*cos(δ)*cos(α)) * mas_2_rad ) * Giga; // [pc Gyr⁻¹] let vz = (μρ*sin(δ) + (+ ρ*μδ*cos(δ) ) * mas_2_rad ) * Giga; // [pc Gyr⁻¹] //////////////////////////////////////////////////////////////////////////// positions.push( x,y,z ); velocities.push( vx, vy, vz ); // positions.push( y,z,x ); // velocities.push( vy, vz, vx ); // angles.push( b,l+π,ρ ); // angleVelocities.push( μb,μl,μρ); angles.push( δ,α,ρ ); angleVelocities.push( μδ,μα,μρ); // sizes.push( obs.size ); }); let positionsBuffer = new THREE.Float32BufferAttribute( positions, 3 ); let anglesBuffer = new THREE.Float32BufferAttribute( angles, 3 ); let velocitiesBuffer = new THREE.Float32BufferAttribute( velocities, 3 ); let angleVelocitiesBuffer = new THREE.Float32BufferAttribute( angleVelocities, 3 ); let geometry = new THREE.BufferGeometry(); geometry.addAttribute( 'position', positionsBuffer ); geometry.addAttribute( 'velocity' , velocitiesBuffer ); geometry.addAttribute( 'angle', anglesBuffer ); geometry.addAttribute( 'angleVelocity', angleVelocitiesBuffer ); let vertexShader = CGPUglsl + ` uniform mat4 slider_a_rot; uniform vec2 slider_s_log; uniform vec2 slider_b; uniform vec2 slider_q; uniform vec2 slider_q_log; uniform vec2 slider_w; uniform vec2 slider_u; uniform vec2 slider_u_log; uniform vec2 slider_w_log; uniform vec2 slider_e; uniform vec2 slider_r; attribute vec3 velocity; attribute vec3 angle; attribute vec3 angleVelocity; varying vec4 vIndexColor; varying vec4 vColor; const mat3 j2k2gal = mat3( -0.0548755604024359, -0.873437090247923, -0.4838350155267381, 0.4941094279435681, -0.4448296299195045, 0.7469822444763707, -0.8676661489811610, -0.1980763734646737, 0.4559837762325372 ); void main() { float hammer3dCtrl = clamp(slider_q.y,0.,1.); float velocityCtrl = slider_q_log.x; float sunMoRemCtrl = clamp(slider_w.x,0.,1.); vec3 pos = inverse(j2k2gal)*position; vec3 dir = pos/length(pos); // vec3 sun_v = vec3(11.1,12.24,7.25)*(3.24078e-14/3.17098e-8*10e9); // [pc Gyr⁻¹] vec3 sun_v = vec3(10.*slider_e,10.*slider_r.x)*(3.24078e-14/3.17098e-8*10e9); // [pc Gyr⁻¹] vec3 parasite_v = sun_v - dot(sun_v,dir)*dir; // vec3 v = velocity; // vec3 v = j2k2gal*parasite_v; // vec3 v = velocity + sunMoRemCtrl*j2k2gal*parasite_v; vec3 v = velocity + j2k2gal*parasite_v; vec3 vel = inverse(j2k2gal)*v; float oscillator = velocityCtrl*0.0025*cos(5.*time); pos = pos/30000.; vel = vel/30000.; vec2 anglePerturbation = angle.yx + oscillator * angleVelocity.yx; vec2 hammerVelocity = spheric2hammer(spheric_rotation( anglePerturbation, slider_a_rot)); vec4 mvHammerPos = modelViewMatrix * vec4( hammerVelocity,20.*(length(pos) + oscillator*length(vel)),1.); vec4 mvPos = modelViewMatrix * ( vec4(pos + oscillator * vel , 1.) ); gl_Position = projectionMatrix * ( (1.-hammer3dCtrl) * mvPos + hammer3dCtrl * mvHammerPos ); // do nothing float size = 1.; size = length(vel.xy)/10000.; size = clamp(size,1.,20.); gl_PointSize = size * slider_s_log.y; float alpha = 1.; if ( abs(pos.z+slider_u.x/10.) > slider_u_log.y/10. ) { // gl_PointSize = gl_PointSize/200.; // gl_PointSize = 0.; alpha = 0.; } // orth scale gl_PointSize = gl_PointSize*pow(1.0 - gl_Position.z/gl_Position.w ,2.); float colorshift = 0.; vec3 s = vec3(.5+length(vel)/30. + colorshift,1.,1.0); // vec3 s = vec3(-0.1 + slider_e.x+length(pos)/2. + colorshift,1.,1.0); // vec3 s = vec3(.5+length(angleVelocity.y)/2.,1.,1.0); // vec3 s = vec3(length(angleVelocity.y)/10.,1.,1.0); // vec3 s = vec3(atan(angleVelocity.x,angleVelocity.y/cos(angle.x)),1.,1.0); vColor = vec4( hsv2rgb(s) ,alpha); }`; let fragmentShader = CGPUglsl + ` varying vec4 vColor; void main() { // gl_FragColor = vec4( 1.,1.,1.,1. ); // gl_FragColor = vec4( vVelocity,1. ); if (vColor.w == 0.) { discard; } gl_FragColor = vColor; }`; let material = new THREE.ShaderMaterial( { uniforms: uniforms, vertexShader: vertexShader, fragmentShader: fragmentShader, blending: THREE.NoBlending, // transparent: true }); let points = new THREE.Points( geometry, material ) splot = new StellarPlot(data, undefined, φ, points); } output(splot);