问题
I'd like to visualize astronomical star catalogues that can contain hundreds of thousands of entries. The catalogues usually consist of simply a list of stars, with spherical coordinates and other data for each star. By spherical coordinates I mean right ascension (0-360 degrees or 0-24 hours) and declination (-90 degrees to +90 degrees). This corresponds to longitude and latitude, just on the celestial sphere instead of Earth's surface.
I'd like to plot all the stars in the catalogue that are located inside a certain field of view, defined by the center (in spherical coordinates) and the size of the field of view (in degrees) and the projection (e.g. stereographic projection).
Plotting the stars by going through the whole catalogue and just checking whether each star is inside the field of view or not is very inefficient.
How could I make this more efficient? Is there a good algorithm or data structure for this kind of a problem?
回答1:
For modern gfx cards numbers like 300K (and more) stars are still manageable...
So you can try to load them all to gfx as VBO/VAO and leave the render/clipping to gfx alone. I use Hipparcos (118322 stars) in this way without problems while each star is a transparent Quad. You just need to pre-compute the quads to view position prior to rendering (just once). Here screenshot from one of my apps where Hipparcos is used in this manner as background stars (in RT)
You can also use geometry shaders to ease up things a lot (can send just points or even
Ra,Dec,Distance
instead of Quads) but this will limit your Target gfx HW to only those supporting geometry shaders.If you got more stars then your HW can handle then use sorted dataset
Most catalogs are sorted by
Ra or Dec
. You can use this by:- select view area
min(Ra,Dec),max(Ra,Dec)
- let assume your data is sorted by
Ra
ascending - find first
i0
where star[i0].Ra>=min.Ra- use binary search !!!
- find first
i1
where star[i1].Ra>=max.Ra- use binary search !!!
- process stars
i0<=i<i1
test if
min.Dec <= star[i].Dec <= max.Dec
and if yes then render it.- select view area
If even this is not fast enough you need to use spatial subdivision
So divide your dataset to smaller ones. And prior to rendering according to selected view area use only datasets near that area. This will lower the amound of data processed significantly.
来源:https://stackoverflow.com/questions/33184329/plotting-a-star-chart-efficiently