Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

star.cpp

Go to the documentation of this file.
00001 // star.cpp
00002 //
00003 // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 #include <celmath/mathlib.h>
00011 #include <cstring>
00012 #include "celestia.h"
00013 #include "astro.h"
00014 #include "orbit.h"
00015 #include "star.h"
00016 #include "texmanager.h"
00017 
00018 
00019 // The value of the temperature of the sun is actually 5780, but the
00020 // stellar class tables list the temperature of a G2V star as 5860.  We
00021 // use the latter value so that the radius of the sun is computed correctly
00022 // as one times SOLAR_RADIUS . . .  the high metallicity of the Sun is
00023 // probably what accounts for the discrepancy in temperature.
00024 // #define SOLAR_TEMPERATURE    5780.0f
00025 #define SOLAR_TEMPERATURE    5860.0f
00026 #define SOLAR_RADIUS         696000
00027 
00028 
00029 struct SpectralTypeInfo
00030 {
00031     char* name;
00032     float temperature;
00033     float rotationPeriod;
00034 };
00035 
00036 ResourceHandle StarDetails::starTexB = InvalidResource;
00037 ResourceHandle StarDetails::starTexA = InvalidResource;
00038 ResourceHandle StarDetails::starTexG = InvalidResource;
00039 ResourceHandle StarDetails::starTexM = InvalidResource;
00040 ResourceHandle StarDetails::starTexL = InvalidResource;
00041 
00042 static StarDetails** normalStarDetails = NULL;
00043 static StarDetails** whiteDwarfDetails = NULL;
00044 static StarDetails*  neutronStarDetails = NULL;
00045 static StarDetails*  blackHoleDetails = NULL;
00046 static StarDetails*  barycenterDetails = NULL;
00047 
00048 
00049 // Star temperature data from Lang's _Astrophysical Data: Planets and Stars_
00050 // Temperatures from missing (and typically not used) types in those
00051 // tables were just interpolated.
00052 static float tempO[3][10] =
00053 {
00054     { 52500, 52500, 52500, 52500, 48000, 44500, 41000, 38000, 35800, 33000 },
00055     { 50000, 50000, 50000, 50000, 45500, 42500, 39500, 37000, 34700, 32000 },
00056     { 47300, 47300, 47300, 47300, 44100, 42500, 39500, 37000, 34700, 32000 },
00057 };
00058 
00059 static float tempB[3][10] =
00060 {
00061     { 30000, 25400, 22000, 18700, 17000, 15400, 14000, 13000, 11900, 10500 },
00062     { 29000, 24000, 20300, 17100, 16000, 15000, 14100, 13200, 12400, 11000 },
00063     { 26000, 20800, 18500, 16200, 15100, 13600, 13000, 12200, 11200, 10300 },
00064 };
00065 
00066 static float tempA[3][10] =
00067 {
00068     {  9520, 9230, 8970, 8720, 8460, 8200, 8020, 7850, 7580, 7390 },
00069     { 10100, 9480, 9000, 8600, 8300, 8100, 7850, 7650, 7450, 7250 },
00070     {  9730, 9230, 9080, 8770, 8610, 8510, 8310, 8150, 7950, 7800 },
00071 };
00072 
00073 static float tempF[3][10] =
00074 {
00075     { 7200, 7050, 6890, 6740, 6590, 6440, 6360, 6280, 6200, 6110 },
00076     { 7150, 7000, 6870, 6720, 6570, 6470, 6350, 6250, 6150, 6080 },
00077     { 7700, 7500, 7350, 7150, 7000, 6900, 6500, 6300, 6100, 5800 },
00078 };
00079 
00080 static float tempG[3][10] =
00081 {
00082     { 6030, 5940, 5860, 5830, 5800, 5770, 5700, 5630, 5570, 5410 },
00083     { 5850, 5650, 5450, 5350, 5250, 5150, 5050, 5070, 4900, 4820 },
00084     { 5550, 5350, 5200, 5050, 4950, 4850, 4750, 4660, 4600, 4500 },
00085 };
00086 
00087 static float tempK[3][10] =
00088 {
00089     { 5250, 5080, 4900, 4730, 4590, 4350, 4200, 4060, 3990, 3920 },
00090     { 4750, 4600, 4420, 4200, 4000, 3950, 3900, 3850, 3830, 3810 },
00091     { 4420, 4330, 4250, 4080, 3950, 3850, 3760, 3700, 3680, 3660 },
00092 };
00093 
00094 static float tempM[3][10] =
00095 {
00096     { 3850, 3720, 3580, 3470, 3370, 3240, 3050, 2940, 2640, 2000 },
00097     { 3800, 3720, 3620, 3530, 3430, 3330, 3240, 3240, 3240, 3240 },
00098     { 3650, 3550, 3450, 3200, 2980, 2800, 2600, 2600, 2600, 2600 },
00099 };
00100 
00101 // Wolf-Rayet temperatures.  From Lang's Astrophysical Data: Planets and
00102 // Stars.
00103 static float tempWN[10] =
00104 {
00105     50000, 50000, 50000, 50000, 47000, 43000, 39000, 32000, 29000, 29000
00106 };
00107 
00108 static float tempWC[10] =
00109 {
00110     60000, 60000, 60000, 60000, 60000, 60000, 60000, 54000, 46000, 38000
00111 };
00112 
00113 // Brown dwarf temperatures
00114 static float tempL[10] =
00115 {
00116     1960, 1930, 1900, 1850, 1800, 1740, 1680, 1620, 1560, 1500
00117 };
00118 
00119 static float tempT[10] =
00120 {
00121     1425, 1350, 1275, 1200, 1140, 1080, 1020, 900, 800, 750
00122 };
00123 
00124 
00125 // Tables with adjustments for estimating absolute bolometric magnitude from
00126 // visual magnitude, from Lang's "Astrophysical Data: Planets and Stars".
00127 // Gaps in the tables from unused spectral classes were filled in with linear
00128 // interpolation--not accurate, but these shouldn't appear in real catalog
00129 // data anyway.
00130 static float bmag_correctionO[3][10] = 
00131 {
00132     // Lum class V (main sequence)
00133     {
00134         -4.75f, -4.75f, -4.75f, -4.75f, -4.45f,
00135         -4.40f, -3.93f, -3.68f, -3.54f, -3.33f,
00136     },
00137     // Lum class III
00138     {
00139         -4.58f, -4.58f, -4.58f, -4.58f, -4.28f,
00140         -4.05f, -3.80f, -3.58f, -3.39f, -3.13f,
00141     },
00142     // Lum class I
00143     {
00144         -4.41f, -4.41f, -4.41f, -4.41f, -4.17f,
00145         -3.87f, -3.74f, -3.48f, -3.35f, -3.18f,
00146     }
00147 };
00148 
00149 static float bmag_correctionB[3][10] = 
00150 {
00151     // Lum class V (main sequence)
00152     {
00153         -3.16f, -2.70f, -2.35f, -1.94f, -1.70f,
00154         -1.46f, -1.21f, -1.02f, -0.80f, -0.51f,
00155     },
00156     // Lum class III
00157     {
00158         -2.88f, -2.43f, -2.02f, -1.60f, -1.45f,
00159         -1.30f, -1.13f, -0.97f, -0.82f, -0.71f,
00160     },
00161     // Lum class I
00162     {
00163         -2.49f, -1.87f, -1.58f, -1.26f, -1.11f,
00164         -0.95f, -0.88f, -0.78f, -0.66f, -0.52f,
00165     }
00166 };
00167 
00168 static float bmag_correctionA[3][10] = 
00169 {
00170     // Lum class V (main sequence)
00171     {
00172         -0.30f, -0.23f, -0.20f, -0.17f, -0.16f,
00173         -0.15f, -0.13f, -0.12f, -0.10f, -0.09f,
00174     },
00175     // Lum class III
00176     {
00177         -0.42f, -0.29f, -0.20f, -0.17f, -0.15f,
00178         -0.14f, -0.12f, -0.10f, -0.10f, -0.10f,
00179     },
00180     // Lum class I
00181     {
00182         -0.41f, -0.32f, -0.28f, -0.21f, -0.17f,
00183         -0.13f, -0.09f, -0.06f, -0.03f, -0.02f,
00184     }
00185 };
00186 
00187 static float bmag_correctionF[3][10] = 
00188 {
00189     // Lum class V (main sequence)
00190     {
00191         -0.09f, -0.10f, -0.11f, -0.12f, -0.13f,
00192         -0.14f, -0.14f, -0.15f, -0.16f, -0.17f,
00193     },
00194     // Lum class III
00195     {
00196         -0.11f, -0.11f, -0.11f, -0.12f, -0.13f,
00197         -0.13f, -0.15f, -0.15f, -0.16f, -0.18f,
00198     },
00199     // Lum class I
00200     {
00201         -0.01f,  0.00f,  0.00f, -0.01f, -0.02f,
00202         -0.03f, -0.05f, -0.07f, -0.09f, -0.12f,
00203     }
00204 };
00205 
00206 static float bmag_correctionG[3][10] = 
00207 {
00208     // Lum class V (main sequence)
00209     {
00210         -0.18f, -0.19f, -0.20f, -0.20f, -0.21f,
00211         -0.21f, -0.27f, -0.33f, -0.40f, -0.36f,
00212     },
00213     // Lum class III
00214     {
00215         -0.20f, -0.24f, -0.27f, -0.29f, -0.32f,
00216         -0.34f, -0.37f, -0.40f, -0.42f, -0.46f,
00217     },
00218     // Lum class I
00219     {
00220         -0.15f, -0.18f, -0.21f, -0.25f, -0.29f,
00221         -0.33f, -0.36f, -0.39f, -0.42f, -0.46f,
00222     }
00223 };
00224 
00225 static float bmag_correctionK[3][10] = 
00226 {
00227     // Lum class V (main sequence)
00228     {
00229         -0.31f, -0.37f, -0.42f, -0.50f, -0.55f,
00230         -0.72f, -0.89f, -1.01f, -1.13f, -1.26f,
00231     },
00232     // Lum class III
00233     {
00234         -0.50f, -0.55f, -0.61f, -0.76f, -0.94f,
00235         -1.02f, -1.09f, -1.17f, -1.20f, -1.22f,
00236     },
00237     // Lum class I
00238     {
00239         -0.50f, -0.56f, -0.61f, -0.75f, -0.90f,
00240         -1.01f, -1.10f, -1.20f, -1.23f, -1.26f,
00241     }
00242 };
00243 
00244 static float bmag_correctionM[3][10] = 
00245 {
00246     // Lum class V (main sequence)
00247     {
00248         -1.38f, -1.62f, -1.89f, -2.15f, -2.38f,
00249         -2.73f, -3.21f, -3.46f, -4.10f, -4.40f,
00250     },
00251     // Lum class III
00252     {
00253         -1.25f, -1.44f, -1.62f, -1.87f, -2.22f,
00254         -2.48f, -2.73f, -2.73f, -2.73f, -2.73f,
00255     },
00256     // Lum class I
00257     {
00258         -1.29f, -1.38f, -1.62f, -2.13f, -2.75f,
00259         -3.47f, -3.90f, -3.90f, -3.90f, -3.90f,
00260     }
00261 };
00262 
00263 // Brown dwarf data from Grant Hutchison
00264 static float bmag_correctionL[10] =
00265 { 
00266     -4.6f, -4.9f, -5.0f, -5.2f, -5.4f, -5.9f, -6.1f, -6.7f, -7.4f, -8.2f,
00267 };
00268 
00269 static float bmag_correctionT[10] =
00270 { 
00271     -8.9f, -9.6f, -10.8f, -11.9f, -13.1f, -14.4f, -16.1f, -17.9f, -19.6f, -19.6f,
00272 };
00273 
00274 // Stellar rotation by spectral and luminosity class.
00275 // Tables from Grant Hutchison:
00276 // "Most data are from Lang's _Astrophysical Data: Planets and Stars_ (I
00277 // calculated from theoretical radii and observed rotation velocities), but
00278 // with some additional information gleaned from elsewhere.
00279 // A big scatter in rotation periods, of course, particularly in the K and
00280 // early M dwarfs. I'm not hugely happy with the supergiant and giant rotation
00281 // periods for K and M, either - they may be considerably slower yet, but it's
00282 // obviously difficult to come by the data when the rotation velocity is too
00283 // slow to obviously affect the spectra."
00284 //
00285 // I add missing values by interpolating linearly--certainly not the best
00286 // technique, but adequate for our purposes.  The rotation rate of the Sun
00287 // was used for spectral class G2.
00288 
00289 static float rotperiod_O[3][10] =
00290 {
00291     { 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f },
00292     { 6.3f, 6.3f, 6.3f, 6.3f, 6.3f, 6.3f, 6.3f, 6.3f, 6.3f, 6.3f },
00293     { 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f },
00294 };
00295 
00296 static float rotperiod_B[3][10] =
00297 {
00298     { 2.0f, 1.8f, 1.6f, 1.4f, 1.1f, 0.8f, 0.8f, 0.8f, 0.8f, 0.7f },
00299     { 6.3f, 5.6f, 5.0f, 4.3f, 3.7f, 3.1f, 2.9f, 2.8f, 2.7f, 2.6f },
00300     { 15.0f, 24.0f, 33.0f, 42.0f, 52.0f, 63.0f, 65.0f, 67.0f, 70.0f, 72.0f },
00301 };
00302 
00303 static float rotperiod_A[3][10] =
00304 {
00305     { 0.7f, 0.7f, 0.6f, 0.6f, 0.5f, 0.5f, 0.5f, 0.6f, 0.6f, 0.7f },
00306     { 2.5f, 2.3f, 2.1f, 1.9f, 1.7f, 1.6f, 1.6f, 1.7f, 1.7f, 1.8f },
00307     { 75.0f, 77.0f, 80.0f, 82.0f, 85.0f, 87.0f, 95.0f, 104.0f, 115.0f, 125.0f },
00308 };
00309 
00310 static float rotperiod_F[3][10] =
00311 {
00312     { 0.7f, 0.7f, 0.6f, 0.6f, 0.5f, 0.5f, 0.5f, 0.6f, 0.6f, 0.7f },
00313     { 1.9f, 2.5f, 3.0f, 3.5f, 4.0f, 4.6f, 5.6f, 6.7f, 7.8f, 8.9f },
00314     { 135.0f, 141.0f, 148.0f, 155.0f, 162.0f, 169.0f, 175.0f, 182.0f, 188.0f, 195.0f },
00315 };
00316 
00317 static float rotperiod_G[3][10] =
00318 {
00319     { 11.1f, 18.2f, 25.4f, 24.7f, 24.0f, 23.3f, 23.0f, 22.7f, 22.3f, 21.9f },
00320     { 10.0f, 13.0f, 16.0f, 19.0f, 22.0f, 25.0f, 28.0f, 31.0f, 33.0f, 35.0f },
00321     { 202.0f, 222.0f, 242.0f, 262.0f, 282.0f,
00322       303.0f, 323.0f, 343.0f, 364.0f, 384.0f },
00323 };
00324 
00325 static float rotperiod_K[3][10] =
00326 {
00327     { 21.5f, 20.8f, 20.2f, 19.4f, 18.8f, 18.2f, 17.6f, 17.0f, 16.4f, 15.8f },
00328     { 38.0f, 43.0f, 48.0f, 53.0f, 58.0f, 63.0f, 71.0f, 78.0f, 86.0f, 93.0f },
00329     { 405.0f, 526.0f, 648.0f, 769.0f, 891.0f,
00330       1012.0f, 1063.0f, 1103.0f, 1154.0f, 1204.0f },
00331 };
00332 
00333 static float rotperiod_M[3][10] =
00334 {
00335     { 15.2f, 12.4f, 9.6f, 6.8f, 4.0f, 1.3f, 1.0f, 0.7f, 0.4f, 0.2f },
00336     { 101.0f, 101.0f, 101.0f, 101.0f, 101.0f, 101.0f, 101.0f, 101.0f, 101.0f, 101.0f },
00337     { 1265.0f, 1265.0f, 1265.0f, 1265.0f, 1265.0f,
00338       1265.0f, 1265.0f, 1265.0f, 1265.0f, 1265.0f },
00339 };
00340 
00341 
00342 char* LumClassNames[StellarClass::Lum_Count] = {
00343     "I-a0", "I-a", "I-b", "II", "III", "IV", "V", "VI", ""
00344 };
00345 
00346 char* SubclassNames[11] = {
00347     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ""
00348 };
00349 
00350 char* SpectralClassNames[StellarClass::NormalClassCount] = {
00351     "O", "B", "A", "F", "G", "K", "M", "R",
00352     "S", "N", "WC", "WN", "?", "L", "T", "C",
00353 };
00354 
00355 char* WDSpectralClassNames[StellarClass::WDClassCount] = {
00356     "DA", "DB", "DC", "DO", "DQ", "DZ", "D", "DX",
00357 };
00358 
00359 
00360 StarDetails*
00361 StarDetails::GetStarDetails(const StellarClass& sc)
00362 {
00363     switch (sc.getStarType())
00364     {
00365     case StellarClass::NormalStar:
00366         return GetNormalStarDetails(sc.getSpectralClass(),
00367                                     sc.getSubclass(),
00368                                     sc.getLuminosityClass());
00369                                     
00370     case StellarClass::WhiteDwarf:
00371         return GetWhiteDwarfDetails(sc.getSpectralClass(),
00372                                     sc.getSubclass());
00373     case StellarClass::NeutronStar:
00374         return GetNeutronStarDetails();
00375     case StellarClass::BlackHole:
00376         return GetBlackHoleDetails();
00377     default:
00378         return NULL;
00379     }
00380 }
00381 
00382 
00383 StarDetails*
00384 StarDetails::CreateStandardStarType(const std::string& specTypeName,
00385                                     float _temperature,
00386                                     float _rotationPeriod)
00387                                     
00388 {
00389     StarDetails* details = new StarDetails();
00390 
00391     details->setTemperature(_temperature);
00392     details->setSpectralType(specTypeName);
00393 
00394     RotationElements re = details->getRotationElements();
00395     re.period = _rotationPeriod;
00396     details->setRotationElements(re);
00397 
00398     return details;
00399 }
00400 
00401 
00402 StarDetails*
00403 StarDetails::GetNormalStarDetails(StellarClass::SpectralClass specClass,
00404                                   unsigned int subclass,
00405                                   StellarClass::LuminosityClass lumClass)
00406 {
00407     if (normalStarDetails == NULL)
00408     {
00409         unsigned int nTypes = StellarClass::Spectral_Count * 11 * 
00410             StellarClass::Lum_Count;
00411         normalStarDetails = new StarDetails*[nTypes];
00412         for (unsigned int i = 0; i < nTypes; i++)
00413             normalStarDetails[i] = NULL;
00414     }
00415 
00416     if (subclass > StellarClass::Subclass_Unknown)
00417         subclass = StellarClass::Subclass_Unknown;
00418 
00419     uint index = subclass + (specClass + lumClass * StellarClass::Spectral_Count) * 11;
00420     if (normalStarDetails[index] == NULL)
00421     {
00422         char name[16];
00423         sprintf(name, "%s%s%s",
00424                 SpectralClassNames[specClass],
00425                 SubclassNames[subclass],
00426                 LumClassNames[lumClass]);
00427 
00428         // Use the same properties for an unknown subclass as for subclass 5
00429         if (subclass == StellarClass::Subclass_Unknown)
00430         {
00431             // Since early O and Wolf-Rayet stars are exceedingly rare,
00432             // use temperature of the more common late types when the subclass
00433             // is unspecified in the spectral type.  For other stars, default
00434             // to subclass 5.
00435             switch (specClass)
00436             {
00437             case StellarClass::Spectral_O:
00438             case StellarClass::Spectral_WN:
00439             case StellarClass::Spectral_WC:
00440                 subclass = 9;
00441                 break;
00442             default:
00443                 subclass = 5;
00444                 break;
00445             }
00446         }
00447 
00448         unsigned int lumIndex = 0;
00449         switch (lumClass)
00450         {
00451         case StellarClass::Lum_Ia0:
00452         case StellarClass::Lum_Ia:
00453         case StellarClass::Lum_Ib:
00454         case StellarClass::Lum_II:
00455             lumIndex = 2;
00456             break;
00457         case StellarClass::Lum_III:
00458         case StellarClass::Lum_IV:
00459             lumIndex = 1;
00460             break;
00461         case StellarClass::Lum_V:
00462         case StellarClass::Lum_VI:
00463         case StellarClass::Lum_Unknown:
00464             lumIndex = 0;
00465             break;
00466         }
00467 
00468         float temp = 0.0f;
00469         switch (specClass)
00470         {
00471         case StellarClass::Spectral_O:
00472             temp = tempO[lumIndex][subclass];
00473             break;
00474         case StellarClass::Spectral_B:
00475             temp = tempB[lumIndex][subclass];
00476             break;
00477         case StellarClass::Spectral_Unknown:
00478         case StellarClass::Spectral_A:
00479             temp = tempA[lumIndex][subclass];
00480             break;
00481         case StellarClass::Spectral_F:
00482             temp = tempF[lumIndex][subclass];
00483             break;
00484         case StellarClass::Spectral_G:
00485             temp = tempG[lumIndex][subclass];
00486             break;
00487         case StellarClass::Spectral_K:
00488             temp = tempK[lumIndex][subclass];
00489             break;
00490         case StellarClass::Spectral_M:
00491             temp = tempM[lumIndex][subclass];
00492             break;
00493         case StellarClass::Spectral_R:
00494             temp = tempK[lumIndex][subclass];
00495             break;
00496         case StellarClass::Spectral_S:
00497             temp = tempM[lumIndex][subclass];
00498             break;
00499         case StellarClass::Spectral_N:
00500             temp = tempM[lumIndex][subclass];
00501             break;
00502         case StellarClass::Spectral_C:
00503             temp = tempM[lumIndex][subclass];
00504             break;
00505         case StellarClass::Spectral_WN:
00506             temp = tempWN[subclass];
00507             break;
00508         case StellarClass::Spectral_WC:
00509             temp = tempWC[subclass];
00510             break;
00511         case StellarClass::Spectral_L:
00512             temp = tempL[subclass];
00513             break;
00514         case StellarClass::Spectral_T:
00515             temp = tempT[subclass];
00516             break;
00517         }
00518 
00519         float bmagCorrection = 0.0f;
00520         float period = 1.0f;
00521         switch (specClass)
00522         {
00523         case StellarClass::Spectral_O:
00524             period = rotperiod_O[lumIndex][subclass];
00525             bmagCorrection = bmag_correctionO[lumIndex][subclass];
00526             break;
00527         case StellarClass::Spectral_B:
00528             period = rotperiod_B[lumIndex][subclass];
00529             bmagCorrection = bmag_correctionB[lumIndex][subclass];
00530             break;
00531         case StellarClass::Spectral_Unknown:
00532         case StellarClass::Spectral_A:
00533             period = rotperiod_A[lumIndex][subclass];
00534             bmagCorrection = bmag_correctionA[lumIndex][subclass];
00535             break;
00536         case StellarClass::Spectral_F:
00537             period = rotperiod_F[lumIndex][subclass];
00538             bmagCorrection = bmag_correctionF[lumIndex][subclass];
00539             break;
00540         case StellarClass::Spectral_G:
00541             period = rotperiod_G[lumIndex][subclass];
00542             bmagCorrection = bmag_correctionG[lumIndex][subclass];
00543             break;
00544         case StellarClass::Spectral_K:
00545             period = rotperiod_K[lumIndex][subclass];
00546             bmagCorrection = bmag_correctionK[lumIndex][subclass];
00547             break;
00548         case StellarClass::Spectral_M:
00549             period = rotperiod_M[lumIndex][subclass];
00550             bmagCorrection = bmag_correctionM[lumIndex][subclass];
00551             break;
00552 
00553         case StellarClass::Spectral_R:
00554         case StellarClass::Spectral_S:
00555         case StellarClass::Spectral_N:
00556         case StellarClass::Spectral_C:
00557             period = rotperiod_M[lumIndex][subclass];
00558             bmagCorrection = bmag_correctionM[lumIndex][subclass];
00559             break;
00560 
00561         case StellarClass::Spectral_WC:
00562         case StellarClass::Spectral_WN:
00563             period = rotperiod_O[lumIndex][subclass];
00564             bmagCorrection = bmag_correctionO[lumIndex][subclass];
00565             break;
00566 
00567         case StellarClass::Spectral_L:
00568             // Assume that brown dwarfs are fast rotators like late M dwarfs
00569             period = 0.2f;
00570             bmagCorrection = bmag_correctionL[subclass];
00571             break;
00572 
00573         case StellarClass::Spectral_T:
00574             // Assume that brown dwarfs are fast rotators like late M dwarfs
00575             period = 0.2f;
00576             bmagCorrection = bmag_correctionT[subclass];
00577             break;
00578         }
00579 
00580         normalStarDetails[index] = CreateStandardStarType(name, temp, period);
00581         normalStarDetails[index]->setBolometricCorrection(bmagCorrection);
00582         
00583         if (specClass == StellarClass::Spectral_L ||
00584             specClass == StellarClass::Spectral_T)
00585         {
00586             normalStarDetails[index]->setTexture(MultiResTexture(starTexL, starTexL, starTexL));
00587         }
00588         else
00589         {
00590             normalStarDetails[index]->setTexture(MultiResTexture(starTexA, starTexA, starTexA));
00591         }
00592     }
00593 
00594     return normalStarDetails[index];
00595 }
00596 
00597 
00598 StarDetails*
00599 StarDetails::GetWhiteDwarfDetails(StellarClass::SpectralClass specClass,
00600                                   unsigned int subclass)
00601 {
00602     // Hack assumes all WD types are consecutive
00603     unsigned int scIndex = static_cast<unsigned int>(specClass) -
00604         StellarClass::FirstWDClass;
00605 
00606     if (whiteDwarfDetails == NULL)
00607     {
00608         unsigned int nTypes = 
00609             StellarClass::WDClassCount * StellarClass::SubclassCount;
00610         whiteDwarfDetails = new StarDetails*[nTypes];
00611         for (unsigned int i = 0; i < nTypes; i++)
00612             whiteDwarfDetails[i] = NULL;
00613     }
00614 
00615     if (subclass > StellarClass::Subclass_Unknown)
00616         subclass = StellarClass::Subclass_Unknown;
00617 
00618     uint index = subclass + (scIndex * StellarClass::SubclassCount);
00619     if (whiteDwarfDetails[index] == NULL)
00620     {
00621         char name[16];
00622         sprintf(name, "%s%s",
00623                 WDSpectralClassNames[scIndex],
00624                 SubclassNames[subclass]);
00625 
00626         float temp;
00627         if (subclass == 0)
00628             temp = 100000.0f;
00629         if (subclass == StellarClass::Subclass_Unknown)
00630             temp = 10080.0f;  // Treat unknown as subclass 5
00631         else
00632             temp = 50400.0f / subclass;
00633 
00634         // Assign white dwarfs a rotation period of half an hour; very
00635         // rough, as white rotation rates vary a lot.
00636         float period = 1.0f / 48.0f;
00637         
00638         whiteDwarfDetails[index] = CreateStandardStarType(name, temp, period);
00639         whiteDwarfDetails[index]->setTexture(MultiResTexture(starTexA, starTexA, starTexA));
00640     }
00641 
00642     return whiteDwarfDetails[index];
00643 }
00644 
00645 
00646 StarDetails*
00647 StarDetails::GetNeutronStarDetails()
00648 {
00649     if (neutronStarDetails == NULL)
00650     {
00651         // The default neutron star has a rotation period of one second,
00652         // surface temperature of five million K.
00653         neutronStarDetails = CreateStandardStarType("Q", 5000000.0f,
00654                                                     1.0f / 86400.0f);
00655         neutronStarDetails->setRadius(10.0f);
00656         neutronStarDetails->addKnowledge(KnowRadius);
00657         neutronStarDetails->setTexture(MultiResTexture(starTexA, starTexA, starTexA));
00658     }
00659 
00660     return neutronStarDetails;
00661 }
00662 
00663 
00664 StarDetails*
00665 StarDetails::GetBlackHoleDetails()
00666 {
00667     if (blackHoleDetails == NULL)
00668     {
00669         // Default black hole parameters are based on a one solar mass
00670         // black hole.
00671         // The temperature is computed from the equation:
00672         //      T=h_bar c^3/(8 pi G k m)
00673         blackHoleDetails = CreateStandardStarType("X", 6.15e-8f,
00674                                                   1.0f / 86400.0f);
00675         blackHoleDetails->setRadius(2.9f);
00676         blackHoleDetails->addKnowledge(KnowRadius);
00677     }
00678 
00679     return blackHoleDetails;
00680 }
00681 
00682 
00683 StarDetails*
00684 StarDetails::GetBarycenterDetails()
00685 {
00686 
00687     if (barycenterDetails == NULL)
00688     {
00689         barycenterDetails = CreateStandardStarType("Bary", 1.0f, 1.0f);
00690         barycenterDetails->setRadius(0.001f);
00691         barycenterDetails->addKnowledge(KnowRadius);
00692         barycenterDetails->setVisibility(false);
00693     }
00694 
00695     return barycenterDetails;
00696 }
00697 
00698 
00699 void
00700 StarDetails::InitializeStarTextures()
00701 {
00702     starTexB = GetTextureManager()->getHandle(TextureInfo("bstar.jpg", 0));
00703     starTexA = GetTextureManager()->getHandle(TextureInfo("astar.jpg", 0));
00704     starTexG = GetTextureManager()->getHandle(TextureInfo("gstar.jpg", 0));
00705     starTexM = GetTextureManager()->getHandle(TextureInfo("mstar.jpg", 0));
00706     starTexL = GetTextureManager()->getHandle(TextureInfo("browndwarf.jpg", 0));
00707 }
00708 
00709 
00710 StarDetails::StarDetails() :
00711     radius(0.0f),
00712     temperature(0.0f),
00713     bolometricCorrection(0.0f),
00714     knowledge(0u),
00715     visible(true),
00716     model(InvalidResource),
00717     orbit(NULL),
00718     orbitalRadius(0.0f),
00719     barycenter(NULL),
00720     semiAxes(1.0f, 1.0f, 1.0f)
00721 {
00722     spectralType[0] = '\0';
00723 }
00724 
00725 
00726 void
00727 StarDetails::setRadius(float _radius)
00728 {
00729     radius = _radius;
00730 }
00731 
00732 
00733 void
00734 StarDetails::setTemperature(float _temperature)
00735 {
00736     temperature = _temperature;
00737 }
00738 
00739 
00740 void
00741 StarDetails::setSpectralType(const std::string& s)
00742 {
00743     strncpy(spectralType, s.c_str(), sizeof(spectralType));
00744     spectralType[sizeof(spectralType) - 1] = '\0';
00745 }
00746 
00747 
00748 void
00749 StarDetails::setKnowledge(uint32 _knowledge)
00750 {
00751     knowledge = _knowledge;
00752 }
00753 
00754 
00755 void
00756 StarDetails::addKnowledge(uint32 _knowledge)
00757 {
00758     knowledge |= _knowledge;
00759 }
00760 
00761 
00762 void
00763 StarDetails::setBolometricCorrection(float correction)
00764 {
00765     bolometricCorrection = correction;
00766 }
00767 
00768 
00769 void
00770 StarDetails::setTexture(const MultiResTexture& tex)
00771 {
00772     texture = tex;
00773 }
00774 
00775 
00776 void
00777 StarDetails::setModel(ResourceHandle rh)
00778 {
00779     model = rh;
00780 }
00781 
00782 
00783 void
00784 StarDetails::setOrbit(Orbit* o)
00785 {
00786     orbit = o;
00787     computeOrbitalRadius();
00788 }
00789 
00790 
00791 void
00792 StarDetails::setOrbitBarycenter(Star* bc)
00793 {
00794     barycenter = bc;
00795     computeOrbitalRadius();
00796 }
00797 
00798 
00799 void
00800 StarDetails::setOrbitalRadius(float r)
00801 {
00802     if (orbit != NULL)
00803         orbitalRadius = r;
00804 }
00805 
00806 
00807 void
00808 StarDetails::computeOrbitalRadius()
00809 {
00810     if (orbit == NULL)
00811     {
00812         orbitalRadius = 0.0f;
00813     }
00814     else
00815     {
00816         orbitalRadius = (float) astro::kilometersToLightYears(orbit->getBoundingRadius());
00817         if (barycenter != NULL)
00818             orbitalRadius += barycenter->getOrbitalRadius();
00819     }
00820 }
00821 
00822 
00823 void
00824 StarDetails::setVisibility(bool b)
00825 {
00826     visible = b;
00827 }
00828 
00829 
00830 void
00831 StarDetails::setRotationElements(const RotationElements& re)
00832 {
00833     rotationElements = re;
00834 }
00835 
00836 
00837 // Return the radius of the star in kilometers
00838 float Star::getRadius() const
00839 {
00840     if (details->getKnowledge(StarDetails::KnowRadius))
00841         return details->getRadius();
00842         
00843 #ifdef NO_BOLOMETRIC_MAGNITUDE_CORRECTION
00844     // Use the Stefan-Boltzmann law to estimate the radius of a
00845     // star from surface temperature and luminosity
00846     return SOLAR_RADIUS * (float) sqrt(getLuminosity()) *
00847         square(SOLAR_TEMPERATURE / getTemperature());
00848 #else
00849     // Calculate the luminosity of the star from the bolometric, not the
00850     // visual magnitude of the star.
00851     float solarBMag = SOLAR_ABSMAG + bmag_correctionG[0][2];
00852     float bmag = getBolometricMagnitude();
00853     float boloLum = (float) exp((solarBMag - bmag) / LN_MAG);
00854 
00855     // Use the Stefan-Boltzmann law to estimate the radius of a
00856     // star from surface temperature and luminosity
00857     return SOLAR_RADIUS * (float) sqrt(boloLum) *
00858         square(SOLAR_TEMPERATURE / getTemperature());
00859 #endif
00860 }
00861 
00862 
00863 void
00864 StarDetails::setEllipsoidSemiAxes(const Vec3f& v)
00865 {
00866     semiAxes = v;
00867 }
00868 
00869 
00870 UniversalCoord
00871 Star::getPosition(double t) const
00872 {
00873     const Orbit* orbit = getOrbit();
00874     if (!orbit)
00875     {
00876         return UniversalCoord(position.x * 1.0e6,
00877                               position.y * 1.0e6,
00878                               position.z * 1.0e6);
00879     }
00880     else
00881     {
00882         const Star* barycenter = getOrbitBarycenter();
00883 
00884         if (barycenter == NULL)
00885         {
00886             Point3d barycenterPos(position.x * 1.0e6,
00887                                   position.y * 1.0e6,
00888                                   position.z * 1.0e6);
00889 
00890             return UniversalCoord(barycenterPos) +
00891                 ((orbit->positionAtTime(t) - Point3d(0.0, 0.0, 0.0)) *
00892                  astro::kilometersToMicroLightYears(1.0));
00893         }
00894         else
00895         {
00896             return barycenter->getPosition(t) +
00897                 ((orbit->positionAtTime(t) - Point3d(0.0, 0.0, 0.0)) *
00898                  astro::kilometersToMicroLightYears(1.0));
00899         }
00900     }
00901 }
00902 
00903 
00904 MultiResTexture
00905 Star::getTexture() const
00906 {
00907     return details->getTexture();
00908 }
00909 
00910 
00911 ResourceHandle
00912 Star::getModel() const
00913 {
00914     return details->getModel();
00915 }
00916 
00917 
00918 void Star::setCatalogNumber(uint32 n)
00919 {
00920     catalogNumber = n;
00921 }
00922 
00923 void Star::setPosition(float x, float y, float z)
00924 {
00925     position = Point3f(x, y, z);
00926 }
00927 
00928 void Star::setPosition(Point3f p)
00929 {
00930     position = p;
00931 }
00932 
00933 void Star::setAbsoluteMagnitude(float mag)
00934 {
00935     absMag = mag;
00936 }
00937 
00938 
00939 float Star::getApparentMagnitude(float ly) const
00940 {
00941     return astro::absToAppMag(absMag, ly);
00942 }
00943 
00944 
00945 float Star::getLuminosity() const
00946 {
00947     return astro::absMagToLum(absMag);
00948 }
00949 
00950 void Star::setLuminosity(float lum)
00951 {
00952     absMag = astro::lumToAbsMag(lum);
00953 }
00954 
00955 void Star::setDetails(StarDetails* sd)
00956 {
00957     details = sd;
00958 }
00959 
00960 void Star::setOrbitBarycenter(Star* s)
00961 {
00962     details->setOrbitBarycenter(s);
00963 }
00964 
00965 void Star::computeOrbitalRadius()
00966 {
00967     details->computeOrbitalRadius();
00968 }
00969 
00970 void
00971 Star::setRotationElements(const RotationElements& re)
00972 {
00973     details->setRotationElements(re);
00974 }

Generated on Sat Jan 14 22:30:28 2006 for Celestia by  doxygen 1.4.1