Page 1 of 1
Filling galaxies with stars idea
Posted: 04.12.2003, 02:44
by chrisr
To whom it may concern,
i have a very interesting suggestion for celestia lack of stars problem if your interested
As i understand there are a few stars.dat files of varying sizes (i believe the biggest is 2 million). It is not concivealbe that we'll ever be able to catalog the 400 billion stars in our galaxy let along the stars of other galaxies any time soon.
If your not intersted some one else may wish to delvep this addon:
The idea is to create a secondary stars.dat file that works in conjuction with the original. The differece it fill galaxies up with random stars based on parameters that will allow the stars to form the shapes of the galaxies and not be placed between galxies (obviously)
So waht to you guys think
great idea
Posted: 04.12.2003, 19:14
by Guest
chrisr i think this is a great idea, i do it my self if i had any programming skills. Chris, selden, rassilon, what do you guys think????
Posted: 04.12.2003, 23:52
by marc
I have experimented previously with positioning stars randomly in celestia. These are the results:
also see
http://mostlyharmless.sourceforge.net/s ... pdate1.jpg
http://mostlyharmless.sourceforge.net/s ... pdate2.jpg
Obvoiusly there are problems with random not being random. (I'm yet to try another random library)
Using cartesian co-ordinates might give better results, but im guessing that
a pattern will emerge as well.
There are a few other issues:
Celestia can only handle stars up to a finite distance from sol. (ie only our galaxy)
There are memory and performance issues for such a large number of stars. (with celestias current design)
Lastly this would be a fictional feature, which is not what Celestia is about.
Posted: 05.12.2003, 02:48
by selden
Marc,
Clearly either your random number generator or the way you're using it has serious problems
(From what little I know about such things, I'd guess that you picked a very poor seed, probably one with a relatively small value. It should be ~ 2^30 < n < 2^32.)
I admit that I'd like to be able to place stars in galaxies, too. Deriving their spectral types and locations from photographs is one possibility. Of course, that's still not an ideal situation, but seems to be a reasonable place to start.
Chris has mumbled in the past about the possibility of specifying origins other than the sun for star coordinate systems. That should help with the precision and problems related to it. Other than optimizing the related calculations, I don't think the increase of the size of the stellar database should be thought of as a serious problem. Moore's law is still working to our advantage.
marcs random stars
Posted: 05.12.2003, 04:29
by chrisr
This question is directed towards marc. What sort of parameters are you using for yours stars to be randmoly generated. Is it possible to define a specific shape (bondaries of a galaxy) for a particular set of stars to generate in? Would this solve the problem your having?
Posted: 05.12.2003, 06:24
by marc
selden wrote:Clearly either your random number generator or the way you're using it has serious problems
I think your'e both counts Selden. The pattern was pretty nice however.
I used the random number generator provided with MySQL, quoting the MySQL documation: "is not meant to be a perfect random generator".
My method is flawed such that stars will be more concentrated near sol.
Here is the query that i used with my MySQL addon.
UPDATE star SET ra=24*RAND(), dec=180*RAND()-90, distFromSol=RAND()*5000;
RAND() gives a floating point number 0.0 to 1.0
To get it right a custom MySQL function would be needed that makes use of a proper scientific random library. eg
http://www.gnu.org/software/gsl/
The galaxy shape could be defined by some distribution of stars equations, ie galactic zone x has n number of stars.
Perhaps the current galaxy models in celestia could be used for this?
I will try a higher seed later on, but like the star distribution experiment it might take a little while. I've been getting carried away getting my random system generator working agian.
If anyone wants to try it for themselves just do a "SELECT RAND(2147483600);" query before doing the update above.
rand stars
Posted: 05.12.2003, 20:44
by Guest
chrisr-not logged in
Hey marc, im interested in how you made stars appear in celestia randomly. How do you do it. do you use a program to make a stars.dat that defines the parameters of the rand star generation. If so how complicated is it, this program. thyanks
Posted: 05.12.2003, 21:45
by Paolo
Hi all.
If someone is interested a few years ago I've already developed a parametric algorithm to create an antire random galaxy.
Unfortunately it is in Delphi so a conversion is necessary.
With this algorithm I was able to create all the galaxy types:
- irregular
- elliptical
- spiral
- barred spiral
Basically it simply uses a LOD algorithm. So the galaxy was generated through a pair of "recursive" steps.
I've used the standard rand function of Delphi. Setting the seed manually I was able to repeat exactly the sequence and re-generate the same galaxy every time.
You can find this feature in my old simple universe generator that you can download at:
http://members.xoom.virgilio.it/pangeli ... NEWERA.zip
If someone is interested in this algorithm I should traduce it in C++ or I can publish it as it is in delphi. Furthermore save the data in an additional stars.dat and use in Celestia should be almost trivial.
Bye - Paolo
Posted: 06.12.2003, 05:53
by marc
chrisr,
I used a modified version of Celestia that uses a MySQL database instead of the stars.dat files. It works as a celestia addon, here is the link.
http://mostlyharmless.sourceforge.net/s ... index.html
You can use it to edit and create stars.dat files for Celestia. Its a bit tricky to use but there is documentation and an example lua script that explains how.
Paolo,
Wow
. The results of your galaxy algorithm look great. I'd love to have a look at the source code. I'm familiar with Pascal and Delphi so you don't have to convert it to C++. I imagine it should be possible to convert your algorithm into an SQL/lua script.
Sorry everyone, I was wrong to be negative about the idea
, this might just work.
awesome
Posted: 06.12.2003, 16:52
by Guest
marc i deffinately agree, go with paolo's code. its awesome. it looks fantastic. go for it. just think, if i didnt start this thread, you may have never reconsidered this
Posted: 07.12.2003, 15:30
by Paolo
Here it is the Unit.
I think that the porting is SQL is difficult. Perhaps LUA.
Bye - Paolo
Code: Select all
//------------------------------------------------------------------------------
//
// Copyright Paolo Angeli [New Era Project 1997-2001]
//
// the Galaxy object
//
// To Do:
//
// Done:
// [06/08/2001]: Minor Adjustments
// [27/04/1999]: Changed implementations of all functions.
// [../1997] : Creation
//
//------------------------------------------------------------------------------
unit NEGalaxy;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
interface
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Units
//------------------------------------------------------------------------------
uses
Windows, // Zeromemory
classes, // TStringList
SysUtils, // allocmem,freemem ,format etc.
DirectX, // D3DRMBOX
NEConst, // objects constants
NEUtils, // utility functions and constants
NESideral, // sideral base object
NEStar; // Star object
// Constants
//------------------------------------------------------------------------------
const
gaSpiralSteps = 36; // steps in the spiral construction
// The object
//------------------------------------------------------------------------------
Type
// galaxy record pointer definition
PGalaxyRec = PSideralRec;
// The galaxy object to manipulate the galaxies records
//-----------------------------------------------------
TGalaxyObj = Class(TSideralObj)
private
// Star arrangment routines
procedure fArrange_Stars;
procedure fSpiral_Stars(pt:pointer;idx,num:integer);
procedure fRandom_Stars(pt:pointer;idx,num:integer;lim:single);
procedure fCorrect_Stars_Y(pt:pointer;num:integer);
procedure fGlobular_Stars(pt:pointer;idx,num:integer;dia:single;lim:single);
Public
// Creates a new object
constructor Create;
// Initializes the object with different semantics from ancestor
function Init(
p :PD3DVector; // pointer to the center
s :PLongint // pointer to the seed
):boolean; reintroduce;
// UNUSED: Updates the position of the stars in the galaxy
function Update(
time :single // time to wich update the stars positions
):Boolean; override;
// Gets a stringlist with the basic informations about the object
Procedure Get_Info(
var slst:TStringList // stringlist
); override;
// Gets a stringlist with all the informations about the object
Procedure Get_Info_Extended(
var slst:TStringList // stringlist
); override;
// fills the pointer to the sub object with data
function Get_Sub_Obj(
gp :PSideralRec; // Pointer to the records Pool
idx :longint // Index of the record required
):boolean; override;
protected
// UNUSED: Initializes the object from raw data
function fRaw_init(p:PD3DVector;s:PLongint):boolean; override;
end;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
implementation
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Creates a new Galaxy object
//------------------------------------------------------------------------------
constructor TGalaxyObj.Create;
begin
inherited Create;
fObjCode := NE_OBJ_GALAXY;
end;
//------------------------------------------------------------------------------
// Initializes the object
//------------------------------------------------------------------------------
function TGalaxyObj.Init(
p :PD3DVector; // pointer to the center
s :PLongint // pointer to the seed
):boolean;
begin
// check
if is_ok then begin
if (p = nil) or (s = nil) then
fStatus := fObjCode and NE_POINTER_ERROR;
end;
// If data is Ok
if fStatus = NE_OK then
with fSideralPtr^ do begin
// if previously used then clears and releases pools
if inited then
fRelease_pools;
// clears all the object
Zeromemory(fSideralPtr,gcTsideralRecSiz);
// sideral inits
inited := false;
objCode := fObjCode;
supObject := Nil; // this is the main object in NE hierarchy
index := 0; // the same as above
posPtr := p;
seedPtr := s;
// randomizer
randSeed := seedPtr^; // cretes entire universe here
// specific inits creates seeds and postions
fRaw_Init(posPtr,seedPtr);
if is_ok then
inited := true;
end;
result := fStatus = NE_OK;
end;
//------------------------------------------------------------------------------
//Gets a string with all the informations about the galaxy
//------------------------------------------------------------------------------
procedure TGalaxyObj.Get_Info(var slst:TStringList);
var
tmp :string; // Buffer for temporaneous operations
begin
if Is_Inited then
begin
slst.Clear;
with fSideralPtr^ do
begin
slst.add('');
slst.add(NE_OBJ_NAMES[(fObjCode and $00ff0000) shr 16]);
slst.add(' ----------------------------------------------');
case objType of
gaElliptical :tmp:=gnElliptical;
gaClosedSpiral :tmp:=gnClosedSpiral;
gaOpenedSpiral :tmp:=gnOpenedSpiral;
gaBarredSpiral :tmp:=gnBarredSpiral;
gaLenticular :tmp:=gnLenticular;
gaIrregular :tmp:=gnIrregular;
end;
slst.Add(' Type : ' + tmp);
tmp:=format('%-3d',[subObjNum]);
slst.add(' Number of stars : ' + tmp);
tmp:=format('%-3.4g',[radious]);
slst.add(' Average radious [LY] : ' + tmp);
tmp:=format('%-3.3g',[height]);
slst.add(' Height max [LY] : ' + tmp);
slst.add('');
end;
end;
end;
//------------------------------------------------------------------------------
// Returns the extended informations about the object
//------------------------------------------------------------------------------
Procedure TGalaxyObj.Get_Info_Extended(
var slst:TStringList
);
var
ret : string;
begin
if Is_Inited then begin
slst.clear;
with fSideralPtr^ do begin
slst.add(NE_OBJ_NAMES[(fObjCode and $00ff0000) shr 16]);
ret:= 'under constuction ';
slst.add(ret);
end;
end;
end;
//------------------------------------------------------------------------------
// fills the pointer to the sub object with data
//------------------------------------------------------------------------------
function TGalaxyObj.Get_Sub_Obj(
gp : PSideralRec; // Pointer to the records Pool
idx : longint // Index of the record required
):boolean;
var
stObj :TStarObj;
begin
if Is_Inited then
if (gp <> Nil) then begin
// create manipulator object
stObj:= TStarObj.Create;
// set the current pointer
stObj.set_Ptr(gp,idx);
// initializaes object
if not stObj.Init(fSideralPtr,idx) then
fStatus := stObj.status;
// releases manipulator
stObj.free;
end else
fStatus := fObjCode and NE_SUB_OBJ_ERROR;
Get_Sub_obj := (fStatus = NE_OK);
end;
//------------------------------------------------------------------------------
// Initializes randomly the galaxy object
//------------------------------------------------------------------------------
function TGalaxyObj.fRaw_Init(
p :PD3DVector; // pointer to the galaxy center
s :PLongint // pointer to the galaxy seed
):boolean;
var
buf :Array[0..4] of char; // buffer for the galaxy name number
begin
// If data is Ok
if fStatus = NE_OK then
with fSideralPtr^ do
begin
// number of stars
subObjNum := gaStarNumber; // required here for other calculations
// allocate sub obj pools
if fAllocate_Pools then
begin
// type of the galaxy
objType := gaClosedSpiral; // forced here for NE purposes
// radious of the galaxy [YL]
radious := gaRadiousCx; // light years
// max radious
maxRadious:= radious; // supposed be circular
// height of the galaxy
height := 2*radious*gaConst[objType,gaHeightCxIdx];
// rotation versus
rotVersus :=false; // forced
// inclinations (Top vector)
inclination.x := 0;
inclination.y := 1; // Forced none inclination
inclination.z := 0;
// name
Str(index,buf);
name:='Galaxy ';
strCat(name,buf);
// Create star seeds
Get_N_Random_Seeds(subObjSeeds,subObjNum,1,gaStarSeedGenCx);
// Arrange stars positions
fArrange_Stars; // must be here after dimensioning
end;
end;
fRaw_Init := (fStatus = NE_OK);
end;
//------------------------------------------------------------------------------
// Places the stars created randomly to fit the galaxy shape
//------------------------------------------------------------------------------
procedure TGalaxyObj.fArrange_Stars;
var
num, // copy of stars number
sp, // start position
ns, // number of stars
j : integer; // rest of the stars per spiral step
k : single;
p : PD3DVector; // pointer to the centers point pool
begin
with fSideralPtr^ do
begin
// initials
num := subObjNum;
p := fSideralPtr^.subObjPos;
//spiral stars
sp := 0;
k := gaConst[objType,gaSpiralCxIdx];
ns := round(num*k); // stars in spirals
j := ns mod (gaSPIRALSTEPS * 2);
if j >0 then ns:=ns-j; // no rest
if ns>0 then begin
fSpiral_Stars(p,sp,ns);
sp:=sp+ns-1;
end;
// nucleus stars
k := gaConst[objType,gaNucleusCxIdx];
ns:= round(num*k);
if (ns>0) and ((sp+ns-1) < num) then begin
fRandom_Stars(p,sp,ns,gaConst[objType,gaDiamNuclCxIdx]);
sp:=sp+ns-1;
end;
// internal stars
k := gaConst[objType,gaInternalCxIdx];
ns:=round(num*k);
if (ns>0) and ((sp+ns-1) < num) then begin
fRandom_Stars(p,sp,ns,gaConst[objType,gaDiamInterCxIdx]);
sp:=sp+ns;
end;
// all stars
k := gaConst[objType,gaAllCxIdx];
ns:=round(num*k);
if (ns>0) and ((sp+ns-1) < num) then begin
fRandom_Stars(p,sp,ns,gaConst[objType,gaDiamAllCxIdx]);
sp:=sp+ns;
end;
// corrects stars heigth for matching galaxy disk profile
fCorrect_Stars_Y(p,sp);
// globular ammasses
k := gaConst[objType,gaGlobularCxIdx];
ns:=round(num*k);
if (ns>0) and ((sp+ns-1) < num) then begin
fGlobular_Stars(p,sp,ns,
gaConst[objType,gaGlobAmmRadCx],
gaConst[objType,gaDiamGlobCxIdx]);
sp:=sp+ns-1;
end;
// Remaining stars placed everywhere
ns := num - sp -1;
if ns>0 then
fRandom_Stars(p,sp,ns,gaConst[objType,gaDiamAllCxIdx]);
end;
end;
//------------------------------------------------------------------------------
// Positions a set of stars randomly in a delimitated area
//------------------------------------------------------------------------------
Procedure TGalaxyObj.fRandom_Stars(
pt :pointer; // pointer to stars centers pool
idx, // index of the start o the pool
num :integer; // number of stars interested
lim :single // fraction of the diameter interested
);
var
a, // start position
b, // end position
i :integer; // counter
p :PD3DVector; // pointer to the star center
begin
a := idx;
b := idx+num-1;
p:=PD3DVector(longint(pt) + (a*gcD3DVectorSiz));
for i:= a to b do
begin
p^.x:=(2*random -1.0)*lim;
p^.y:=(2*random -1.0)*gaConst[fSideralPtr^.objType,gaHeightCxIdx];;
p^.z:=(2*random -1.0)*sqrt(sqr(lim)-sqr(p^.x)); // circular distribution
inc(p);
end;
end;
//------------------------------------------------------------------------------
// Positions a set of stars randomly in a spiral way
//------------------------------------------------------------------------------
Procedure TGalaxyObj.fSpiral_Stars(
pt :pointer; // pointer to stars centers pool
idx, // index of the start o the pool
num :integer // number of stars interested
);
var
x1, //current x center of the stars group
z1, //current z center of the stars group
distance, //increment distance from center
currAng, //current angle
angleStep,
scost, //radious of the stars groups
KIncrAngle :single; //spiral angle increment
KIncrDist :single; //distance increment
i,j, //counter s
groupN, //stars per group
delta :integer; //distance between the first semipool and the snd
p1, //pointer to the current point first semipool
p2 :PD3DVector; //pointer to the current point second semipool
begin
with fSideralPtr^ do begin
KIncrAngle := 1.45; // spiral angle increment
KIncrDist := 0.02; // distance increment
angleStep := 360/gaspiralsteps;
groupN := num div (gaSpiralSTEPS * 2);
scost := gaConst[objType,gaSpireDiamCxIdx];
p1 := PD3DVector(longint(pt)+(gcD3DVectorSiz*idx));
delta := num div 2;
delta := gcD3DVectorSiz*delta;
p2 := PD3DVector(longint(p1)+delta);
for j:=0 to gaSpiralSteps-1 do
begin
currAng := j*KincrAngle*angleStep; // angle
distance := 1/gaSpiralSteps*j+KincrDist; // distance from center
// center of the point on the spire
z1:=distance*cos(currAng*(pi/180));
x1:=distance*sin(currAng*(pi/180));
for i:= 1 to groupN do begin
if rotVersus = true then begin
p1^.x:= x1+Get_Rnd_S(-scost,scost)-0.5;
p1^.z:= z1+Get_Rnd_S(-scost,scost)-0.5;
p2^.x:= x1+Get_Rnd_S(-scost,scost);
p2^.z:= z1+Get_Rnd_S(-scost,scost);
end else begin
p1^.x:= -x1+Get_Rnd_S(-scost,scost);
p1^.z:= -z1+Get_Rnd_S(-scost,scost);
p2^.x:= x1+Get_Rnd_S(-scost,scost);
p2^.z:= z1+Get_Rnd_S(-scost,scost);
end;
if ((p1^.x = 0) and ( p1^.y = 0 ) and ( p1^.z = 0) ) or
((p2^.x = 0) and ( p2^.y = 0 ) and ( p2^.z = 0) ) then
p1^.x := 1;
inc(p1);
inc(p2);
end;
end;
end;
end;
//------------------------------------------------------------------------------
// Corrects the height of the stars and the elliptical shape
//------------------------------------------------------------------------------
Procedure TGalaxyObj.fCorrect_Stars_Y(
pt :pointer; // pointer to stars centers pool
num :integer // number of stars interested
);
const
spC :integer = 0;
var
i :integer; // counter
dia, // copy for galaxy diameter
wid, // copy for galaxy height
dis, // distance from the center
disn, // internal diameter
hei :single; // temporaneous value
p :PD3DVector; // star center point
begin
with fSideralPtr^ do
begin
dia :=2;
wid :=height/(2*radious);
disn :=(dia*gaConst[fSideralPtr^.objType,gaDiamNuclCxIdx]);
// assign scansion pointer
p:=pt;
//scansion of the stars centers pool
for i:= 0 to num-1 do begin
// calculate distance of the point
dis:=sqrt(sqr(p^.x)+sqr(p^.z));
// reduces distance if is outer diameter (Sriral_Stars does it sometimes)
while dis > dia do
begin
p^.x:=p^.x*0.95;
p^.z:=p^.z*0.95;
dis:=sqrt(sqr(p^.x)+sqr(p^.z));
end;
hei := 0;
if dis <> 0 then begin
// calculates star height for disk
if dis > disn then
hei:= ((dia/1.6)-dis)*wid
// nucleus
else
hei:= ((dia/1.6)-dis)*wid//+((disn-dis)*wid)
end;
// randomize height
p^.y:=hei*(2*(random-0.5));
if abs(p^.y) > wid then
p^.y := wid;
//increment pointer
inc(p);
end;
end;
end;
//------------------------------------------------------------------------------
// Creates the globular ammasses
//------------------------------------------------------------------------------
Procedure TGalaxyObj.fGlobular_Stars(
pt :pointer; // pointer to stars centers pool
idx, // index of the start o the pool
num :integer; // number of stars interested
dia :single; // average diameter of ammasses
lim :single // fraction of the diameter interested
);
var
b, // end position
i,j :integer; // counter
ammasses, // number of ammasses
stPerAmm, // stars per ammass
rest :longint; // rest
ammDiam,
rad :single; // max ammass center distance from galaxy center
rad1 :single; // like prev. but minus ammass diameter
p :PD3DVector; // pointer to the star center
p1 :D3DVector; // center of the ammass
begin
rad := lim; // ammasses restricted to this area
ammasses := Get_Rnd_L(num div 10,num div 7);
if ammasses <> 0 then begin
stPerAmm := num div ammasses;
rest := num mod ammasses;
end else begin
ammasses := 1;
stPerAmm := num;
rest := 0;
end;
// pointer to the stars centers point pool
p:=PD3DVector(longint(pt) + (idx*gcD3DVectorSiz));
b:=stPerAmm;
// for each ammass
for i:= 1 to ammasses do begin
ammDiam := dia;
ammDiam := ammDiam*Get_Rnd_S(0.8,1.2);
rad1 := rad - (ammDiam/2);
// center of the ammass
p1.y:=(2*random-1.0)*((fSideralPtr^.height/fSideralPtr^.radious)-ammDiam)/2;
p1.x:=(2*random-1.0)*rad1;
p1.z:=(2*random-1.0)*sqrt(sqr(rad1)-sqr(p1.x));
if i = ammasses then
b:=rest;
// stars in the ammass
for j:= 1 to b do begin
p^.x := (2*random-1.0)*ammDiam;
p^.y := (2*random-1.0)*sqrt(sqr(ammdiam)-sqr(p^.x));
p^.z := (2*random-1.0)*sqrt(sqr(ammdiam)-sqr(p^.x));
p^.x := p^.x + p1.x;
p^.y := p^.y + p1.y;
p^.z := p^.z + p1.z;
inc(p);
end;
end;
end;
//------------------------------------------------------------------------------
// Updates the position of the stars in the galaxy: UNUSED
//------------------------------------------------------------------------------
function TGalaxyObj.Update(
time : single // time to wich update the stars positions
):Boolean;
begin
//at moment does nothing
Update := (fStatus = NE_OK);
end;
end.
Posted: 08.12.2003, 00:05
by marc
Thanks Paolo, it looks good.
Paolo wrote:Here it is the Unit.
I think that the porting is SQL is difficult. Perhaps LUA.
Your'e right. I imagine it would be 95% Lua with a few SQL statements used to sample the non positional star information.
It's on my to-do list (changelog on my website). There are a few other things I want to finish first. Hopefully someone else might pick this project up.
Posted: 08.12.2003, 00:33
by bh
This is very interesting!...keep it up guys!
Regards...bh.
oh-no!
Posted: 08.12.2003, 14:58
by Guest
your not hinting that your gonna give up on "mostly harmless" are you?
Posted: 08.12.2003, 22:16
by Size_Mick
Would this program hold any interest to anyone, or relevance to a possible solution in Celestia? Look here:
http://www.synthetic-reality.com/galaxy.htm
Re: oh-no!
Posted: 09.12.2003, 00:25
by marc
Anonymous wrote:your not hinting that your gonna give up on "mostly harmless" are you?
No way! I might have a little go at this later on, that all.