ofrohn / d3-celestial

A star map with d3.js
BSD 3-Clause "New" or "Revised" License
635 stars 181 forks source link

Feature request: show star brightness without size change #65

Closed ehdorrii closed 4 years ago

ehdorrii commented 4 years ago

For my application, I am wanting to simulate a view of the sky, rather than generating a "star map" kind of view. Would it be possible to -- when cConfig.stars.exponent is equal to zero -- paint the stars with a "color" that is determined by the magnitude? In the simple case, where cConfig.stars.colors=false, then paint a star which has a magnitude of 0 (or brighter) with rgb(255,255,255), and as a star's magnitude decreases, use smaller values down to rgb(0,0,0) at the limiting magnitude. Roughly speaking, rgb(x,x,x) where x=255-magnitude*(256/limit).

Calculating color when stars.color=true is more complicated than what you're doing now. I'm thinking that converting from RGB to HSV, decreasing saturation (S) to around 25%, and then using magnitude to scale along brightness (V), and then converting back to RGB might produce good results. On the other hand, that will certainly slow things down, so maybe just ignoring star color might be preferable.

If this doesn't fit into your concept of d3-celestial's intent, I'm ok with that and will find another solution; but I thought it would be worth asking.

ofrohn commented 4 years ago

The easiest way to do it is to set stars.show to false in the config and add your own display routine. To find out if that works I just did a demo of it myself, you can find the result here https://github.com/ofrohn/d3-celestial/blob/master/demo/altstars.html or see it in action here https://ofrohn.github.io/celestial-demo/altstars.html

The good news is that d3.js already has a convenient way to do a continuous color scale that I used in the above demo. With

starColor = d3.scale.linear()
     .domain([-1.5, 0, limitMagnitude])
     .range(['white', 'white', 'black'])

you'll get the behavior you described above, where domain sets the magnitude scale with a stop at 0 so everything brighter stays white, and then greys down to the limit magnitude which is black. In the demo I used limit + 1 so that the faintest stars are still a little brighter than the background. You then use it with color = starColor(magnitude)

The color version is only a little more complicated, get the color with the bvcolor function and use that instead of 'white', so for every star:


var colorindex= Celestial.starColor(d);  //The D3-Celestial function, which has the same name as the scale. Oops
starColor.range([colorindex, colorindex, 'black'])
color = starColor(d.properties.mag)
ofrohn commented 4 years ago

Oh, and you'll need the latest version for the color to work

ehdorrii commented 4 years ago

Oh my!! That gives an absolutely stellar result (pun intended)! Radius=2 was too big, but radius=0.8 gives a very realistic display. Thank you very much indeed!!