1 #define OUT (*params.out)  \
2  \
3 
4 /*5:*/
5 #line 331 "pp3.w"
6 
7 #include <iostream>
8 #include <string>
9 #include <fstream>
10 #include <sstream>
11 #include <vector>
12 #include <map>
13 #include <list>
14 #include <iomanip>
15 #include <cstdlib>
16 #include <cmath>
17 #include <cfloat>
18 #include <cstring>
19 
20 using namespace std;
21 
22 /*43:*/
23 #line 1673 "pp3.w"
24 
my_fmin(const double & x,const double & y)25 inline double my_fmin(const double&x,const double&y){
26 return x<y?x:y;
27 }
28 
my_fmax(const double & x,const double & y)29 inline double my_fmax(const double&x,const double&y){
30 return x> y?x:y;
31 }
32 
my_fdim(const double & x,const double & y)33 inline double my_fdim(const double&x,const double&y){
34 return x> y?x-y:0.0;
35 }
36 
37 
38 /*:43*/
39 #line 346 "pp3.w"
40 
41 
42 /*:5*//*7:*/
43 #line 368 "pp3.w"
44 
45 const char*pp3data_env_raw= getenv("PP3DATA");
46 const string pp3data_env= (pp3data_env_raw==NULL?
47 "":pp3data_env_raw);
48 #ifdef PP3DATA
49 const string pp3data(PP3DATA);
50 #else
51 const string pp3data;
52 #endif
53 const string filename_prefix(!pp3data_env.empty()?
54 pp3data_env+'/':(pp3data.empty()?
55 "":pp3data+"/"));
56 
57 
58 /*:7*//*8:*/
59 #line 384 "pp3.w"
60 
61 /*70:*/
62 #line 2388 "pp3.w"
63 
64 struct color{
65 double red,green,blue;
66 string name;
colorcolor67 color(string name,double red,double green,double blue)
68 :red(red),green(green),blue(blue),name(name){}
colorcolor69 color(double red,double green,double blue)
70 :red(red),green(green),blue(blue),name(){}
71 void set(ostream&out)const;
72 };
73 
74 /*:70*/
75 #line 385 "pp3.w"
76 
77 
78 struct parameters{
79 double center_rectascension,center_declination;
80 double view_frame_width,view_frame_height;
81 double grad_per_cm;
82 double label_skip,minimal_nebula_radius,faintest_cluster_magnitude,
83 faintest_diffuse_nebula_magnitude,faintest_star_magnitude,
84 star_scaling,minimal_star_radius,faintest_star_disk_magnitude,
85 faintest_star_with_label_magnitude,shortest_constellation_line;
86 string constellation;
87 int font_size;
88 double penalties_label,penalties_star,penalties_nebula,
89 penalties_boundary,penalties_boundary_rim,penalties_cline,
90 penalties_cline_rim,penalties_threshold,penalties_rim;
91 string filename_stars,filename_nebulae,filename_dimensions,
92 filename_lines,filename_boundaries,filename_milkyway,
93 filename_preamble,filename_include;
94 string filename_output;
95 ostream*out;
96 istream*in;
97 bool input_file;
98 color bgcolor,gridcolor,eclipticcolor,boundarycolor,hlboundarycolor,
99 starcolor,nebulacolor,labelcolor,textlabelcolor,clinecolor,
100 milkywaycolor;
101 double linewidth_grid,linewidth_ecliptic,linewidth_boundary,
102 linewidth_hlboundary,linewidth_cline,linewidth_nebula;
103 string linestyle_grid,linestyle_ecliptic,linestyle_boundary,
104 linestyle_hlboundary,linestyle_cline,linestyle_nebula;
105 bool milkyway_visible,nebulae_visible,colored_stars,show_grid,
106 show_ecliptic,show_boundaries,show_lines,show_labels;
107 bool create_eps,create_pdf;
parametersparameters108 parameters():/*9:*/
109 #line 426 "pp3.w"
110 
111 center_rectascension(5.8),center_declination(0.0),
112 view_frame_width(15.0),view_frame_height(15.0),
113 grad_per_cm(4.0),
114 constellation("ORI"),font_size(10),
115 label_skip(0.06),minimal_nebula_radius(0.1),
116 faintest_cluster_magnitude(4.0),
117 faintest_diffuse_nebula_magnitude(8.0),
118 faintest_star_magnitude(7.0),star_scaling(1.0),
119 minimal_star_radius(0.015),
120 faintest_star_disk_magnitude(4.5),
121 faintest_star_with_label_magnitude(3.7),
122 shortest_constellation_line(0.1),
123 penalties_label(1.0),penalties_star(1.0),
124 penalties_nebula(1.0),penalties_boundary(1.0),
125 penalties_boundary_rim(1.0),penalties_cline(1.0),
126 penalties_cline_rim(1.0),penalties_threshold(1.0),
127 penalties_rim(1.0),
128 filename_stars(filename_prefix+"stars.dat"),
129 filename_nebulae(filename_prefix+"nebulae.dat"),
130 filename_dimensions("labeldimens.dat"),
131 filename_lines(filename_prefix+"lines.dat"),
132 filename_boundaries(filename_prefix+"boundaries.dat"),
133 filename_milkyway(filename_prefix+"milkyway.dat"),
134 filename_preamble(),filename_include(),
135 filename_output(),out(&cout),in(0),input_file(false),
136 bgcolor("bgcolor",0,0,0.4),
137 gridcolor("gridcolor",0,0.298,0.447),
138 eclipticcolor("eclipticcolor",1,0,0),
139 boundarycolor("boundarycolor",0.5,0.5,0),
140 hlboundarycolor("hlboundarycolor",1,1,0),
141 starcolor("starcolor",1,1,1),
142 nebulacolor("nebulacolor",1,1,1),
143 labelcolor("labelcolor",0,1,1),
144 textlabelcolor(1,1,0),
145 clinecolor("clinecolor",0,1,0),
146 milkywaycolor(0,0,1),
147 linewidth_grid(0.025),linewidth_ecliptic(0.018),
148 linewidth_boundary(0.035),linewidth_hlboundary(0.035),
149 linewidth_cline(0.035),linewidth_nebula(0.018),
150 linestyle_grid("solid"),linestyle_ecliptic("dashed"),
151 linestyle_boundary("dashed"),
152 linestyle_hlboundary("dashed"),linestyle_cline("solid"),
153 linestyle_nebula("solid"),
154 milkyway_visible(false),
155 nebulae_visible(true),
156 colored_stars(true),
157 show_grid(true),show_ecliptic(true),show_boundaries(true),
158 show_lines(true),show_labels(true),
159 create_eps(false),
160 create_pdf(false)
161 
162 
163 /*:9*/
164 #line 417 "pp3.w"
165 {}
view_frame_width_in_bpparameters166 int view_frame_width_in_bp(){
167 return int(ceil(view_frame_width/2.54*72));
168 }
view_frame_height_in_bpparameters169 int view_frame_height_in_bp(){
170 return int(ceil(view_frame_height/2.54*72));
171 }
172 }params;
173 
174 /*:8*//*39:*/
175 #line 1576 "pp3.w"
176 
177 typedef enum{hidden,visible,undecided}visibility;
178 
179 struct view_data{
180 visibility in_view;
181 double x,y;
182 double radius,skip;
183 visibility with_label;
184 bool label_arranged;
185 string label;
186 double label_width,label_height,label_depth;
187 bool on_baseline;
188 color label_color;
189 int label_angle;
view_dataview_data190 view_data():in_view(undecided),x(DBL_MAX),y(DBL_MAX),radius(0.0),
191 skip(params.label_skip),
192 with_label(undecided),label_arranged(false),label(),
193 label_width(0.0),label_height(0.0),
194 label_depth(0.0),on_baseline(false),
195 label_color(params.labelcolor),label_angle(0){}
196 void get_label_boundaries(double&left,double&right,double&top,
197 double&bottom)const;
scopeview_data198 double scope()const{return radius+skip+
199 my_fmax(label_width,label_height)+2.0*skip;}
has_valid_coordinatesview_data200 bool has_valid_coordinates()const{return x!=DBL_MAX&&y!=DBL_MAX;}
201 virtual double penalties_with(const double left,const double right,
202 const double top,const double bottom,
203 bool core= true)const;
204 };
205 
206 /*:39*//*40:*/
207 #line 1610 "pp3.w"
208 
209 typedef vector<view_data*> objects_list;
210 
211 /*:40*//*41:*/
212 #line 1622 "pp3.w"
213 
get_label_boundaries(double & left,double & right,double & top,double & bottom) const214 void view_data::get_label_boundaries(double&left,double&right,double&top,
215 double&bottom)const{
216 const double origin_x=
217 x+(radius+skip)*cos(M_PI_4*double(label_angle));
218 const double origin_y=
219 y+(radius+skip)*sin(M_PI_4*double(label_angle));
220 switch(label_angle){
221 case 0:case 1:case 7:left= origin_x;break;
222 case 2:case 6:left= origin_x-label_width/2.0;break;
223 case 3:case 4:case 5:left= origin_x-label_width;break;
224 }
225 right= left+label_width;
226 switch(label_angle){
227 case 0:case 4:bottom= origin_y-
228 (on_baseline?0.0:label_height/2.0);break;
229 case 1:case 2:case 3:bottom= origin_y;break;
230 case 5:case 6:case 7:bottom= origin_y-label_height;break;
231 }
232 if(on_baseline)bottom-= label_depth;
233 top= bottom+label_height;
234 }
235 
236 /*:41*//*42:*/
237 #line 1650 "pp3.w"
238 
penalties_with(const double left,const double right,const double top,const double bottom,bool core) const239 double view_data::penalties_with(const double left,const double right,
240 const double top,const double bottom,
241 bool core)const{
242 if(with_label==visible&&label_arranged){
243 double left2,right2,top2,bottom2;
244 get_label_boundaries(left2,right2,top2,bottom2);
245 const double overlap_left= my_fmax(left,left2);
246 const double overlap_right= my_fmin(right,right2);
247 const double overlap_top= my_fmin(top,top2);
248 const double overlap_bottom= my_fmax(bottom,bottom2);
249 const double overlap_x= my_fdim(overlap_right,overlap_left);
250 const double overlap_y= my_fdim(overlap_top,overlap_bottom);
251 return overlap_x*overlap_y*params.penalties_label;
252 }else return 0.0;
253 }
254 
255 /*:42*//*44:*/
256 #line 1703 "pp3.w"
257 
258 struct star:public view_data{
259 int hd,bs;
260 double rectascension,declination;
261 double magnitude;
262 double b_v;
263 int flamsteed;
264 string name;
265 string constellation;
266 string spectral_class;
starstar267 star():hd(0),bs(0),rectascension(0.0),declination(0.0),
268 magnitude(0.0),b_v(0.0),flamsteed(0),name(""),
269 spectral_class(""),view_data(){}
270 virtual double penalties_with(const double left,const double right,
271 const double top,const double bottom,
272 bool core= true)const;
273 };
274 
275 /*:44*//*45:*/
276 #line 1727 "pp3.w"
277 
penalties_with(const double left,const double right,const double top,const double bottom,bool core) const278 double star::penalties_with(const double left,const double right,
279 const double top,const double bottom,
280 bool core)const{
281 double penalties= view_data::penalties_with(left,right,top,bottom,
282 core);
283 const double left2= x-radius,right2= x+radius,top2= y+radius,
284 bottom2= y-radius;
285 const double overlap_left= my_fmax(left,left2);
286 const double overlap_right= my_fmin(right,right2);
287 const double overlap_top= my_fmin(top,top2);
288 const double overlap_bottom= my_fmax(bottom,bottom2);
289 const double overlap_x= my_fdim(overlap_right,overlap_left);
290 const double overlap_y= my_fdim(overlap_top,overlap_bottom);
291 penalties+= overlap_x*overlap_y*params.penalties_star;
292 return penalties;
293 }
294 
295 
296 typedef vector<star> stars_list;
297 
298 /*:45*//*46:*/
299 #line 1770 "pp3.w"
300 
operator >>(istream & in,star & s)301 istream&operator>>(istream&in,star&s){
302 in>>s.hd>>s.bs>>s.rectascension
303 >>s.declination>>s.magnitude>>s.b_v
304 >>s.flamsteed;
305 char ch;
306 do in.get(ch);while(in&&ch!='\n');
307 getline(in,s.name);
308 getline(in,s.constellation);
309 getline(in,s.spectral_class);
310 return in;
311 }
312 
313 /*:46*//*47:*/
314 #line 1786 "pp3.w"
315 
read_stars(stars_list & stars)316 void read_stars(stars_list&stars){
317 ifstream stars_file(params.filename_stars.c_str());
318 if(!stars_file)throw string("No stars file found: "
319 +params.filename_stars);
320 star current_star;
321 stars_file>>current_star;
322 while(stars_file){
323 current_star.label= string("\\Starname{")+current_star.name+'}';
324 stars.push_back(current_star);
325 stars_file>>current_star;
326 }
327 }
328 
329 
330 /*:47*//*48:*/
331 #line 1805 "pp3.w"
332 
333 typedef enum{unknown,galaxy,emission,reflection,open_cluster,
334 globular_cluster}nebula_kind;
335 
336 /*:48*//*49:*/
337 #line 1823 "pp3.w"
338 
339 struct nebula:public view_data{
340 int ngc,ic,messier;
341 string constellation;
342 double rectascension,declination;
343 double magnitude;
344 double diameter_x,diameter_y;
345 double horizontal_angle;
346 nebula_kind kind;
nebulanebula347 nebula():ngc(0),ic(0),messier(0),constellation(),rectascension(0.0),
348 declination(0.0),magnitude(0.0),diameter_x(0.0),
349 diameter_y(0.0),horizontal_angle(0.0),kind(unknown){}
350 virtual double penalties_with(const double left,const double right,
351 const double top,const double bottom,
352 bool core= true)const;
353 };
354 
355 typedef vector<nebula> nebulae_list;
356 
357 /*:49*//*50:*/
358 #line 1848 "pp3.w"
359 
penalties_with(const double left,const double right,const double top,const double bottom,bool core) const360 double nebula::penalties_with(const double left,const double right,
361 const double top,const double bottom,
362 bool core)const{
363 double penalties= view_data::penalties_with(left,right,top,bottom,core);
364 const double left2= x-radius,right2= x+radius,top2= y+radius,
365 bottom2= y-radius;
366 const double overlap_left= my_fmax(left,left2);
367 const double overlap_right= my_fmin(right,right2);
368 const double overlap_top= my_fmin(top,top2);
369 const double overlap_bottom= my_fmax(bottom,bottom2);
370 const double overlap_x= my_fdim(overlap_right,overlap_left);
371 const double overlap_y= my_fdim(overlap_top,overlap_bottom);
372 penalties+= overlap_x*overlap_y*params.penalties_nebula;
373 return penalties;
374 }
375 
376 /*:50*//*51:*/
377 #line 1876 "pp3.w"
378 
operator >>(istream & in,nebula & n)379 istream&operator>>(istream&in,nebula&n){
380 int kind;
381 in>>n.ngc>>n.ic>>n.messier>>n.constellation>>n.rectascension
382 >>n.declination>>n.magnitude>>n.diameter_x>>n.diameter_y
383 >>n.horizontal_angle>>kind;
384 n.kind= nebula_kind(kind);
385 return in;
386 }
387 
388 /*:51*//*52:*/
389 #line 1889 "pp3.w"
390 
read_nebulae(nebulae_list & nebulae)391 void read_nebulae(nebulae_list&nebulae){
392 ifstream nebulae_file(params.filename_nebulae.c_str());
393 nebula current_nebula;
394 nebulae_file>>current_nebula;
395 while(nebulae_file){
396 /*53:*/
397 #line 1908 "pp3.w"
398 
399 string catalogue;
400 stringstream number;
401 if(current_nebula.messier> 0){
402 catalogue= "\\Messier{";
403 number<<current_nebula.messier;
404 }else if(current_nebula.ngc> 0){
405 catalogue= "\\NGC{";
406 number<<current_nebula.ngc;
407 }else if(current_nebula.ic> 0){
408 catalogue= "\\IC{";
409 number<<current_nebula.ic;
410 }else throw string("Invalid catalogue: \"")+catalogue+'"';
411 current_nebula.label= catalogue+number.str()+'}';
412 
413 
414 /*:53*/
415 #line 1895 "pp3.w"
416 
417 nebulae.push_back(current_nebula);
418 nebulae_file>>current_nebula;
419 }
420 }
421 
422 /*:52*//*54:*/
423 #line 1933 "pp3.w"
424 
425 struct point{
426 double x,y;
pointpoint427 point(const double x,const double y):x(x),y(y){}
pointpoint428 point():x(0.0),y(0.0){}
429 };
430 
431 /*:54*//*55:*/
432 #line 1955 "pp3.w"
433 
434 struct boundary{
435 vector<point> points;
436 vector<string> constellations;
437 bool belongs_to_constellation(const string constellation)const;
438 };
439 
440 typedef vector<boundary> boundaries_list;
441 
442 /*:55*//*56:*/
443 #line 1970 "pp3.w"
444 
belongs_to_constellation(const string constellation) const445 bool boundary::belongs_to_constellation(const string constellation)const{
446 for(int i= 0;i<constellations.size();i++)
447 if(constellations[i].substr(0,3)==constellation.substr(0,3))
448 return true;
449 return false;
450 }
451 
452 /*:56*//*57:*/
453 #line 1998 "pp3.w"
454 
operator >>(istream & in,boundary & p)455 istream&operator>>(istream&in,boundary&p){
456 int size;
457 in>>size;
458 if(!in.good())return in;
459 p.points.resize(size);
460 for(int i= 0;i<size;i++)
461 in>>p.points[i].x>>p.points[i].y;
462 in>>size;
463 p.constellations.resize(size);
464 for(int i= 0;i<size;i++)
465 in>>p.constellations[i];
466 return in;
467 }
468 
469 /*:57*//*58:*/
470 #line 2016 "pp3.w"
471 
read_constellation_boundaries(boundaries_list & boundaries)472 void read_constellation_boundaries(boundaries_list&boundaries){
473 ifstream boundaryfile(params.filename_boundaries.c_str());
474 boundary current_boundary;
475 boundaryfile>>current_boundary;
476 while(boundaryfile){
477 boundaries.push_back(current_boundary);
478 boundaryfile>>current_boundary;
479 }
480 }
481 
482 /*:58*//*59:*/
483 #line 2038 "pp3.w"
484 
485 struct boundary_atom:public view_data{
486 point start,end;
487 boundary_atom(point start,point end);
488 virtual double penalties_with(const double left,const double right,
489 const double top,const double bottom,
490 bool core= true)const;
491 };
492 
493 /*:59*//*60:*/
494 #line 2054 "pp3.w"
495 
boundary_atom(point start,point end)496 boundary_atom::boundary_atom(point start,point end):start(start),end(end){
497 x= (start.x+end.x)/2.0;
498 y= (start.y+end.y)/2.0;
499 radius= hypot(end.x-start.x,end.y-start.y)/2.0;
500 radius*= M_PI_2;
501 in_view= visible;
502 with_label= hidden;
503 skip= 0.0;
504 }
505 
506 /*:60*//*61:*/
507 #line 2075 "pp3.w"
508 
509 /*63:*/
510 #line 2187 "pp3.w"
511 
line_intersection(double numerator,double denominator,double zero_point,double slope,double min,double max,double & intersection)512 bool line_intersection(double numerator,double denominator,
513 double zero_point,double slope,
514 double min,double max,
515 double&intersection){
516 if(denominator==0)return false;
517 const double lambda= numerator/denominator;
518 intersection= zero_point+lambda*slope;
519 return lambda> 0.0&&lambda<1.0&&
520 intersection> min&&intersection<max;
521 }
522 
523 /*:63*/
524 #line 2076 "pp3.w"
525 
526 
penalties_with(const double left,const double right,const double top,const double bottom,bool core) const527 double boundary_atom::penalties_with(const double left,const double right,
528 const double top,const double bottom,
529 bool core)
530 const{
531 double intersection;
532 point r(end.x-start.x,end.y-start.y);
533 vector<point> intersection_points;
534 if(line_intersection(left-start.x,r.x,start.y,r.y,
535 bottom,top,intersection))
536 intersection_points.push_back(point(left,intersection));
537 if(line_intersection(right-start.x,r.x,start.y,r.y,
538 bottom,top,intersection))
539 intersection_points.push_back(point(right,intersection));
540 if(line_intersection(top-start.y,r.y,start.x,r.x,
541 left,right,intersection))
542 intersection_points.push_back(point(intersection,top));
543 if(line_intersection(bottom-start.y,r.y,start.x,r.x,
544 left,right,intersection))
545 intersection_points.push_back(point(intersection,bottom));
546 if(start.x> left&&start.x<right&&start.y> bottom&&start.y<top)
547 intersection_points.push_back(start);
548 if(end.x> left&&end.x<right&&end.y> bottom&&end.y<top)
549 intersection_points.push_back(end);
550 if(intersection_points.empty())return 0.0;
551 if(intersection_points.size()!=2){
552 cerr<<"pp3: Funny "<<intersection_points.size()
553 <<"-fold constellation boundary intersecrtion."<<endl;
554 return 0.0;
555 }
556 const double length= hypot(intersection_points[1].x-
557 intersection_points[0].x,
558 intersection_points[1].y-
559 intersection_points[0].y);
560 return(core?8.0*params.penalties_boundary:
561 0.5*params.penalties_boundary_rim)/72.27*2.54*length;
562 }
563 
564 /*:61*//*62:*/
565 #line 2133 "pp3.w"
566 
567 struct connection:public view_data{
568 point start,end;
569 int from,to;
connectionconnection570 connection(const int from,const int to)
571 :from(from),to(to),start(),end(){in_view= visible;
572 with_label= hidden;skip= 0.0;}
573 virtual double penalties_with(const double left,const double right,
574 const double top,const double bottom,
575 bool core= true)const;
576 };
577 
578 typedef vector<connection> connections_list;
579 
580 /*:62*//*64:*/
581 #line 2206 "pp3.w"
582 
penalties_with(const double left,const double right,const double top,const double bottom,bool core) const583 double connection::penalties_with(const double left,const double right,
584 const double top,const double bottom,
585 bool core)const
586 {
587 double intersection;
588 point r(end.x-start.x,end.y-start.y);
589 vector<point> intersection_points;
590 if(line_intersection(left-start.x,r.x,start.y,r.y,
591 bottom,top,intersection))
592 intersection_points.push_back(point(left,intersection));
593 if(line_intersection(right-start.x,r.x,start.y,r.y,
594 bottom,top,intersection))
595 intersection_points.push_back(point(right,intersection));
596 if(line_intersection(top-start.y,r.y,start.x,r.x,
597 left,right,intersection))
598 intersection_points.push_back(point(intersection,top));
599 if(line_intersection(bottom-start.y,r.y,start.x,r.x,
600 left,right,intersection))
601 intersection_points.push_back(point(intersection,bottom));
602 if(start.x> left&&start.x<right&&start.y> bottom&&start.y<top)
603 intersection_points.push_back(start);
604 if(end.x> left&&end.x<right&&end.y> bottom&&end.y<top)
605 intersection_points.push_back(end);
606 if(intersection_points.empty())return 0.0;
607 if(intersection_points.size()!=2){
608 cerr<<"pp3: Funny "<<intersection_points.size()
609 <<"-fold constellation line intersecrtion."<<endl;
610 return 0.0;
611 }
612 const double length= hypot(intersection_points[1].x-
613 intersection_points[0].x,
614 intersection_points[1].y-
615 intersection_points[0].y);
616 return(core?8.0*params.penalties_cline:
617 0.5*params.penalties_cline_rim)/72.27*2.54*length;
618 }
619 
620 /*:64*//*65:*/
621 #line 2255 "pp3.w"
622 
read_constellation_lines(connections_list & connections,const stars_list & stars)623 void read_constellation_lines(connections_list&connections,
624 const stars_list&stars){
625 ifstream file(params.filename_lines.c_str());
626 string from_catalogue_name,to_catalogue_name;
627 int from_catalogue_index= 0,to_catalogue_index= 0;
628 file>>to_catalogue_name;
629 while(file){
630 if(to_catalogue_name[0]=='#'){
631 string dummy;
632 getline(file,dummy);
633 }else if(to_catalogue_name==";")
634 from_catalogue_index= 0;
635 else{
636 file>>to_catalogue_index;
637 if(from_catalogue_index> 0&&to_catalogue_index> 0){
638 /*66:*/
639 #line 2283 "pp3.w"
640 
641 int from_index= -1,to_index= -1;
642 for(int i= 0;i<stars.size();i++){
643 /*67:*/
644 #line 2308 "pp3.w"
645 
646 
647 if(from_index==-1)
648 if(from_catalogue_name=="HD"){
649 if(stars[i].hd==from_catalogue_index)from_index= i;
650 }else{
651 if(from_catalogue_name==stars[i].constellation)
652 if(stars[i].flamsteed==from_catalogue_index)
653 from_index= i;
654 }else if(to_index!=-1)break;
655 
656 /*:67*/
657 #line 2286 "pp3.w"
658 
659 /*68:*/
660 #line 2323 "pp3.w"
661 
662 
663 if(to_index==-1)
664 if(to_catalogue_name=="HD"){
665 if(stars[i].hd==to_catalogue_index)to_index= i;
666 }else{
667 if(to_catalogue_name==stars[i].constellation)
668 if(stars[i].flamsteed==to_catalogue_index)
669 to_index= i;
670 }else if(from_index!=-1)break;
671 
672 
673 /*:68*/
674 #line 2287 "pp3.w"
675 
676 }
677 if(from_index==-1||to_index==-1){
678 stringstream error_message;
679 error_message<<"Unrecognised star in constellation lines: ";
680 if(from_index==0)
681 error_message<<from_catalogue_name<<' '
682 <<from_catalogue_index;
683 else
684 error_message<<to_catalogue_name<<' '
685 <<to_catalogue_index;
686 throw error_message.str();
687 }
688 connections.push_back(connection(from_index,to_index));
689 
690 /*:66*/
691 #line 2271 "pp3.w"
692 
693 }
694 from_catalogue_name= to_catalogue_name;
695 from_catalogue_index= to_catalogue_index;
696 }
697 file>>to_catalogue_name;
698 }
699 }
700 
701 /*:65*//*71:*/
702 #line 2405 "pp3.w"
703 
set(ostream & out) const704 void color::set(ostream&out)const{
705 out<<"\\newrgbcolor{dummycolor}{"<<red<<' '<<green<<' '<<blue
706 <<"}\\dummycolor\n  \\psset{linecolor=dummycolor}%\n";
707 }
708 
709 /*:71*//*72:*/
710 #line 2417 "pp3.w"
711 
operator >>(istream & in,color & c)712 istream&operator>>(istream&in,color&c){
713 in>>c.red>>c.green>>c.blue;
714 if(!in
715 ||c.red<0.0||c.red> 1.0
716 ||c.green<0.0||c.green> 1.0
717 ||c.blue<0.0||c.blue> 1.0)
718 throw string("Invalid RGB values in input script");
719 return in;
720 }
721 
722 /*:72*//*73:*/
723 #line 2432 "pp3.w"
724 
operator <<(ostream & out,const color & c)725 ostream&operator<<(ostream&out,const color&c){
726 if(c.name.empty())throw string("Cannot write unnamed color to stream");
727 out<<"\\newrgbcolor{"<<c.name<<"}{"<<c.red<<' '<<c.green
728 <<' '<<c.blue<<"}%\n";
729 return out;
730 }
731 
732 /*:73*//*74:*/
733 #line 2447 "pp3.w"
734 
interpolate_colors(const double x,const color c1,const color c2,const string new_name="")735 color interpolate_colors(const double x,const color c1,const color c2,
736 const string new_name= ""){
737 if(x<0.0||x> 1.0)throw string("Invalid x for color interpolation");
738 const double y= 1.0-x;
739 return color(new_name,
740 y*c1.red+x*c2.red,
741 y*c1.green+x*c2.green,
742 y*c1.blue+x*c2.blue);
743 }
744 
745 
746 
747 
748 
749 /*:74*//*76:*/
750 #line 2489 "pp3.w"
751 
752 class transformation{
753 double width,height,rad_per_cm;
754 double a[3][3],a_unscaled[3][3];
755 inline double stretch_factor(double z)const;
756 public:
757 transformation(const double rectascension,
758 const double declination,
759 const double width,const double height,
760 const double grad_per_cm);
761 bool polar_projection(const double rectascension,const double declination,
762 double&x,double&y)const;
get_rad_per_cm() const763 double get_rad_per_cm()const{return rad_per_cm;}
764 };
765 
766 /*:76*//*77:*/
767 #line 2562 "pp3.w"
768 
stretch_factor(const double z) const769 inline double transformation::stretch_factor(const double z)const{
770 const double zt= 1.0-z;
771 return 1.0+zt*
772 (1.0/3.0+zt*
773 (2.0/15.0+zt*
774 (2.0/35.0+zt*
775 (8.0/315.0+zt*
776 (8.0/693.0)))));
777 }
778 
779 /*:77*//*78:*/
780 #line 2587 "pp3.w"
781 
transformation(const double rectascension,const double declination,const double width,const double height,const double grad_per_cm)782 transformation::transformation(const double rectascension,
783 const double declination,
784 const double width,const double height,
785 const double grad_per_cm){
786 const double phi= -(rectascension+12)*15.0*M_PI/180.0;
787 const double delta= declination*M_PI/180.0;
788 const double alpha= -delta+M_PI_2;
789 rad_per_cm= grad_per_cm*M_PI/180.0;
790 a_unscaled[0][0]= sin(phi);
791 a_unscaled[0][1]= cos(phi);
792 a_unscaled[0][2]= 0.0;
793 a_unscaled[1][0]= cos(phi)*cos(alpha);
794 a_unscaled[1][1]= -sin(phi)*cos(alpha);
795 a_unscaled[1][2]= sin(alpha);
796 a_unscaled[2][0]= -cos(phi)*sin(alpha);
797 a_unscaled[2][1]= sin(phi)*sin(alpha);
798 a_unscaled[2][2]= cos(alpha);
799 for(int i= 0;i<3;i++)
800 for(int j= 0;j<3;j++)
801 a[i][j]= a_unscaled[i][j]/rad_per_cm;
802 transformation::width= width;
803 transformation::height= height;
804 }
805 
806 /*:78*//*79:*/
807 #line 2621 "pp3.w"
808 
polar_projection(const double rectascension,const double declination,double & x,double & y) const809 bool transformation::polar_projection(const double rectascension,
810 const double declination,
811 double&x,double&y)const{
812 const double phi= rectascension*15.0*M_PI/180.0;
813 const double delta= declination*M_PI/180.0;
814 const double cos_delta= cos(delta);
815 
816 const double x0= cos_delta*cos(phi);
817 const double y0= cos_delta*sin(phi);
818 const double z0= sin(delta);
819 
820 const double z1=
821 a_unscaled[2][0]*x0+a_unscaled[2][1]*y0+a_unscaled[2][2]*z0;
822 if(z1<-DBL_EPSILON)return false;
823 const double stretch= stretch_factor(z1);
824 const double x1= a[0][0]*x0+a[0][1]*y0;
825 const double y1= a[1][0]*x0+a[1][1]*y0+a[1][2]*z0;
826 x= x1*stretch+width/2.0;
827 y= y1*stretch+height/2.0;
828 if(x<0.0||x> width||y<0.0||y> height)return false;
829 return true;
830 }
831 
832 
833 /*:79*//*81:*/
834 #line 2669 "pp3.w"
835 
calculate_overlap(double left1,double right1,double top1,double bottom1,double left2,double right2,double top2,double bottom2)836 double calculate_overlap(double left1,double right1,double top1,
837 double bottom1,double left2,double right2,
838 double top2,double bottom2){
839 const double overlap_left= my_fmax(left1,left2);
840 const double overlap_right= my_fmin(right1,right2);
841 const double overlap_top= my_fmin(top1,top2);
842 const double overlap_bottom= my_fmax(bottom1,bottom2);
843 const double overlap_x= my_fdim(overlap_right,overlap_left);
844 const double overlap_y= my_fdim(overlap_top,overlap_bottom);
845 return overlap_x*overlap_y;
846 }
847 
848 /*:81*//*82:*/
849 #line 2690 "pp3.w"
850 
851 struct dimension{
852 double width,height,depth;
dimensiondimension853 dimension():width(0.0),height(0.0),depth(0.0){}
dimensiondimension854 dimension(const dimension&d):width(d.width),height(d.height),
855 depth(d.depth){}
856 };
857 
858 typedef map<string,dimension> dimensions_list;
859 
860 /*:82*//*83:*/
861 #line 2708 "pp3.w"
862 
863 /*122:*/
864 #line 4023 "pp3.w"
865 
create_preamble(ostream & out)866 void create_preamble(ostream&out){
867 out<<"\\documentclass["<<params.font_size<<"pt]{article}\n\n"
868 <<"\\nofiles"
869 <<"\\usepackage[dvips]{color}\n"
870 <<"\\usepackage{pstricks,pst-text}\n"
871 <<"\\newcommand*{\\DP}{.}\n"
872 <<"\\newcommand*{\\TicMark}[1]{#1}\n"
873 <<"\\newcommand*{\\Label}[1]{#1}\n"
874 <<"\\newcommand*{\\TextLabel}[1]{#1}\n"
875 <<"\\newcommand*{\\FlexLabel}[1]{#1}\n"
876 <<"\\newcommand*{\\Starname}[1]{#1}\n"
877 <<"\\newcommand*{\\Messier}[1]{M\\,#1}\n"
878 <<"\\newcommand*{\\NGC}[1]{NGC\\,#1}\n"
879 <<"\\newcommand*{\\IC}[1]{IC\\,#1}\n\n";
880 
881 if(params.filename_preamble.empty())
882 out<<"\\usepackage{mathptmx}\n"
883 <<"\\usepackage{helvet}\n"
884 <<"\\AtBeginDocument{\\sffamily}\n";
885 else out<<"\\input "<<params.filename_preamble<<'\n';
886 }
887 
888 /*:122*/
889 #line 2709 "pp3.w"
890 
891 /*89:*/
892 #line 2922 "pp3.w"
893 
recalculate_dimensions(dimensions_list & dimensions,const objects_list & objects)894 void recalculate_dimensions(dimensions_list&dimensions,
895 const objects_list&objects)
896 {
897 list<string> required_names;
898 for(int i= 0;i<objects.size();i++){
899 const string current_name= objects[i]->label;
900 if(!current_name.empty())required_names.push_back(current_name);
901 }
902 required_names.unique();
903 
904 ofstream temp_file("pp3temp.tex");
905 create_preamble(temp_file);
906 temp_file<<"\n\\begin{document}\n"
907 <<"\\newwrite\\labelsfile\n"
908 <<"\\catcode`\\_=11  % for underscores in the filename\n"
909 <<"\\immediate\\openout\\labelsfile=pp3temp.dat\n"
910 <<"\\catcode`\\_=8\n";
911 list<string> ::const_iterator p= required_names.begin();
912 while(p!=required_names.end())
913 temp_file<<"\\setbox0 = \\hbox{\\Label{"<<*(p++)
914 <<"}}\n  \\immediate\\write\\labelsfile{"
915 "\\the\\wd0s \\the\\ht0s \\the\\dp0s}\n";
916 temp_file<<"\\immediate\\closeout\\labelsfile\n\\end{document}\n";
917 temp_file.close();
918 string commandline("latex pp3temp");
919 if(params.filename_output.empty())
920 commandline+= " > pp3dump.log";
921 if(system(commandline.c_str())!=0)
922 throw string("Label dimensions calculations: LaTeX call failed: ")
923 +commandline;
924 
925 ifstream raw_labels_file("pp3temp.dat");
926 p= required_names.begin();
927 while(p!=required_names.end()){
928 string current_width,current_height,current_depth;
929 string current_name;
930 current_name= *(p++);
931 raw_labels_file>>current_width>>current_height>>current_depth;
932 current_width.substr(0,current_width.length()-3);
933 current_height.substr(0,current_height.length()-3);
934 current_depth.substr(0,current_depth.length()-3);
935 dimensions[current_name].width= strtod(current_width.c_str(),0)
936 /72.27*2.54;
937 dimensions[current_name].height= strtod(current_height.c_str(),0)
938 /72.27*2.54;
939 dimensions[current_name].depth= strtod(current_depth.c_str(),0)
940 /72.27*2.54;
941 dimensions[current_name].height+= dimensions[current_name].depth;
942 }
943 
944 /*90:*/
945 #line 2980 "pp3.w"
946 
947 ofstream cooked_labels_file("labeldimens.dat");
948 cooked_labels_file.setf(ios::fixed);
949 cooked_labels_file.precision(5);
950 dimensions_list::const_iterator q= dimensions.begin();
951 while(q!=dimensions.end()){
952 string current_name;
953 dimension current_dimension;
954 current_name= q->first;
955 current_dimension= (q++)->second;
956 cooked_labels_file<<current_name<<'\n'
957 <<current_dimension.width<<' '
958 <<current_dimension.height<<' '
959 <<current_dimension.depth
960 <<'\n';
961 }
962 
963 
964 /*:90*/
965 #line 2973 "pp3.w"
966 
967 }
968 
969 /*:89*/
970 #line 2710 "pp3.w"
971 
972 
arrange_labels(objects_list & objects,dimensions_list & dimensions)973 void arrange_labels(objects_list&objects,dimensions_list&dimensions){
974 objects_list vicinity;
975 /*88:*/
976 #line 2874 "pp3.w"
977 
978 bool dimensions_recalculated= false;
979 for(int i= 0;i<objects.size();i++){
980 view_data*current_object= objects[i];
981 if(current_object->with_label==visible){
982 if(!dimensions_recalculated&&
983 dimensions.find(current_object->label)==dimensions.end()){
984 recalculate_dimensions(dimensions,objects);
985 dimensions_recalculated= true;
986 if(dimensions.find(current_object->label)==dimensions.end())
987 throw string("Update of label dimensions file failed: \"")+
988 current_object->label+"\" not found";
989 }
990 current_object->label_width= dimensions[current_object->label].width;
991 current_object->label_height=
992 dimensions[current_object->label].height;
993 current_object->label_depth= dimensions[current_object->label].depth;
994 }
995 }
996 
997 
998 /*:88*/
999 #line 2714 "pp3.w"
1000 
1001 for(int i= 0;i<objects.size();i++){
1002 vicinity.clear();
1003 if(objects[i]->in_view==visible&&objects[i]->with_label==visible
1004 &&!objects[i]->label_arranged){
1005 /*84:*/
1006 #line 2790 "pp3.w"
1007 
1008 const double on_object_scope= objects[i]->scope();
1009 for(int j= 0;j<objects.size();j++){
1010 if(i!=j&&objects[j]->in_view==visible){
1011 const double distance=
1012 hypot(objects[i]->x-objects[j]->x,
1013 objects[i]->y-objects[j]->y);
1014 if(distance<on_object_scope+objects[j]->scope()&&
1015 /*85:*/
1016 #line 2803 "pp3.w"
1017 
1018 (distance> objects[j]->skip||
1019 (objects[j]->with_label==visible&&!objects[j]->label.empty()))
1020 
1021 /*:85*/
1022 #line 2798 "pp3.w"
1023 )
1024 vicinity.push_back(objects[j]);
1025 }
1026 }
1027 
1028 /*:84*/
1029 #line 2719 "pp3.w"
1030 
1031 double best_penalty= DBL_MAX;
1032 int best_angle= 0;
1033 for(int k= 0;k<8;k++){
1034 objects[i]->label_angle= k;
1035 double on_object_left,on_object_right,on_object_top,
1036 on_object_bottom;
1037 objects[i]->
1038 get_label_boundaries(on_object_left,on_object_right,
1039 on_object_top,on_object_bottom);
1040 double penalty= 0.0;
1041 double rim_width= 2.0*objects[i]->skip;
1042 for(int j= 0;j<vicinity.size();j++){
1043 penalty+= vicinity[j]->
1044 penalties_with(on_object_left,on_object_right,
1045 on_object_top,on_object_bottom)+
1046 vicinity[j]->
1047 penalties_with(on_object_left-rim_width,
1048 on_object_right+rim_width,
1049 on_object_top+rim_width,
1050 on_object_bottom-rim_width,
1051 false)*params.penalties_rim;
1052 }
1053 if(on_object_left<0.0||on_object_bottom<0.0||
1054 on_object_right> params.view_frame_width||
1055 on_object_top> params.view_frame_height)
1056 penalty+= 10000.0;
1057 if(penalty<best_penalty){
1058 best_penalty= penalty;
1059 best_angle= k;
1060 }
1061 }
1062 if(!objects[i]->label.empty())
1063 if(best_penalty<0.4*params.penalties_threshold*
1064 objects[i]->label_height*objects[i]->label_width){
1065 objects[i]->label_angle= best_angle;
1066 objects[i]->label_arranged= true;
1067 #ifdef DEBUG
1068 stringstream penalty;
1069 penalty.precision(2);
1070 penalty<<" "<<best_penalty<<" ("
1071 <<best_penalty/
1072 (objects[i]->label_height*objects[i]->label_width)
1073 *100<<"%)";
1074 
1075 cerr<<"pp3DEBUG: Object "<<objects[i]->label<<' ';
1076 const star*s= dynamic_cast<star*> (objects[i]);
1077 if(s)cerr<<s->constellation;
1078 cerr<<" has penalty of"<<penalty.str()<<endl;
1079 #endif
1080 }else{
1081 objects[i]->with_label= hidden;
1082 objects[i]->label_arranged= true;
1083 }
1084 }
1085 }
1086 }
1087 
1088 /*:83*//*86:*/
1089 #line 2813 "pp3.w"
1090 
print_labels(const objects_list & objects)1091 void print_labels(const objects_list&objects){
1092 for(int i= 0;i<objects.size();i++)
1093 if(objects[i]->in_view==visible&&objects[i]->with_label==visible
1094 &&objects[i]->label_arranged){
1095 double left,right,top,bottom;
1096 objects[i]->get_label_boundaries(left,right,top,bottom);
1097 if(left<0.0||bottom<0.0||right> params.view_frame_width
1098 ||top> params.view_frame_height)continue;
1099 
1100 objects[i]->label_color.set(OUT);
1101 OUT<<"\\hbox to 0pt{";
1102 OUT<<"\\hskip"<<left<<"cm";
1103 OUT<<"\\vbox to 0pt{\\vss\n  \\hbox{\\Label{";
1104 OUT<<objects[i]->label;
1105 OUT<<"}}\\vskip"<<bottom<<"cm";
1106 OUT<<"\\hrule height 0pt}\\hss}%\n";
1107 #ifdef DEBUG
1108 OUT<<"\\psframe[linewidth=0.1pt]("<<left<<','<<bottom
1109 <<")("<<right<<','<<bottom+objects[i]->label_depth<<")%\n";
1110 OUT<<"\\psframe[linewidth=0.3pt]("<<left<<','<<bottom
1111 <<")("<<right<<','<<top<<")%\n";
1112 #endif
1113 }
1114 }
1115 
1116 /*:86*//*87:*/
1117 #line 2848 "pp3.w"
1118 
read_label_dimensions(dimensions_list & dimensions)1119 void read_label_dimensions(dimensions_list&dimensions){
1120 ifstream file(params.filename_dimensions.c_str());
1121 string name,dummy;
1122 getline(file,name);
1123 while(file){
1124 file>>dimensions[name].width>>dimensions[name].height
1125 >>dimensions[name].depth;
1126 getline(file,dummy);
1127 getline(file,name);
1128 }
1129 }
1130 
1131 /*:87*//*91:*/
1132 #line 3005 "pp3.w"
1133 
1134 struct text:public view_data{
1135 string contents;
1136 double rectascension,declination;
1137 text(string t,double r,double d,color c,int angle,bool on_baseline);
1138 };
1139 
1140 typedef list<text> texts_list;
1141 
1142 /*:91*//*92:*/
1143 #line 3020 "pp3.w"
1144 
text(string t,double r,double d,color c,int angle,bool on_baseline)1145 text::text(string t,double r,double d,color c,int angle,bool on_baseline)
1146 :contents(t),rectascension(r),declination(d){
1147 label= string("\\TextLabel{")+t+'}';
1148 with_label= visible;
1149 label_angle= angle;
1150 view_data::on_baseline= on_baseline;
1151 label_arranged= true;
1152 label_color= c;
1153 radius= skip= 0.0;
1154 }
1155 
1156 /*:92*//*93:*/
1157 #line 3037 "pp3.w"
1158 
draw_text_labels(transformation & mytransform,texts_list & texts,objects_list & objects)1159 void draw_text_labels(transformation&mytransform,texts_list&texts,
1160 objects_list&objects){
1161 texts_list::iterator p= texts.begin();
1162 while(p!=texts.end()){
1163 double x,y;
1164 if(mytransform.polar_projection(p->rectascension,
1165 p->declination,
1166 x,y)){
1167 p->in_view= visible;
1168 p->x= x;
1169 p->y= y;
1170 objects.push_back(&(*p));
1171 }
1172 p++;
1173 }
1174 }
1175 
1176 /*:93*//*94:*/
1177 #line 3075 "pp3.w"
1178 
1179 struct flex_label:public view_data{
1180 double rectascension,declination;
1181 flex_label(string s,double r,double d,color c,int a,bool b);
1182 virtual bool draw(const transformation&mytransform,
1183 dimensions_list&dimensions,objects_list&objects)
1184 const= 0;
1185 };
1186 
1187 /*:94*//*95:*/
1188 #line 3091 "pp3.w"
1189 
flex_label(string s,double r,double d,color c,int a,bool b)1190 flex_label::flex_label(string s,double r,double d,color c,int a,bool b)
1191 :rectascension(r),declination(d){
1192 label_color= c;
1193 label= string("\\FlexLabel{")+s+'}';
1194 label_angle= a;
1195 on_baseline= b;
1196 in_view= visible;
1197 with_label= hidden;
1198 label_arranged= true;
1199 }
1200 
1201 typedef list<flex_label*> flexes_list;
1202 
1203 /*:95*//*96:*/
1204 #line 3108 "pp3.w"
1205 
1206 struct declination_flex:public flex_label{
declination_flexdeclination_flex1207 declination_flex(string s,double r,double d,color c,int a,bool b)
1208 :flex_label(s,r,d,c,a,b){}
1209 virtual bool draw(const transformation&mytransform,
1210 dimensions_list&dimensions,objects_list&objects)
1211 const;
1212 virtual double penalties_with(const double left,const double right,
1213 const double top,const double bottom,
1214 bool core= true)const;
1215 };
1216 
1217 /*:96*//*97:*/
1218 #line 3139 "pp3.w"
1219 
draw(const transformation & mytransform,dimensions_list & dimensions,objects_list & objects) const1220 bool declination_flex::draw(const transformation&mytransform,
1221 dimensions_list&dimensions,
1222 objects_list&objects)const{
1223 if(dimensions.find(label)==dimensions.end())
1224 recalculate_dimensions(dimensions,objects);
1225 if(dimensions.find(label)==dimensions.end())
1226 throw string("Update of label dimensions file failed: \"")+
1227 label+"\" not found";
1228 const double label_width= dimensions[label].width;
1229 const double label_height= dimensions[label].height;
1230 const double rectascension_halfwidth= label_width
1231 *mytransform.get_rad_per_cm()*180.0/M_PI/15.0
1232 /cos(declination*M_PI/180.0)/2.0;
1233 char justification;
1234 double path_point_rectascension[3];
1235 path_point_rectascension[0]= rectascension;
1236 path_point_rectascension[1]= rectascension-rectascension_halfwidth;
1237 path_point_rectascension[2]= rectascension-
1238 2.0*rectascension_halfwidth;
1239 switch(label_angle){
1240 case 0:case 1:case 7:
1241 justification= 'l';
1242 break;
1243 case 2:case 6:
1244 justification= 'c';
1245 for(int i= 0;i<3;i++)
1246 path_point_rectascension[i]+= rectascension_halfwidth;
1247 break;
1248 case 3:case 4:case 5:
1249 justification= 'r';
1250 for(int i= 0;i<3;i++)
1251 path_point_rectascension[i]+= 2.0*rectascension_halfwidth;
1252 break;
1253 }
1254 double lower;
1255 switch(label_angle){
1256 case 0:case 4:lower= -0.4;break;
1257 case 1:case 2:case 3:lower= 0.0;break;
1258 case 5:case 6:case 7:lower= -0.8;break;
1259 }
1260 double x[3],y[3];
1261 for(int i= 0;i<3;i++)
1262 if(!mytransform.polar_projection(path_point_rectascension[i],
1263 declination,x[i],y[i]))
1264 return false;
1265 
1266 label_color.set(OUT);
1267 OUT<<"\\Label{\\pstextpath["<<justification
1268 <<"](0,"<<lower<<"em){\\pscurve[linestyle=none]%\n  ";
1269 for(int i= 0;i<3;i++)
1270 OUT<<'('<<x[i]<<"cm,"<<y[i]<<"cm)";
1271 OUT<<"}{\\dummycolor"<<label<<"}}%\n";
1272 
1273 return true;
1274 }
1275 
1276 /*:97*//*98:*/
1277 #line 3199 "pp3.w"
1278 
penalties_with(const double left,const double right,const double top,const double bottom,bool core) const1279 double declination_flex::penalties_with(const double left,const double right,
1280 const double top,const double bottom,
1281 bool core)const{
1282 return 0.0;
1283 }
1284 
1285 /*:98*//*99:*/
1286 #line 3214 "pp3.w"
1287 
draw_flex_labels(const transformation & mytransform,const flexes_list & flexes,objects_list & objects,dimensions_list & dimensions)1288 void draw_flex_labels(const transformation&mytransform,
1289 const flexes_list&flexes,objects_list&objects,
1290 dimensions_list&dimensions){
1291 flexes_list::const_iterator p= flexes.begin();
1292 while(p!=flexes.end())objects.push_back(*p++);
1293 p= flexes.begin();
1294 while(p!=flexes.end())(*p++)->draw(mytransform,dimensions,objects);
1295 }
1296 
1297 /*:99*//*100:*/
1298 #line 3239 "pp3.w"
1299 
1300 /*101:*/
1301 #line 3290 "pp3.w"
1302 
create_hs_colour(double b_v,string spectral_class)1303 void create_hs_colour(double b_v,string spectral_class){
1304 double hue,saturation;
1305 const double bv0= -0.1,bv1= 0.001,bv2= 0.62,bv3= 1.7;
1306 const double hue0= 0.6,hue1= 0.47,hue2= 0.17,hue3= 0.0;
1307 const double min_saturation= 0.0,max_saturation= 0.2;
1308 /*102:*/
1309 #line 3325 "pp3.w"
1310 
1311 if(b_v> 90.0){
1312 switch(spectral_class[0]){
1313 case'O':b_v= 0.0;break;
1314 case'B':b_v= -0.07;break;
1315 case'A':b_v= 0.11;break;
1316 case'F':b_v= 0.43;break;
1317 case'G':b_v= 0.89;break;
1318 case'K':b_v= 1.24;break;
1319 case'M':b_v= 1.62;break;
1320 case'N':b_v= 2.88;break;
1321 case'S':b_v= 1.84;break;
1322 case'C':b_v= 3.02;break;
1323 default:b_v= 0.0;break;
1324 }
1325 }
1326 
1327 
1328 /*:102*/
1329 #line 3296 "pp3.w"
1330 
1331 if(b_v<bv0)b_v= bv0;
1332 if(b_v> bv3)b_v= bv3;
1333 if(b_v<bv1){
1334 hue= (b_v-bv0)/(bv1-bv0)
1335 *(hue1-hue0)+hue0;
1336 saturation= (b_v-bv0)/(bv1-bv0)
1337 *(min_saturation-max_saturation)+max_saturation;
1338 }
1339 else if(b_v<bv2){
1340 hue= 0.3;
1341 saturation= 0;
1342 }
1343 else{
1344 hue= (b_v-bv2)/(bv3-bv2)
1345 *(hue3-hue2)+hue2;
1346 saturation= (b_v-bv2)/(bv3-bv2)
1347 *(max_saturation-min_saturation)+min_saturation;
1348 }
1349 OUT<<hue<<' '<<saturation;
1350 }
1351 
1352 /*:101*/
1353 #line 3240 "pp3.w"
1354 
1355 
draw_stars(const transformation & mytransform,stars_list & stars,objects_list & objects)1356 void draw_stars(const transformation&mytransform,stars_list&stars,
1357 objects_list&objects){
1358 for(int i= 0;i<stars.size();i++)
1359 if(stars[i].in_view!=hidden&&
1360 stars[i].magnitude<params.faintest_star_magnitude){
1361 
1362 if(mytransform.polar_projection(stars[i].rectascension,
1363 stars[i].declination,
1364 stars[i].x,stars[i].y)){
1365 stars[i].in_view= visible;
1366 const double m_dot= params.faintest_star_disk_magnitude;
1367 const double r_min= params.minimal_star_radius/
1368 params.star_scaling;
1369 stars[i].radius= params.star_scaling*
1370 (stars[i].magnitude<m_dot?
1371 sqrt((m_dot-stars[i].magnitude)/300.0+r_min*r_min)
1372 :r_min);
1373 if(stars[i].with_label==undecided)
1374 stars[i].with_label=
1375 (stars[i].magnitude<
1376 params.faintest_star_with_label_magnitude&&
1377 !stars[i].name.empty())?visible:hidden;
1378 if(params.colored_stars){
1379 OUT<<"\\newhsbcolor{starcolor}{";
1380 create_hs_colour(stars[i].b_v,stars[i].spectral_class);
1381 OUT<<" 1}%\n";
1382 }else OUT<<params.starcolor;
1383 OUT<<"\\pscircle*[linecolor=starcolor]("
1384 <<stars[i].x<<","
1385 <<stars[i].y<<"){"
1386 <<stars[i].radius/2.54*72.27<<"pt}%\n";
1387 objects.push_back(&stars[i]);
1388 }else stars[i].in_view= hidden;
1389 }else stars[i].in_view= stars[i].with_label= hidden;
1390 }
1391 
1392 /*:100*//*103:*/
1393 #line 3367 "pp3.w"
1394 
draw_nebulae(const transformation & mytransform,nebulae_list & nebulae,objects_list & objects)1395 void draw_nebulae(const transformation&mytransform,nebulae_list&nebulae,
1396 objects_list&objects){
1397 OUT<<"\\psset{linecolor=nebulacolor,linewidth="
1398 <<params.linewidth_nebula<<"cm,linestyle="
1399 <<params.linestyle_nebula<<",curvature=1 .5 -1}%\n";
1400 for(int i= 0;i<nebulae.size();i++)
1401 if(nebulae[i].in_view==visible||
1402 (nebulae[i].in_view==undecided&&
1403 (((nebulae[i].kind==open_cluster||
1404 nebulae[i].kind==globular_cluster)
1405 &&nebulae[i].magnitude<params.faintest_cluster_magnitude)
1406 ||
1407 ((nebulae[i].kind==galaxy||nebulae[i].kind==reflection||
1408 nebulae[i].kind==emission)&&
1409 nebulae[i].magnitude<params.faintest_diffuse_nebula_magnitude)
1410 ||
1411 nebulae[i].messier> 0))){
1412 if(mytransform.polar_projection(nebulae[i].rectascension,
1413 nebulae[i].declination,
1414 nebulae[i].x,nebulae[i].y)){
1415 nebulae[i].in_view= visible;
1416 if(nebulae[i].horizontal_angle> 360.0)
1417 nebulae[i].diameter_x= nebulae[i].diameter_y=
1418 sqrt(nebulae[i].diameter_x*nebulae[i].diameter_y);
1419 nebulae[i].radius= nebulae[i].diameter_x/2.0/
1420 mytransform.get_rad_per_cm()*M_PI/180.0;
1421 if(nebulae[i].with_label!=hidden)
1422 nebulae[i].with_label= visible;
1423 if(nebulae[i].radius> params.minimal_nebula_radius){
1424 /*104:*/
1425 #line 3424 "pp3.w"
1426 
1427 if(nebulae[i].diameter_x==nebulae[i].diameter_y)
1428 OUT<<"\\pscircle("<<nebulae[i].x<<','<<nebulae[i].y
1429 <<"){"<<nebulae[i].radius<<"}%\n";
1430 else{
1431 double rectascension[4],declination[4];
1432 const double r_scale= 1.0/cos(nebulae[i].declination*M_PI/180.0);
1433 const double cos_angle
1434 = cos(nebulae[i].horizontal_angle*M_PI/180.0);
1435 const double sin_angle
1436 = sin(nebulae[i].horizontal_angle*M_PI/180.0);
1437 const double half_x= nebulae[i].diameter_x/2.0;
1438 const double half_y= nebulae[i].diameter_y/2.0;
1439 rectascension[0]= nebulae[i].rectascension-
1440 half_x*cos_angle/15.0*r_scale;
1441 declination[0]= nebulae[i].declination-
1442 half_x*sin_angle;
1443 rectascension[1]= nebulae[i].rectascension+
1444 half_y*sin_angle/15.0*r_scale;
1445 declination[1]= nebulae[i].declination-
1446 half_y*cos_angle;
1447 rectascension[2]= nebulae[i].rectascension+
1448 half_x*cos_angle/15.0*r_scale;
1449 declination[2]= nebulae[i].declination+
1450 half_x*sin_angle;
1451 rectascension[3]= nebulae[i].rectascension-
1452 half_y*sin_angle/15.0*r_scale;
1453 declination[3]= nebulae[i].declination+
1454 half_y*cos_angle;
1455 OUT<<"\\psccurve";
1456 for(int j= 0;j<4;j++){
1457 double x,y;
1458 mytransform.polar_projection(rectascension[j],
1459 declination[j],x,y);
1460 OUT<<'('<<x<<','<<y<<')';
1461 }
1462 }
1463 OUT<<"\\relax\n";
1464 
1465 
1466 /*:104*/
1467 #line 3397 "pp3.w"
1468 
1469 }else{
1470 nebulae[i].radius= params.minimal_nebula_radius;
1471 OUT<<"\\pscircle("
1472 <<nebulae[i].x<<","
1473 <<nebulae[i].y<<"){"
1474 <<nebulae[i].radius/2.54*72.27<<"pt}%\n";
1475 }
1476 objects.push_back(&nebulae[i]);
1477 }else nebulae[i].in_view= hidden;
1478 }else nebulae[i].in_view= nebulae[i].with_label= hidden;
1479 }
1480 
1481 /*:103*//*106:*/
1482 #line 3494 "pp3.w"
1483 
add_curve_point(const double rectascension,const double declination,const transformation & transform,const int i,bool & within_curve,const int steps)1484 inline void add_curve_point(const double rectascension,
1485 const double declination,
1486 const transformation&transform,
1487 const int i,bool&within_curve,
1488 const int steps){
1489 static double last_x,last_y;
1490 double x,y;
1491 if(transform.polar_projection(rectascension,declination,x,y)){
1492 if(!within_curve){
1493 OUT<<"\\pscurve"<<"("<<x<<','<<y<<")";
1494 within_curve= true;
1495 }else if(i%steps==0)OUT<<"("<<x<<','<<y<<")";
1496 if(i%(steps*4)==0||steps==1)OUT<<"%\n";
1497 
1498 }else
1499 if(within_curve){
1500 OUT<<"("<<last_x<<','<<last_y<<")"<<"\\relax\n";
1501 within_curve= false;
1502 }
1503 last_x= x;last_y= y;
1504 }
1505 
1506 /*:106*//*107:*/
1507 #line 3539 "pp3.w"
1508 
create_grid(const transformation transform,const double scans_per_cm=10,const double point_distance=5.0)1509 void create_grid(const transformation transform,
1510 const double scans_per_cm= 10,
1511 const double point_distance= 5.0){
1512 if(!params.show_grid&&!params.show_ecliptic)return;
1513 const double scans_per_fullcircle=
1514 scans_per_cm/transform.get_rad_per_cm()*2.0*M_PI;
1515 const int steps= int((point_distance*M_PI/180.0)*
1516 (scans_per_fullcircle/(2.0*M_PI)))+2;
1517 bool within_curve;
1518 if(params.show_grid){
1519 OUT<<"\\psset{linestyle="<<params.linestyle_grid
1520 <<",linecolor=gridcolor,linewidth="
1521 <<params.linewidth_grid<<"cm}%\n";
1522 /*108:*/
1523 #line 3569 "pp3.w"
1524 
1525 for(int declination= -80;declination<=80;declination+= 10){
1526 if(declination==0)
1527 OUT<<"\\psset{linewidth="<<2.0*params.linewidth_grid
1528 <<"cm}%\n";
1529 within_curve= false;
1530 const int number_of_points=
1531 int(cos(declination*M_PI/180.0)*scans_per_fullcircle);
1532 for(int i= 0;i<=number_of_points;i++)
1533 add_curve_point(double(i)/double(number_of_points)*24.0,
1534 declination,transform,i,within_curve,
1535 i==number_of_points?1:steps);
1536 if(declination==0)
1537 OUT<<"\\psset{linewidth="<<params.linewidth_grid<<"cm}%\n";
1538 }
1539 
1540 /*:108*/
1541 #line 3553 "pp3.w"
1542 
1543 /*109:*/
1544 #line 3589 "pp3.w"
1545 
1546 const int number_of_points= int(scans_per_fullcircle/2.0);
1547 for(int rectascension= 0;rectascension<=23;rectascension++){
1548 within_curve= false;
1549 for(int i= 0;i<=number_of_points;i++)
1550 add_curve_point(double(rectascension),
1551 double(i)/double(number_of_points)*160.0-80.0,
1552 transform,i,within_curve,
1553 i==number_of_points?1:steps);
1554 }
1555 
1556 /*:109*/
1557 #line 3554 "pp3.w"
1558 
1559 }
1560 if(params.show_ecliptic){
1561 /*110:*/
1562 #line 3617 "pp3.w"
1563 
1564 OUT<<"\\psset{linestyle="<<params.linestyle_ecliptic
1565 <<",linecolor=eclipticcolor,"
1566 <<"linewidth="<<params.linewidth_ecliptic<<"cm}%\n";
1567 {
1568 const double epsilon= 23.44*M_PI/180.0;
1569 const int number_of_points= int(scans_per_fullcircle);
1570 within_curve= false;
1571 for(int i= 0;i<=number_of_points;i++){
1572 const double phi0= double(i)/double(number_of_points)*2.0*M_PI;
1573 const double m_sin_phi0= -sin(phi0);
1574 const double phi= atan2(m_sin_phi0*cos(epsilon),cos(phi0));
1575 const double delta= asin(m_sin_phi0*sin(epsilon));
1576 add_curve_point(phi*12.0/M_PI,delta*180.0/M_PI,
1577 transform,i,within_curve,
1578 i==number_of_points?1:steps);
1579 }
1580 }
1581 
1582 /*:110*/
1583 #line 3557 "pp3.w"
1584 
1585 }
1586 }
1587 
1588 /*:107*//*112:*/
1589 #line 3656 "pp3.w"
1590 
draw_boundary_line(const boundary & b,const transformation & transform,objects_list & objects,bool highlighted=false)1591 void draw_boundary_line(const boundary&b,const transformation&transform,
1592 objects_list&objects,bool highlighted= false){
1593 vector<point> current_line;
1594 for(int j= 0;j<b.points.size();j++){
1595 const double rectascension= b.points[j].x;
1596 const double declination= b.points[j].y;
1597 double x,y;
1598 if(!transform.polar_projection(rectascension,declination,x,y))
1599 continue;
1600 current_line.push_back(point(x,y));
1601 }
1602 if(current_line.size()>=2){
1603 if(current_line.size()==2)OUT<<"\\psline";
1604 else OUT<<"\\pscurve";
1605 OUT<<"[liftpen=2]{c-c}";
1606 for(int j= 0;j<current_line.size();j++){
1607 OUT<<'('<<current_line[j].x<<','
1608 <<current_line[j].y<<')';
1609 if(j%4==3)OUT<<"%\n";
1610 if(highlighted)
1611 /*113:*/
1612 #line 3688 "pp3.w"
1613 
1614 if(j> 0)objects.push_back(new boundary_atom(current_line[j],
1615 current_line[j-1]));
1616 
1617 /*:113*/
1618 #line 3677 "pp3.w"
1619 
1620 }
1621 OUT<<"\\relax\n";
1622 }
1623 }
1624 
1625 /*:112*//*114:*/
1626 #line 3704 "pp3.w"
1627 
draw_boundaries(const transformation & mytransform,boundaries_list & boundaries,objects_list & objects,string constellation=string (""))1628 void draw_boundaries(const transformation&mytransform,
1629 boundaries_list&boundaries,
1630 objects_list&objects,
1631 string constellation= string("")){
1632 OUT<<"\\psset{linecolor=boundarycolor,linewidth="
1633 <<params.linewidth_boundary<<"cm,"
1634 <<"linestyle="<<params.linestyle_boundary<<"}%\n";
1635 if(!constellation.empty()){
1636 for(int i= 0;i<boundaries.size();i++)
1637 if(!boundaries[i].belongs_to_constellation(constellation))
1638 draw_boundary_line(boundaries[i],mytransform,objects);
1639 OUT<<"\\psset{linecolor=hlboundarycolor,linewidth="
1640 <<params.linewidth_boundary<<"cm,"<<"linestyle="
1641 <<params.linestyle_hlboundary<<"}%\n";
1642 OUT<<"\\pscustom{";
1643 for(int i= 0;i<boundaries.size();i++)
1644 if(boundaries[i].belongs_to_constellation(constellation))
1645 draw_boundary_line(boundaries[i],mytransform,objects,true);
1646 OUT<<"}%\n";
1647 }else
1648 for(int i= 0;i<boundaries.size();i++)
1649 draw_boundary_line(boundaries[i],mytransform,objects);
1650 }
1651 
1652 /*:114*//*115:*/
1653 #line 3746 "pp3.w"
1654 
draw_constellation_lines(connections_list & connections,const stars_list & stars,objects_list & objects)1655 void draw_constellation_lines(connections_list&connections,
1656 const stars_list&stars,
1657 objects_list&objects){
1658 OUT<<"\\psset{linecolor=clinecolor,linestyle="<<params.linestyle_cline
1659 <<",linewidth="<<params.linewidth_cline<<"cm}%\n";
1660 for(int i= 0;i<connections.size();i++)
1661 if((stars[connections[i].from].in_view==visible||
1662 stars[connections[i].to].in_view==visible)
1663 &&stars[connections[i].from].has_valid_coordinates()
1664 &&stars[connections[i].to].has_valid_coordinates()){
1665 double x1= stars[connections[i].from].x;
1666 double y1= stars[connections[i].from].y;
1667 double x2= stars[connections[i].to].x;
1668 double y2= stars[connections[i].to].y;
1669 const double phi= atan2(y2-y1,x2-x1);
1670 double r= hypot(x2-x1,y2-y1);
1671 double skip;
1672 skip= stars[connections[i].from].radius+
1673 stars[connections[i].from].skip;
1674 r-= skip;
1675 x1+= skip*cos(phi);
1676 y1+= skip*sin(phi);
1677 skip= stars[connections[i].to].radius+
1678 stars[connections[i].to].skip;
1679 r-= skip;
1680 x2-= skip*cos(phi);
1681 y2-= skip*sin(phi);
1682 connections[i].radius= r/2.0;
1683 connections[i].x= (x1+x2)/2.0;
1684 connections[i].y= (y1+y2)/2.0;
1685 if(r> params.shortest_constellation_line&&r> 0.0){
1686 OUT<<"\\psline{cc-cc}("<<x1<<','<<y1
1687 <<")("<<x2<<','<<y2<<")%\n";
1688 connections[i].start= point(x1,y1);
1689 connections[i].end= point(x2,y2);
1690 objects.push_back(&connections[i]);
1691 }
1692 }
1693 
1694 }
1695 
1696 
1697 /*:115*//*116:*/
1698 #line 3807 "pp3.w"
1699 
draw_milky_way(const transformation & mytransform)1700 void draw_milky_way(const transformation&mytransform){
1701 vector<vector<point> > pixels(256);
1702 /*69:*/
1703 #line 2361 "pp3.w"
1704 
1705 ifstream file(params.filename_milkyway.c_str());
1706 double radius;
1707 file>>radius;
1708 double rectascension,declination,x,y;
1709 int pixel;
1710 const double cm_per_grad= 1.0/
1711 (mytransform.get_rad_per_cm()*180.0/M_PI);
1712 radius*= cm_per_grad/2.54*72.27;
1713 file>>rectascension>>declination>>pixel;
1714 while(file){
1715 if(mytransform.polar_projection(rectascension,declination,x,y))
1716 pixels[pixel].push_back(point(x,y));
1717 file>>rectascension>>declination>>pixel;
1718 }
1719 
1720 
1721 /*:69*/
1722 #line 3810 "pp3.w"
1723 
1724 for(int i= 1;i<pixels.size();i++){
1725 if(pixels[i].size()==0)continue;
1726 interpolate_colors(double(i)/255.0,params.bgcolor,
1727 params.milkywaycolor).set(OUT);
1728 for(int j= 0;j<pixels[i].size();j++)
1729 OUT<<"\\qdisk("<<pixels[i][j].x<<","<<pixels[i][j].y
1730 <<"){"<<radius<<"pt}%\n";
1731 }
1732 }
1733 
1734 
1735 /*:116*//*117:*/
1736 #line 3837 "pp3.w"
1737 
1738 /*11:*/
1739 #line 496 "pp3.w"
1740 
read_boolean(istream & script)1741 bool read_boolean(istream&script){
1742 string boolean;
1743 script>>boolean;
1744 if(boolean=="on")return true;
1745 else if(boolean=="off")return false;
1746 else throw string("Expected \"on\" or \"off\" in \"switch\" construct "
1747 "in input script");
1748 }
1749 
1750 /*:11*//*12:*/
1751 #line 518 "pp3.w"
1752 
read_string(istream & script)1753 string read_string(istream&script){
1754 const string UnexpectedEOS("Unexpected end of input script while reading a"
1755 " string parameter");
1756 char c;
1757 string contents;
1758 while(script.get(c))if(!isspace(c))break;
1759 if(!script)throw UnexpectedEOS;
1760 if(c!='"'){
1761 script>>contents;
1762 if(script)contents.insert(contents.begin(),c);else contents= c;
1763 }else{
1764 while(script.get(c)){
1765 if(c=='"')break;
1766 if(c=='\\'){
1767 if(!script.get(c))
1768 throw UnexpectedEOS;
1769 switch(c){
1770 case'\\':case'"':contents+= c;break;
1771 default:throw string("Unknown escape sequence in string");
1772 }
1773 }else contents+= c;
1774 }
1775 if(!script)
1776 throw UnexpectedEOS;
1777 }
1778 return contents;
1779 }
1780 
1781 /*:12*//*13:*/
1782 #line 559 "pp3.w"
1783 
1784 void read_parameters_from_script(istream&script){
1785 string opcode;
1786 script>>opcode;
1787 while(opcode!="objects_and_labels"&&script){
1788 if(opcode[0]=='#'){
1789 string rest_of_line;
1790 getline(script,rest_of_line);
1791 }else
1792 /*14:*/
1793 #line 609 "pp3.w"
1794 
1795 if(opcode=="color"){
1796 string color_name;
1797 script>>color_name;
1798 if(color_name=="background")script>>params.bgcolor;
1799 else if(color_name=="grid")script>>params.gridcolor;
1800 else if(color_name=="ecliptic")script>>params.eclipticcolor;
1801 else if(color_name=="boundaries")
1802 script>>params.boundarycolor;
1803 else if(color_name=="highlighted_boundaries")
1804 script>>params.hlboundarycolor;
1805 else if(color_name=="stars")script>>params.starcolor;
1806 else if(color_name=="nebulae")script>>params.nebulacolor;
1807 else if(color_name=="labels")script>>params.labelcolor;
1808 else if(color_name=="text_labels")
1809 script>>params.textlabelcolor;
1810 else if(color_name=="constellation_lines")
1811 script>>params.clinecolor;
1812 else if(color_name=="milky_way")script>>params.milkywaycolor;
1813 else throw string("Undefined \"color\" construct"
1814 " in input script: \"")+color_name+'"';
1815 }
1816 
1817 /*:14*/
1818 #line 568 "pp3.w"
1819 
1820 else
1821 /*15:*/
1822 #line 645 "pp3.w"
1823 
1824 if(opcode=="line_width"){
1825 string line_name;
1826 script>>line_name;
1827 if(line_name=="grid")script>>params.linewidth_grid;
1828 else if(line_name=="ecliptic")
1829 script>>params.linewidth_ecliptic;
1830 else if(line_name=="boundaries")
1831 script>>params.linewidth_boundary;
1832 else if(line_name=="highlighted_boundaries")
1833 script>>params.linewidth_hlboundary;
1834 else if(line_name=="nebulae")
1835 script>>params.linewidth_nebula;
1836 else if(line_name=="constellation_lines")
1837 script>>params.linewidth_cline;
1838 else throw string("Undefined \"line_width\" construct"
1839 " in input script: \"")+line_name+'"';
1840 }
1841 
1842 /*:15*/
1843 #line 570 "pp3.w"
1844 
1845 else
1846 /*16:*/
1847 #line 681 "pp3.w"
1848 
1849 if(opcode=="line_style"){
1850 string line_name;
1851 script>>line_name;
1852 if(line_name=="grid")script>>params.linestyle_grid;
1853 else if(line_name=="ecliptic")
1854 script>>params.linestyle_ecliptic;
1855 else if(line_name=="boundaries")
1856 script>>params.linestyle_boundary;
1857 else if(line_name=="highlighted_boundaries")
1858 script>>params.linestyle_hlboundary;
1859 else if(line_name=="nebulae")
1860 script>>params.linestyle_nebula;
1861 else if(line_name=="constellation_lines")
1862 script>>params.linestyle_cline;
1863 else throw string("Undefined \"line_width\" construct"
1864 " in input script: \"")+line_name+'"';
1865 }
1866 
1867 
1868 /*:16*/
1869 #line 572 "pp3.w"
1870 
1871 else
1872 /*17:*/
1873 #line 721 "pp3.w"
1874 
1875 if(opcode=="switch"){
1876 string switch_name;
1877 script>>switch_name;
1878 if(switch_name=="milky_way")
1879 params.milkyway_visible= read_boolean(script);
1880 else if(switch_name=="nebulae")
1881 params.nebulae_visible= read_boolean(script);
1882 else if(switch_name=="colored_stars")
1883 params.colored_stars= read_boolean(script);
1884 else if(switch_name=="grid")
1885 params.show_grid= read_boolean(script);
1886 else if(switch_name=="ecliptic")
1887 params.show_ecliptic= read_boolean(script);
1888 else if(switch_name=="boundaries")
1889 params.show_boundaries= read_boolean(script);
1890 else if(switch_name=="constellation_lines")
1891 params.show_lines= read_boolean(script);
1892 else if(switch_name=="labels")
1893 params.show_labels= read_boolean(script);
1894 else if(switch_name=="eps_output")
1895 params.create_eps= read_boolean(script);
1896 else if(switch_name=="pdf_output")
1897 params.create_pdf= read_boolean(script);
1898 else throw string("Undefined \"switch\" construct"
1899 " in input script: \"")+switch_name+'"';
1900 }
1901 
1902 /*:17*/
1903 #line 574 "pp3.w"
1904 
1905 else
1906 /*18:*/
1907 #line 789 "pp3.w"
1908 
1909 if(opcode=="penalties"){
1910 string penalty_name;
1911 double value;
1912 script>>penalty_name>>value;
1913 value/= 1000.0;
1914 if(penalty_name=="stars")
1915 params.penalties_star= value;
1916 else if(penalty_name=="labels")
1917 params.penalties_label= value;
1918 else if(penalty_name=="nebulae")
1919 params.penalties_nebula= value;
1920 else if(penalty_name=="boundaries")
1921 params.penalties_boundary= value;
1922 else if(penalty_name=="boundaries_rim")
1923 params.penalties_boundary_rim= value;
1924 else if(penalty_name=="constellation_lines")
1925 params.penalties_cline= value;
1926 else if(penalty_name=="constellation_lines_rim")
1927 params.penalties_cline_rim= value;
1928 else if(penalty_name=="threshold")
1929 params.penalties_threshold= value;
1930 else if(penalty_name=="rim")
1931 params.penalties_rim= value;
1932 else throw string("Undefined \"penalties\" construct"
1933 " in input script: \"")+penalty_name+'"';
1934 }
1935 
1936 /*:18*/
1937 #line 576 "pp3.w"
1938 
1939 else
1940 /*19:*/
1941 #line 853 "pp3.w"
1942 
1943 if(opcode=="filename"){
1944 string object_name;
1945 script>>object_name;
1946 if(object_name=="output")
1947 params.filename_output= read_string(script);
1948 else if(object_name=="stars")
1949 params.filename_stars= read_string(script);
1950 else if(object_name=="nebulae")
1951 params.filename_nebulae= read_string(script);
1952 else if(object_name=="label_dimensions")
1953 params.filename_dimensions= read_string(script);
1954 else if(object_name=="constellation_lines")
1955 params.filename_lines= read_string(script);
1956 else if(object_name=="boundaries")
1957 params.filename_boundaries= read_string(script);
1958 else if(object_name=="milky_way")
1959 params.filename_milkyway= read_string(script);
1960 else if(object_name=="latex_preamble")
1961 params.filename_preamble= read_string(script);
1962 else if(object_name=="include"){
1963 if(!params.filename_include.empty())
1964 throw string("Nesting depth of include files greater"
1965 " than one");
1966 params.filename_include= read_string(script);
1967 ifstream included_script(params.filename_include.c_str());
1968 if(!included_script.good())
1969 cerr<<"pp3: Warning: included file "
1970 <<params.filename_include
1971 <<" not found; ignored"<<endl;
1972 else read_parameters_from_script(included_script);
1973 }
1974 else throw string("Undefined \"filename\" construct"
1975 " in input script: \"")+object_name+'"';
1976 }
1977 
1978 
1979 /*:19*/
1980 #line 578 "pp3.w"
1981 
1982 else
1983 /*20:*/
1984 #line 947 "pp3.w"
1985 
1986 if(opcode=="set"){
1987 string param_name;
1988 script>>param_name;
1989 if(param_name=="center_rectascension")
1990 script>>params.center_rectascension;
1991 else if(param_name=="center_declination")
1992 script>>params.center_declination;
1993 else if(param_name=="box_width")
1994 script>>params.view_frame_width;
1995 else if(param_name=="box_height")
1996 script>>params.view_frame_height;
1997 else if(param_name=="grad_per_cm")
1998 script>>params.grad_per_cm;
1999 else if(param_name=="constellation")
2000 params.constellation= read_string(script);
2001 else if(param_name=="shortest_constellation_line")
2002 script>>params.shortest_constellation_line;
2003 else if(param_name=="label_skip")
2004 script>>params.label_skip;
2005 else if(param_name=="minimal_nebula_radius")
2006 script>>params.minimal_nebula_radius;
2007 else if(param_name=="faintest_cluster_magnitude")
2008 script>>params.faintest_cluster_magnitude;
2009 else if(param_name=="faintest_diffuse_nebula_magnitude")
2010 script>>params.faintest_diffuse_nebula_magnitude;
2011 else if(param_name=="faintest_star_magnitude")
2012 script>>params.faintest_star_magnitude;
2013 else if(param_name=="minimal_star_radius")
2014 script>>params.minimal_star_radius;
2015 else if(param_name=="faintest_star_disk_magnitude")
2016 script>>params.faintest_star_disk_magnitude;
2017 else if(param_name=="faintest_star_with_label_magnitude")
2018 script>>params.faintest_star_with_label_magnitude;
2019 else if(param_name=="star_scaling")
2020 script>>params.star_scaling;
2021 else if(param_name=="fontsize")
2022 script>>params.font_size;
2023 else
2024 throw string("Undefined \"set\" construct in input script: \"")
2025 +param_name+'"';
2026 }
2027 
2028 /*:20*/
2029 #line 580 "pp3.w"
2030 
2031 else throw string("Undefined opcode in input script: \"")
2032 +opcode+'"';
2033 script>>opcode;
2034 }
2035 }
2036 
2037 /*:13*//*21:*/
2038 #line 998 "pp3.w"
2039 
2040 typedef map<int,int> index_list;
2041 
2042 /*:21*//*23:*/
2043 #line 1041 "pp3.w"
2044 
2045 bool assure_valid_catalogue_index(const int index,const index_list&catalogue,
2046 const string catalogue_name){
2047 if(catalogue.find(index)==catalogue.end()){
2048 cerr<<"pp3: Warning: Invalid "<<catalogue_name<<" index: "
2049 <<index<<".\n";
2050 return false;
2051 }else return true;
2052 }
2053 
2054 bool assure_valid_catalogue_index(const int index,
2055 const string constellation,
2056 map<string,index_list> &flamsteed){
2057 bool found= true;
2058 if(flamsteed.find(constellation)==flamsteed.end())found= false;
2059 else if(flamsteed[constellation].find(index)==
2060 flamsteed[constellation].end())found= false;
2061 if(!found)cerr<<"pp3: Warning: Invalid Flamsteed number: "
2062 <<index<<".\n";
2063 return found;
2064 }
2065 
2066 bool assure_valid_catalogue_index(const int index,
2067 const index_list&henry_draper){
2068 if(henry_draper.find(index)==henry_draper.end()){
2069 cerr<<"pp3: Warning: Invalid HD number: "
2070 <<index<<".\n";
2071 return false;
2072 }else return true;
2073 }
2074 
2075 /*:23*//*24:*/
2076 #line 1079 "pp3.w"
2077 
2078 void search_objects(istream&script,
2079 index_list&ngc,index_list&ic,
2080 index_list&messier,index_list&henry_draper,
2081 map<string,index_list> &flamsteed,
2082 vector<int> &found_stars,vector<int> &found_nebulae){
2083 found_stars.clear();
2084 found_nebulae.clear();
2085 string catalogue_name;
2086 int catalogue_index;
2087 script>>catalogue_name;
2088 while(script&&catalogue_name!=";"){
2089 script>>catalogue_index;
2090 if(catalogue_index<=0){
2091 stringstream error_message;
2092 error_message<<"Invalid index: "<<catalogue_index;
2093 throw error_message.str();
2094 }
2095 if(!script)throw string("Unexpected end of input script");
2096 
2097 if(params.nebulae_visible||
2098 (catalogue_name!="NGC"&&catalogue_name!="IC"&&
2099 catalogue_name!="M")){
2100 if(catalogue_name=="NGC"){
2101 if(assure_valid_catalogue_index(catalogue_index,ngc,"NGC"))
2102 found_nebulae.push_back(ngc[catalogue_index]);
2103 }else if(catalogue_name=="IC"){
2104 if(assure_valid_catalogue_index(catalogue_index,ic,"IC"))
2105 found_nebulae.push_back(ic[catalogue_index]);
2106 }else if(catalogue_name=="M"){
2107 if(assure_valid_catalogue_index(catalogue_index,messier,"M"))
2108 found_nebulae.push_back(messier[catalogue_index]);
2109 }else if(catalogue_name=="HD"){
2110 if(assure_valid_catalogue_index(catalogue_index,henry_draper))
2111 found_stars.push_back(henry_draper[catalogue_index]);
2112 }else{
2113 if(assure_valid_catalogue_index(catalogue_index,
2114 catalogue_name,flamsteed))
2115 found_stars.
2116 push_back(flamsteed[catalogue_name][catalogue_index]);
2117 }
2118 }
2119 script>>catalogue_name;
2120 }
2121 }
2122 
2123 /*:24*//*25:*/
2124 #line 1131 "pp3.w"
2125 
2126 view_data*identify_object(istream&script,index_list&ngc,
2127 index_list&ic,index_list&messier,
2128 index_list&henry_draper,
2129 map<string,index_list> &flamsteed,
2130 stars_list&stars,nebulae_list&nebulae){
2131 string catalogue_name;
2132 int catalogue_index;
2133 script>>catalogue_name>>catalogue_index;
2134 if(!script)throw string("Unexpected end of input script");
2135 if(catalogue_name=="NGC"){
2136 if(assure_valid_catalogue_index(catalogue_index,ngc,"NGC"))
2137 return&nebulae[ngc[catalogue_index]];
2138 }else if(catalogue_name=="IC"){
2139 if(assure_valid_catalogue_index(catalogue_index,ic,"IC"))
2140 return&nebulae[ic[catalogue_index]];
2141 }else if(catalogue_name=="M"){
2142 if(assure_valid_catalogue_index(catalogue_index,messier,"M"))
2143 return&nebulae[messier[catalogue_index]];
2144 }else if(catalogue_name=="HD"){
2145 if(assure_valid_catalogue_index(catalogue_index,henry_draper))
2146 return&stars[henry_draper[catalogue_index]];
2147 }else{
2148 if(assure_valid_catalogue_index(catalogue_index,
2149 catalogue_name,flamsteed))
2150 return&stars[flamsteed[catalogue_name][catalogue_index]];
2151 }
2152 return 0;
2153 }
2154 
2155 /*:25*//*26:*/
2156 #line 1174 "pp3.w"
2157 
2158 void read_objects_and_labels(istream&script,
2159 const dimensions_list&dimensions,
2160 objects_list&objects,stars_list&stars,
2161 nebulae_list&nebulae,
2162 texts_list&texts,
2163 flexes_list&flexes,
2164 const transformation&mytransform,
2165 bool included= false){
2166 if(!params.filename_include.empty()&&!included){
2167 ifstream included_file(params.filename_include.c_str());
2168 /*27:*/
2169 #line 1230 "pp3.w"
2170 
2171 string token;
2172 included_file>>token;
2173 while(included_file){
2174 if(token[0]=='#')getline(included_file,token);
2175 else if(token=="objects_and_labels")break;
2176 included_file>>token;
2177 }
2178 
2179 
2180 /*:27*/
2181 #line 1185 "pp3.w"
2182 
2183 read_objects_and_labels(included_file,dimensions,objects,stars,
2184 nebulae,texts,flexes,mytransform,true);
2185 }
2186 string opcode;
2187 script>>opcode;
2188 if(!script)return;
2189 /*22:*/
2190 #line 1012 "pp3.w"
2191 
2192 const int max_ngc= 7840,max_ic= 5386,max_messier= 110;
2193 index_list ngc,ic,messier;
2194 for(int i= 0;i<nebulae.size();i++){
2195 if(nebulae[i].ngc> 0&&nebulae[i].ngc<=max_ngc)
2196 ngc[nebulae[i].ngc]= i;
2197 if(nebulae[i].ic> 0&&nebulae[i].ic<=max_ic)
2198 ic[nebulae[i].ic]= i;
2199 if(nebulae[i].messier> 0&&nebulae[i].messier<=max_messier)
2200 messier[nebulae[i].messier]= i;
2201 }
2202 index_list henry_draper;
2203 map<string,index_list> flamsteed;
2204 for(int i= 0;i<stars.size();i++){
2205 if(stars[i].hd> 0)henry_draper[stars[i].hd]= i;
2206 if(stars[i].flamsteed> 0)
2207 flamsteed[stars[i].constellation][stars[i].flamsteed]= i;
2208 }
2209 
2210 
2211 /*:22*/
2212 #line 1192 "pp3.w"
2213 
2214 while(script){
2215 if(opcode[0]=='#'){
2216 string rest_of_line;
2217 getline(script,rest_of_line);
2218 }else
2219 /*28:*/
2220 #line 1255 "pp3.w"
2221 
2222 if(opcode=="reposition"){
2223 string position,semicolon;
2224 view_data*current_object=
2225 identify_object(script,ngc,ic,messier,henry_draper,
2226 flamsteed,stars,nebulae);
2227 int angle;
2228 bool on_baseline= false;
2229 script>>position>>semicolon;
2230 if(semicolon!=";")
2231 throw string("Expected \";\" after \"reposition\" command");
2232 /*29:*/
2233 #line 1276 "pp3.w"
2234 
2235 if(position=="E"||position=="E_")angle= 0;
2236 else if(position=="NE")angle= 1;
2237 else if(position=="N")angle= 2;
2238 else if(position=="NW")angle= 3;
2239 else if(position=="W"||position=="W_")angle= 4;
2240 else if(position=="SW")angle= 5;
2241 else if(position=="S")angle= 6;
2242 else if(position=="SE")angle= 7;
2243 else throw string("Undefined position angle: ")+position;
2244 on_baseline= position[position.length()-1]=='_';
2245 
2246 
2247 /*:29*/
2248 #line 1267 "pp3.w"
2249 
2250 if(current_object){
2251 current_object->label_angle= angle;
2252 current_object->with_label= visible;
2253 current_object->on_baseline= on_baseline;
2254 current_object->label_arranged= true;
2255 }
2256 }
2257 
2258 /*:28*/
2259 #line 1198 "pp3.w"
2260 
2261 else
2262 /*30:*/
2263 #line 1293 "pp3.w"
2264 
2265 if(opcode=="set_label_text"){
2266 view_data*current_object=
2267 identify_object(script,ngc,ic,messier,henry_draper,
2268 flamsteed,stars,nebulae);
2269 if(current_object)current_object->label= read_string(script);
2270 }
2271 
2272 
2273 /*:30*/
2274 #line 1200 "pp3.w"
2275 
2276 else
2277 /*35:*/
2278 #line 1409 "pp3.w"
2279 
2280 if(opcode=="text"){
2281 string token,contents,position("NE");
2282 double rectascension,declination;
2283 contents= read_string(script);
2284 script>>token;
2285 if(token!="at")throw string("\"at\" in \"text\" command expected");
2286 script>>rectascension>>declination;
2287 script>>token;
2288 int angle= 1;
2289 bool on_baseline= false;
2290 enum{kind_text_label,kind_flex_declination}label_kind
2291 = kind_text_label;
2292 double step_rectascension= -1.0;
2293 double step_declination= -1.0;
2294 while(script&&token!=";"){
2295 if(token=="color")script>>params.textlabelcolor;
2296 else if(token=="towards"){
2297 script>>position;
2298 /*29:*/
2299 #line 1276 "pp3.w"
2300 
2301 if(position=="E"||position=="E_")angle= 0;
2302 else if(position=="NE")angle= 1;
2303 else if(position=="N")angle= 2;
2304 else if(position=="NW")angle= 3;
2305 else if(position=="W"||position=="W_")angle= 4;
2306 else if(position=="SW")angle= 5;
2307 else if(position=="S")angle= 6;
2308 else if(position=="SE")angle= 7;
2309 else throw string("Undefined position angle: ")+position;
2310 on_baseline= position[position.length()-1]=='_';
2311 
2312 
2313 /*:29*/
2314 #line 1429 "pp3.w"
2315 
2316 }
2317 else if(token=="along"){
2318 script>>token;
2319 if(token=="declination"){
2320 label_kind= kind_flex_declination;
2321 }else throw string("Invalid \"along\" option");
2322 }
2323 else if(token=="tics"){
2324 script>>token;
2325 if(token=="rectascension"){
2326 script>>step_rectascension;
2327 if(step_rectascension<=0.0)
2328 throw string("Invalid \"tics\" interval");
2329 step_declination= -1.0;
2330 }else if(token=="declination"){
2331 script>>step_declination;
2332 if(step_declination<=0.0)
2333 throw string("Invalid \"tics\" interval");
2334 step_rectascension= -1.0;
2335 }else throw string("Invalid \"tics\" option");
2336 }else throw string("Invalid \"text\" option");
2337 script>>token;
2338 }
2339 if(!script)
2340 throw string("Unexpected end of script while scanning \"text\"");
2341 if(step_rectascension<=0.0&&step_declination<=0.0){
2342 /*36:*/
2343 #line 1481 "pp3.w"
2344 
2345 switch(label_kind){
2346 case kind_text_label:
2347 texts.push_back(text(contents,rectascension,declination,
2348 params.textlabelcolor,angle,on_baseline));
2349 break;
2350 case kind_flex_declination:
2351 flexes.push_back(new declination_flex(contents,rectascension,
2352 declination,
2353 params.textlabelcolor,angle,
2354 on_baseline));
2355 break;
2356 }
2357 
2358 /*:36*/
2359 #line 1456 "pp3.w"
2360 
2361 }if(step_rectascension> 0.0){
2362 string user_pattern(contents);
2363 double start= rectascension-floor(rectascension/step_rectascension)
2364 *step_rectascension;
2365 for(rectascension= start;rectascension<24.0;
2366 rectascension+= step_rectascension){cerr<<rectascension<<' ';
2367 /*37:*/
2368 #line 1508 "pp3.w"
2369 
2370 {
2371 stringstream coordinates;
2372 coordinates.setf(ios::fixed);
2373 coordinates<<"\\def\\coordinates#1#2#3#4#5#6#7#8#9{\\TicMark{"
2374 <<user_pattern<<"}}";
2375 coordinates<<"\\coordinates{"<<rectascension<<"}{"
2376 <<declination<<"}{";
2377 coordinates<<int(floor(rectascension))<<"}{"
2378 <<int(floor((rectascension-floor(rectascension))
2379 *60.0))
2380 <<"}{";
2381 if(int(declination)> 0.0)coordinates<<'+';
2382 coordinates<<int(declination)<<"}{}{}{}{}";
2383 contents= coordinates.str();
2384 while(contents.find(".")!=string::npos)
2385 contents.replace(contents.find("."),1,"{\\DP}");
2386 }
2387 
2388 /*:37*/
2389 #line 1463 "pp3.w"
2390 
2391 /*36:*/
2392 #line 1481 "pp3.w"
2393 
2394 switch(label_kind){
2395 case kind_text_label:
2396 texts.push_back(text(contents,rectascension,declination,
2397 params.textlabelcolor,angle,on_baseline));
2398 break;
2399 case kind_flex_declination:
2400 flexes.push_back(new declination_flex(contents,rectascension,
2401 declination,
2402 params.textlabelcolor,angle,
2403 on_baseline));
2404 break;
2405 }
2406 
2407 /*:36*/
2408 #line 1464 "pp3.w"
2409 
2410 }
2411 }else if(step_declination> 0.0){
2412 string user_pattern(contents);
2413 double start= declination-floor((declination+90.0)/step_declination)
2414 *step_declination;
2415 for(declination= start;declination<=90.0;
2416 declination+= step_declination){cerr<<declination<<' ';
2417 /*37:*/
2418 #line 1508 "pp3.w"
2419 
2420 {
2421 stringstream coordinates;
2422 coordinates.setf(ios::fixed);
2423 coordinates<<"\\def\\coordinates#1#2#3#4#5#6#7#8#9{\\TicMark{"
2424 <<user_pattern<<"}}";
2425 coordinates<<"\\coordinates{"<<rectascension<<"}{"
2426 <<declination<<"}{";
2427 coordinates<<int(floor(rectascension))<<"}{"
2428 <<int(floor((rectascension-floor(rectascension))
2429 *60.0))
2430 <<"}{";
2431 if(int(declination)> 0.0)coordinates<<'+';
2432 coordinates<<int(declination)<<"}{}{}{}{}";
2433 contents= coordinates.str();
2434 while(contents.find(".")!=string::npos)
2435 contents.replace(contents.find("."),1,"{\\DP}");
2436 }
2437 
2438 /*:37*/
2439 #line 1472 "pp3.w"
2440 
2441 /*36:*/
2442 #line 1481 "pp3.w"
2443 
2444 switch(label_kind){
2445 case kind_text_label:
2446 texts.push_back(text(contents,rectascension,declination,
2447 params.textlabelcolor,angle,on_baseline));
2448 break;
2449 case kind_flex_declination:
2450 flexes.push_back(new declination_flex(contents,rectascension,
2451 declination,
2452 params.textlabelcolor,angle,
2453 on_baseline));
2454 break;
2455 }
2456 
2457 /*:36*/
2458 #line 1473 "pp3.w"
2459 
2460 }
2461 }
2462 }
2463 
2464 /*:35*/
2465 #line 1202 "pp3.w"
2466 
2467 else{
2468 vector<int> found_stars,found_nebulae;
2469 /*31:*/
2470 #line 1305 "pp3.w"
2471 
2472 if(opcode=="delete_labels"){
2473 search_objects(script,ngc,ic,messier,henry_draper,
2474 flamsteed,found_stars,found_nebulae);
2475 for(int i= 0;i<found_stars.size();i++){
2476 stars[found_stars[i]].with_label= hidden;
2477 stars[found_stars[i]].label_arranged= true;
2478 }
2479 for(int i= 0;i<found_nebulae.size();i++){
2480 nebulae[found_nebulae[i]].with_label= hidden;
2481 nebulae[found_nebulae[i]].label_arranged= false;
2482 }
2483 }
2484 
2485 /*:31*/
2486 #line 1205 "pp3.w"
2487 
2488 else
2489 /*32:*/
2490 #line 1323 "pp3.w"
2491 
2492 if(opcode=="add_labels"){
2493 search_objects(script,ngc,ic,messier,henry_draper,
2494 flamsteed,found_stars,found_nebulae);
2495 for(int i= 0;i<found_stars.size();i++)
2496 stars[found_stars[i]].with_label= visible;
2497 for(int i= 0;i<found_nebulae.size();i++)
2498 nebulae[found_nebulae[i]].with_label= visible;
2499 }
2500 
2501 /*:32*/
2502 #line 1207 "pp3.w"
2503 
2504 else
2505 /*34:*/
2506 #line 1348 "pp3.w"
2507 
2508 if(opcode=="delete"){
2509 search_objects(script,ngc,ic,messier,henry_draper,
2510 flamsteed,found_stars,found_nebulae);
2511 for(int i= 0;i<found_stars.size();i++)
2512 stars[found_stars[i]].in_view= hidden;
2513 for(int i= 0;i<found_nebulae.size();i++)
2514 nebulae[found_nebulae[i]].in_view= hidden;
2515 }
2516 
2517 /*:34*/
2518 #line 1209 "pp3.w"
2519 
2520 else
2521 /*33:*/
2522 #line 1336 "pp3.w"
2523 
2524 if(opcode=="add"){
2525 search_objects(script,ngc,ic,messier,henry_draper,
2526 flamsteed,found_stars,found_nebulae);
2527 for(int i= 0;i<found_stars.size();i++)
2528 stars[found_stars[i]].in_view= visible;
2529 for(int i= 0;i<found_nebulae.size();i++)
2530 nebulae[found_nebulae[i]].in_view= visible;
2531 }
2532 
2533 /*:33*/
2534 #line 1211 "pp3.w"
2535 
2536 else throw string("Undefined opcode in input script: \"")
2537 +opcode+'"';
2538 }
2539 script>>opcode;
2540 }
2541 }
2542 
2543 /*:26*/
2544 #line 3838 "pp3.w"
2545 
2546 
2547 int main(int argc,char**argv){
2548 try{
2549 /*118:*/
2550 #line 3887 "pp3.w"
2551 
2552 if(argc==2){
2553 if(argv[1][0]!='-'){
2554 params.in= new ifstream(argv[1]);
2555 if(!params.in->good())
2556 throw string("Input script file ")+argv[1]
2557 +" not found";
2558 else params.input_file= true;
2559 }else if(!strcmp(argv[1],"-"))params.in= &cin;else
2560 cerr<<"Invalid argument: "<<argv[1]<<endl;
2561 }
2562 if(params.in==0){
2563 cerr<<"PP3 1.3.2  Copyright (c) 2002--2004 Torsten Bronger\n"
2564 <<"           http://pp3.sourceforge.net\n\n"
2565 <<"Syntax:\n  pp3 {input-file}\n\n"
2566 <<"{input-file} may be \"-\" to denote standard input.\n"
2567 <<"You may give an empty file to get a default plot.\n"
2568 <<"The plot is sent to standard output by default.\n";
2569 exit(0);
2570 }
2571 
2572 /*:118*/
2573 #line 3842 "pp3.w"
2574 
2575 read_parameters_from_script(*params.in);
2576 if(!params.filename_output.empty())
2577 params.out= new ofstream(params.filename_output.c_str());
2578 transformation mytransform(params.center_rectascension,
2579 params.center_declination,
2580 params.view_frame_width,
2581 params.view_frame_height,
2582 params.grad_per_cm);
2583 
2584 /*119:*/
2585 #line 3911 "pp3.w"
2586 
2587 boundaries_list boundaries;
2588 dimensions_list dimensions;
2589 objects_list objects;
2590 stars_list stars;
2591 nebulae_list nebulae;
2592 connections_list connections;
2593 texts_list texts;
2594 flexes_list flexes;
2595 
2596 read_stars(stars);
2597 
2598 if(params.show_boundaries)read_constellation_boundaries(boundaries);
2599 read_label_dimensions(dimensions);
2600 if(params.nebulae_visible)read_nebulae(nebulae);
2601 if(params.show_lines)read_constellation_lines(connections,stars);
2602 
2603 /*:119*/
2604 #line 3852 "pp3.w"
2605 
2606 
2607 read_objects_and_labels(*params.in,dimensions,objects,stars,
2608 nebulae,texts,flexes,mytransform);
2609 
2610 OUT.setf(ios::fixed);
2611 OUT.precision(3);
2612 /*121:*/
2613 #line 3957 "pp3.w"
2614 
2615 create_preamble(OUT);
2616 OUT<<"\\usepackage[nohead,nofoot,margin=0cm,"
2617 <<"paperwidth="<<params.view_frame_width_in_bp()<<"bp,"
2618 <<"paperheight="<<params.view_frame_height_in_bp()<<"bp"
2619 <<"]{geometry}\n\n"
2620 <<"\n\\begin{document}\\parindent0pt\n"
2621 <<"\\pagestyle{empty}\\thispagestyle{empty}%\n"
2622 <<"\\special{papersize="<<params.view_frame_width_in_bp()-0.1
2623 <<"bp,"<<params.view_frame_height_in_bp()-0.1<<"bp}%\n"
2624 <<"\\vbox to "<<params.view_frame_height_in_bp()<<"bp{"
2625 <<"\\vfill"
2626 <<"\\hbox to "<<params.view_frame_width_in_bp()<<"bp{%\n"
2627 <<params.bgcolor<<params.gridcolor<<params.eclipticcolor
2628 <<params.boundarycolor<<params.hlboundarycolor<<params.starcolor
2629 <<params.nebulacolor<<params.clinecolor;
2630 
2631 /*:121*/
2632 #line 3859 "pp3.w"
2633 
2634 OUT<<"\\psclip{\\psframe[linestyle=none](0bp,0bp)("
2635 <<params.view_frame_width_in_bp()
2636 <<"bp,"<<params.view_frame_height_in_bp()<<"bp)}%\n"
2637 <<"\\psframe*[linecolor=bgcolor,linestyle=none](-1bp,-1bp)("
2638 <<params.view_frame_width_in_bp()+1
2639 <<"bp,"<<params.view_frame_height_in_bp()+1<<"bp)%\n";
2640 /*120:*/
2641 #line 3935 "pp3.w"
2642 
2643 if(params.milkyway_visible)draw_milky_way(mytransform);
2644 create_grid(mytransform);
2645 if(params.show_boundaries)
2646 draw_boundaries(mytransform,boundaries,objects,
2647 params.constellation);
2648 draw_flex_labels(mytransform,flexes,objects,dimensions);
2649 draw_text_labels(mytransform,texts,objects);
2650 if(params.nebulae_visible)draw_nebulae(mytransform,nebulae,objects);
2651 draw_stars(mytransform,stars,objects);
2652 if(params.show_lines)
2653 draw_constellation_lines(connections,stars,objects);
2654 if(params.show_labels){
2655 arrange_labels(objects,dimensions);
2656 print_labels(objects);
2657 }
2658 
2659 /*:120*/
2660 #line 3866 "pp3.w"
2661 
2662 OUT<<"\\endpsclip\n";
2663 /*123:*/
2664 #line 4049 "pp3.w"
2665 
2666 OUT<<"\\hfill}}\\end{document}\n";
2667 
2668 /*:123*/
2669 #line 3868 "pp3.w"
2670 
2671 if(params.input_file)delete params.in;
2672 if(!params.filename_output.empty())
2673 delete params.out;else OUT.flush();
2674 /*124:*/
2675 #line 4055 "pp3.w"
2676 
2677 if(!params.filename_output.empty()&&(params.create_eps
2678 ||params.create_pdf)){
2679 string commandline= string("latex ")+params.filename_output;
2680 if(system(commandline.c_str())==0){
2681 string base_filename(params.filename_output);
2682 if(base_filename.find('.')!=string::npos)
2683 base_filename.erase(base_filename.find('.'));
2684 commandline= string("dvips -o ")+base_filename+".eps "
2685 +base_filename;
2686 if(system(commandline.c_str())==0){
2687 if(params.create_pdf){
2688 commandline= string("ps2pdf ")+
2689 "-dCompatibility=1.3 "+
2690 base_filename+".eps "+base_filename+".pdf";
2691 if(system(commandline.c_str())!=0)
2692 throw string("ps2pdf call failed: ")+commandline;
2693 }
2694 }else throw string("dvips call failed: ")+commandline;
2695 }else throw string("LaTeX call failed: ")+commandline;
2696 }
2697 
2698 
2699 /*:124*/
2700 #line 3872 "pp3.w"
2701 
2702 }
2703 catch(string s){
2704 cerr<<"pp3: "<<s<<'.'<<endl;
2705 exit(1);
2706 }
2707 return 0;
2708 }
2709 
2710 /*:117*/
2711