1 // StarPlot - A program for interactively viewing 3D maps of stellar positions.
2 // Copyright (C) 2000  Kevin B. McCarty
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 
18 
19 //
20 // star.h - The Star class.
21 //
22 
23 #ifndef _STAR_H_
24 #define _STAR_H_
25 
26 #include "../../lib/compat.h"
27 #include "strings.h"
28 #include "specclass.h"
29 #include "vector3.h"
30 #include "viewer.h"
31 #include <cstdlib>
32 #include <cstdio>
33 #include <cctype>
34 #include <cmath>
35 
36 // Specify the characters used to separate fields in a star text record
37 const char FIELD_DELIMITER = ';';
38 const char SUBFIELD_DELIMITER = ',';
39 
40 // How many pixels a secondary star must be from its primary before
41 //  being drawn (implemented in StarArray::Read())
42 const unsigned int MIN_SECONDARY_DISTANCE = 2;
43 
44 // Default radius, in pixels, with which a star is drawn
45 //  (implemented in Star::Display())
46 const unsigned int STAR_PIXEL_RADIUS = 2;
47 
48 // function to hash spectral class.  This takes the one-letter class
49 //  description as argument and outputs the position of the class in
50 //  the Rules.StarClasses array (see comments below).
SpecHash(char spectrum)51 inline size_t SpecHash(char spectrum)
52 {
53   switch (toupper(spectrum)) {
54     case 'O': case 'W': return 0;             // O and Wolf-Rayet stars
55     case 'B': return 1;
56     case 'A': return 2;
57     case 'F': return 3;
58     case 'G': return 4;
59     case 'K': return 5;
60     case 'M': return 6;
61     case 'D': return 7;                       // White dwarfs
62     case '*': return 9;                       // Nonstellar objects
63     default : return 8;                       // Unclassified stars
64   }
65 }
66 
67 
68 // an enum to specify what kind of labels should be attached to stars:
69 //  full name, name only for stars with Bayer designations, numerical index,
70 //  or none.
71 enum star_label_t { NO_LABEL, NUMBER_LABEL, STRING_LABEL, LANDMARK_LABEL };
72 
73 // an enum to specify whether the diameter of star icons should depend upon
74 //  MK class or upon magnitude
75 enum star_diameter_t { MK_DIAMETERS, MAGNITUDE_DIAMETERS };
76 
77 #define CELESTIAL 1
78 #define GALACTIC  0
79 
80 // a struct to keep all these rules for which stars get displayed in
81 //  one place.  This will be a private member of StarArray
82 
83 struct Rules {
84   // where we are reading the data from
85   StringList   ChartFileNames;
86 
87   // which stars get displayed: used in the Star::PassesFilter() check
88   Vector3      ChartLocation;
89   SolidAngle   ChartOrientation;
90   double       ChartRadius;
91   float        ChartDimmestMagnitude;
92   float        ChartBrightestMagnitude;
93   bool	       ChartHideCompanions;
94 
95   // the following is included in this struct for convenience, but is not
96   // used in the core classes; implementation is up to the GUI interface.
97   bool         ChartAutosetDimmestMagnitude;
98 
99   // The elements of StarClasses tell whether or not to display a specific
100   //  spectral class of star.  See the SpecHash function comment above.
101   bool         StarClasses[10];
102 
103   // some other display toggles: used in the displays
104   bool         CelestialCoords;
105   star_diameter_t StarDiameters;
106   star_label_t StarLabels;
107   bool         StarBars;
108   bool         ChartGrid;
109   bool         ChartLegend;
110   distance_unit ChartUnits[4];
111 
112   // constructors for convenience
CopyRules113   void Copy(const StringList &files, const Vector3 &posn,
114             const SolidAngle &orientation, double rad,
115             float dimmag, float brightmag, bool hide_comps,
116 	    bool autoset, const bool classes[10],
117             bool coords, star_diameter_t diam, star_label_t label,
118             bool bars, bool grid, bool legend,
119 	    const distance_unit units[4])
120   {
121     ChartFileNames   = files;
122     ChartLocation    = posn;
123     ChartOrientation = orientation;
124     ChartRadius      = rad;
125     ChartDimmestMagnitude = dimmag;
126     ChartBrightestMagnitude = brightmag;
127     ChartHideCompanions = hide_comps;
128     ChartAutosetDimmestMagnitude = autoset;
129     for (unsigned int i = 0; i < 10; i++) StarClasses[i] = classes[i];
130     CelestialCoords  = coords;
131     StarDiameters    = diam;
132     StarLabels       = label;
133     StarBars         = bars;
134     ChartGrid        = grid;
135     ChartLegend      = legend;
136     for (unsigned int i = 0; i < 4; i++) ChartUnits[i] = units[i];
137   }
138 
RulesRules139   Rules(const StringList &files, const Vector3 &posn,
140 	const SolidAngle &orientation, double rad, float dimmag,
141 	float brightmag, bool hide_comps, bool autoset, const bool classes[10],
142         bool coords, star_diameter_t diam, star_label_t label,
143         bool bars, bool grid, bool legend,
144 	const distance_unit units[4])
145   { Copy(files, posn, orientation, rad, dimmag, brightmag, hide_comps, autoset,
146 	 classes, coords, diam, label, bars, grid, legend, units);
147   }
148 
RulesRules149   Rules()
150   { bool classes[10];
151     for (unsigned int i = 0; i < 10; i++) classes[i] = true;
152     distance_unit units[4] = { DIST_LY, DIST_LY, DIST_AU, DIST_KM };
153     Copy(StringList(), Vector3(0,0,0), SolidAngle(0,0), 10, 25, -25,
154 	 true, true, classes, CELESTIAL, MAGNITUDE_DIAMETERS, LANDMARK_LABEL,
155 	 true, true, true, units);
156   }
157 
RulesRules158   Rules(const Rules &r)
159   { Copy(r.ChartFileNames, r.ChartLocation, r.ChartOrientation, r.ChartRadius,
160 	 r.ChartDimmestMagnitude, r.ChartBrightestMagnitude,
161 	 r.ChartHideCompanions, r.ChartAutosetDimmestMagnitude,
162 	 r.StarClasses, r.CelestialCoords,
163 	 r.StarDiameters, r.StarLabels, r.StarBars, r.ChartGrid,
164 	 r.ChartLegend, r.ChartUnits);
165   }
166 
~RulesRules167   ~Rules() { }
168 
169   Rules & operator= (const Rules &r)
170   { if (&r != this)
171       Copy(r.ChartFileNames, r.ChartLocation, r.ChartOrientation, r.ChartRadius,
172       r.ChartDimmestMagnitude, r.ChartBrightestMagnitude,
173       r.ChartHideCompanions, r.ChartAutosetDimmestMagnitude,
174       r.StarClasses, r.CelestialCoords,
175       r.StarDiameters, r.StarLabels, r.StarBars, r.ChartGrid,
176       r.ChartLegend, r.ChartUnits);
177     return *this;
178   }
179 };
180 
181 
182 class Star {
183  private:
184   StringList sNames;            // list of designations for the star
185   StringList sMembership;       // in one or more clusters or multiple systems
186   StringList sComments;         // miscellaneous text information
187 
188   SolidAngle sGridPosn;         // star location, relative to sun, and size
189   double sDistance, sDiameter;  //  (in radians and L-Y)
190   double sPrimaryDistance;      // distance (L-Y) from primary; 0 if n/a
191 
192   double sMagnitude;            // absolute visual magnitude
193   SpecClass sSpectrum;          // spectral type and luminosity class (O9.5 Ia)
194 
195   mutable size_t sPlace;	// numerical order of the star, for labels
196   mutable unsigned int xPixel;  // location of the star on the plot
197   mutable unsigned int yPixel;
198   mutable unsigned int rPixel;  // radius of the star in pixels
199   mutable bool sLabelDraw;      // whether to draw label if in landmark mode
200 
201   // function to save some typing in the copy constructor and operator=
202   void Obtain(StringList, StringList, StringList, SolidAngle,
203 	      double, double, double, double, SpecClass, size_t,
204 	      unsigned int, unsigned int, unsigned int, bool);
205 
206  public:
207   Star();
208   Star(const Star &s); // copy constructor
209   Star & operator=(const Star &s);
210 
211   // constructs a Star by parsing a text record:
212   Star(const std::string &record,
213        bool fastconversion = false, bool nameconvert = true);
214 
GetPlace()215   inline unsigned int GetPlace()  const { return sPlace; }
SetPlace(size_t place)216   inline void SetPlace(size_t place) const { sPlace = place; }
GetXPixel()217   inline unsigned int GetXPixel() const { return xPixel; }
GetYPixel()218   inline unsigned int GetYPixel() const { return yPixel; }
GetRPixel()219   inline unsigned int GetRPixel() const { return rPixel; }
SetLabel(bool label)220   inline void SetLabel(bool label) const { sLabelDraw = label; }
221 
222   // convert celestial to galactic coordinates and vice versa (note this
223   //  does NOT test to see whether it's already in desired coord. system)
toGalactic()224   inline void toGalactic()
225     {
226       if (sDistance == 0.0) sGridPosn = SolidAngle(0.0, 0.0);
227       else sGridPosn = sGridPosn.toGalactic();
228     }
229 
toCelestial()230   inline void toCelestial()
231     {
232       if (sDistance == 0.0) sGridPosn = SolidAngle(0.0, 0.0);
233       else sGridPosn = sGridPosn.toCelestial();
234     }
235 
236   // get various pieces of information about the star
GetStarXYZ()237   inline Vector3 GetStarXYZ() const { return sGridPosn.toCartesian(sDistance); }
GetStarDistance()238   inline double GetStarDistance()  const { return sDistance; }
GetStarMagnitude()239   inline double GetStarMagnitude() const { return sMagnitude; }
GetStarPrimaryDistance()240   inline double GetStarPrimaryDistance() const { return sPrimaryDistance; }
GetStarClass()241   inline SpecClass  GetStarClass() const { return sSpectrum; }
GetStarNames()242   inline StringList GetStarNames() const { return sNames; }
GetStarMembership()243   inline StringList GetStarMembership() const { return sMembership; }
244 
245   // for use by starconvert:
SetStarMembership(std::string s)246   inline void SetStarMembership(std::string s) { sMembership.push_back(s); }
SetStarPrimaryDistance(double d)247   inline void SetStarPrimaryDistance(double d) { sPrimaryDistance = d; }
248 
249   // tells whether star should be displayed given the Rules
250   bool PassesFilter(const Rules &rules) const;
251 
252   // plot the star onto the painting device, as viewed from the specified
253   //  point and orientation given in Rules.
254   //
255   //  Note: StarViewer is a generic display class defined in viewer.h -- I am
256   //  trying to keep the graphics-library dependent functions contained in
257   //  descendant classes of StarViewer (e.g. KDEViewer, GTKViewer, etc.,
258   //  which will be wrapper classes around the given graphics libraries).
259   //  This will make the code a bit more confusing, but make the program
260   //  easier to port.
261   void Display(const Rules &rules, StarViewer *sv) const;
262 
263   // a lighter-weight drawing function that just plots the star at a specific
264   //  point (returns the radius of star drawn, in pixels)
265   unsigned int Draw(const Rules &rules, StarViewer *sv, int xposn, int yposn,
266 		    int pixelradius = 0) const;
267 
268   // write star information to a StringList:
269   StringList GetInfo(const Rules &rules, bool punctuation = true,
270 		     char sep = ' ') const;
271 };
272 
273 
274 #endif
275