#define OUT (*params.out) \ \ /*5:*/ #line 331 "pp3.w" #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; /*43:*/ #line 1673 "pp3.w" inline double my_fmin(const double&x,const double&y){ return x y?x:y; } inline double my_fdim(const double&x,const double&y){ return x> y?x-y:0.0; } /*:43*/ #line 346 "pp3.w" /*:5*//*7:*/ #line 368 "pp3.w" const char*pp3data_env_raw= getenv("PP3DATA"); const string pp3data_env= (pp3data_env_raw==NULL? "":pp3data_env_raw); #ifdef PP3DATA const string pp3data(PP3DATA); #else const string pp3data; #endif const string filename_prefix(!pp3data_env.empty()? pp3data_env+'/':(pp3data.empty()? "":pp3data+"/")); /*:7*//*8:*/ #line 384 "pp3.w" /*70:*/ #line 2388 "pp3.w" struct color{ double red,green,blue; string name; color(string name,double red,double green,double blue) :red(red),green(green),blue(blue),name(name){} color(double red,double green,double blue) :red(red),green(green),blue(blue),name(){} void set(ostream&out)const; }; /*:70*/ #line 385 "pp3.w" struct parameters{ double center_rectascension,center_declination; double view_frame_width,view_frame_height; double grad_per_cm; double label_skip,minimal_nebula_radius,faintest_cluster_magnitude, faintest_diffuse_nebula_magnitude,faintest_star_magnitude, star_scaling,minimal_star_radius,faintest_star_disk_magnitude, faintest_star_with_label_magnitude,shortest_constellation_line; string constellation; int font_size; double penalties_label,penalties_star,penalties_nebula, penalties_boundary,penalties_boundary_rim,penalties_cline, penalties_cline_rim,penalties_threshold,penalties_rim; string filename_stars,filename_nebulae,filename_dimensions, filename_lines,filename_boundaries,filename_milkyway, filename_preamble,filename_include; string filename_output; ostream*out; istream*in; bool input_file; color bgcolor,gridcolor,eclipticcolor,boundarycolor,hlboundarycolor, starcolor,nebulacolor,labelcolor,textlabelcolor,clinecolor, milkywaycolor; double linewidth_grid,linewidth_ecliptic,linewidth_boundary, linewidth_hlboundary,linewidth_cline,linewidth_nebula; string linestyle_grid,linestyle_ecliptic,linestyle_boundary, linestyle_hlboundary,linestyle_cline,linestyle_nebula; bool milkyway_visible,nebulae_visible,colored_stars,show_grid, show_ecliptic,show_boundaries,show_lines,show_labels; bool create_eps,create_pdf; parameters():/*9:*/ #line 426 "pp3.w" center_rectascension(5.8),center_declination(0.0), view_frame_width(15.0),view_frame_height(15.0), grad_per_cm(4.0), constellation("ORI"),font_size(10), label_skip(0.06),minimal_nebula_radius(0.1), faintest_cluster_magnitude(4.0), faintest_diffuse_nebula_magnitude(8.0), faintest_star_magnitude(7.0),star_scaling(1.0), minimal_star_radius(0.015), faintest_star_disk_magnitude(4.5), faintest_star_with_label_magnitude(3.7), shortest_constellation_line(0.1), penalties_label(1.0),penalties_star(1.0), penalties_nebula(1.0),penalties_boundary(1.0), penalties_boundary_rim(1.0),penalties_cline(1.0), penalties_cline_rim(1.0),penalties_threshold(1.0), penalties_rim(1.0), filename_stars(filename_prefix+"stars.dat"), filename_nebulae(filename_prefix+"nebulae.dat"), filename_dimensions("labeldimens.dat"), filename_lines(filename_prefix+"lines.dat"), filename_boundaries(filename_prefix+"boundaries.dat"), filename_milkyway(filename_prefix+"milkyway.dat"), filename_preamble(),filename_include(), filename_output(),out(&cout),in(0),input_file(false), bgcolor("bgcolor",0,0,0.4), gridcolor("gridcolor",0,0.298,0.447), eclipticcolor("eclipticcolor",1,0,0), boundarycolor("boundarycolor",0.5,0.5,0), hlboundarycolor("hlboundarycolor",1,1,0), starcolor("starcolor",1,1,1), nebulacolor("nebulacolor",1,1,1), labelcolor("labelcolor",0,1,1), textlabelcolor(1,1,0), clinecolor("clinecolor",0,1,0), milkywaycolor(0,0,1), linewidth_grid(0.025),linewidth_ecliptic(0.018), linewidth_boundary(0.035),linewidth_hlboundary(0.035), linewidth_cline(0.035),linewidth_nebula(0.018), linestyle_grid("solid"),linestyle_ecliptic("dashed"), linestyle_boundary("dashed"), linestyle_hlboundary("dashed"),linestyle_cline("solid"), linestyle_nebula("solid"), milkyway_visible(false), nebulae_visible(true), colored_stars(true), show_grid(true),show_ecliptic(true),show_boundaries(true), show_lines(true),show_labels(true), create_eps(false), create_pdf(false) /*:9*/ #line 417 "pp3.w" {} int view_frame_width_in_bp(){ return int(ceil(view_frame_width/2.54*72)); } int view_frame_height_in_bp(){ return int(ceil(view_frame_height/2.54*72)); } }params; /*:8*//*39:*/ #line 1576 "pp3.w" typedef enum{hidden,visible,undecided}visibility; struct view_data{ visibility in_view; double x,y; double radius,skip; visibility with_label; bool label_arranged; string label; double label_width,label_height,label_depth; bool on_baseline; color label_color; int label_angle; view_data():in_view(undecided),x(DBL_MAX),y(DBL_MAX),radius(0.0), skip(params.label_skip), with_label(undecided),label_arranged(false),label(), label_width(0.0),label_height(0.0), label_depth(0.0),on_baseline(false), label_color(params.labelcolor),label_angle(0){} void get_label_boundaries(double&left,double&right,double&top, double&bottom)const; double scope()const{return radius+skip+ my_fmax(label_width,label_height)+2.0*skip;} bool has_valid_coordinates()const{return x!=DBL_MAX&&y!=DBL_MAX;} virtual double penalties_with(const double left,const double right, const double top,const double bottom, bool core= true)const; }; /*:39*//*40:*/ #line 1610 "pp3.w" typedef vector objects_list; /*:40*//*41:*/ #line 1622 "pp3.w" void view_data::get_label_boundaries(double&left,double&right,double&top, double&bottom)const{ const double origin_x= x+(radius+skip)*cos(M_PI_4*double(label_angle)); const double origin_y= y+(radius+skip)*sin(M_PI_4*double(label_angle)); switch(label_angle){ case 0:case 1:case 7:left= origin_x;break; case 2:case 6:left= origin_x-label_width/2.0;break; case 3:case 4:case 5:left= origin_x-label_width;break; } right= left+label_width; switch(label_angle){ case 0:case 4:bottom= origin_y- (on_baseline?0.0:label_height/2.0);break; case 1:case 2:case 3:bottom= origin_y;break; case 5:case 6:case 7:bottom= origin_y-label_height;break; } if(on_baseline)bottom-= label_depth; top= bottom+label_height; } /*:41*//*42:*/ #line 1650 "pp3.w" double view_data::penalties_with(const double left,const double right, const double top,const double bottom, bool core)const{ if(with_label==visible&&label_arranged){ double left2,right2,top2,bottom2; get_label_boundaries(left2,right2,top2,bottom2); const double overlap_left= my_fmax(left,left2); const double overlap_right= my_fmin(right,right2); const double overlap_top= my_fmin(top,top2); const double overlap_bottom= my_fmax(bottom,bottom2); const double overlap_x= my_fdim(overlap_right,overlap_left); const double overlap_y= my_fdim(overlap_top,overlap_bottom); return overlap_x*overlap_y*params.penalties_label; }else return 0.0; } /*:42*//*44:*/ #line 1703 "pp3.w" struct star:public view_data{ int hd,bs; double rectascension,declination; double magnitude; double b_v; int flamsteed; string name; string constellation; string spectral_class; star():hd(0),bs(0),rectascension(0.0),declination(0.0), magnitude(0.0),b_v(0.0),flamsteed(0),name(""), spectral_class(""),view_data(){} virtual double penalties_with(const double left,const double right, const double top,const double bottom, bool core= true)const; }; /*:44*//*45:*/ #line 1727 "pp3.w" double star::penalties_with(const double left,const double right, const double top,const double bottom, bool core)const{ double penalties= view_data::penalties_with(left,right,top,bottom, core); const double left2= x-radius,right2= x+radius,top2= y+radius, bottom2= y-radius; const double overlap_left= my_fmax(left,left2); const double overlap_right= my_fmin(right,right2); const double overlap_top= my_fmin(top,top2); const double overlap_bottom= my_fmax(bottom,bottom2); const double overlap_x= my_fdim(overlap_right,overlap_left); const double overlap_y= my_fdim(overlap_top,overlap_bottom); penalties+= overlap_x*overlap_y*params.penalties_star; return penalties; } typedef vector stars_list; /*:45*//*46:*/ #line 1770 "pp3.w" istream&operator>>(istream&in,star&s){ in>>s.hd>>s.bs>>s.rectascension >>s.declination>>s.magnitude>>s.b_v >>s.flamsteed; char ch; do in.get(ch);while(in&&ch!='\n'); getline(in,s.name); getline(in,s.constellation); getline(in,s.spectral_class); return in; } /*:46*//*47:*/ #line 1786 "pp3.w" void read_stars(stars_list&stars){ ifstream stars_file(params.filename_stars.c_str()); if(!stars_file)throw string("No stars file found: " +params.filename_stars); star current_star; stars_file>>current_star; while(stars_file){ current_star.label= string("\\Starname{")+current_star.name+'}'; stars.push_back(current_star); stars_file>>current_star; } } /*:47*//*48:*/ #line 1805 "pp3.w" typedef enum{unknown,galaxy,emission,reflection,open_cluster, globular_cluster}nebula_kind; /*:48*//*49:*/ #line 1823 "pp3.w" struct nebula:public view_data{ int ngc,ic,messier; string constellation; double rectascension,declination; double magnitude; double diameter_x,diameter_y; double horizontal_angle; nebula_kind kind; nebula():ngc(0),ic(0),messier(0),constellation(),rectascension(0.0), declination(0.0),magnitude(0.0),diameter_x(0.0), diameter_y(0.0),horizontal_angle(0.0),kind(unknown){} virtual double penalties_with(const double left,const double right, const double top,const double bottom, bool core= true)const; }; typedef vector nebulae_list; /*:49*//*50:*/ #line 1848 "pp3.w" double nebula::penalties_with(const double left,const double right, const double top,const double bottom, bool core)const{ double penalties= view_data::penalties_with(left,right,top,bottom,core); const double left2= x-radius,right2= x+radius,top2= y+radius, bottom2= y-radius; const double overlap_left= my_fmax(left,left2); const double overlap_right= my_fmin(right,right2); const double overlap_top= my_fmin(top,top2); const double overlap_bottom= my_fmax(bottom,bottom2); const double overlap_x= my_fdim(overlap_right,overlap_left); const double overlap_y= my_fdim(overlap_top,overlap_bottom); penalties+= overlap_x*overlap_y*params.penalties_nebula; return penalties; } /*:50*//*51:*/ #line 1876 "pp3.w" istream&operator>>(istream&in,nebula&n){ int kind; in>>n.ngc>>n.ic>>n.messier>>n.constellation>>n.rectascension >>n.declination>>n.magnitude>>n.diameter_x>>n.diameter_y >>n.horizontal_angle>>kind; n.kind= nebula_kind(kind); return in; } /*:51*//*52:*/ #line 1889 "pp3.w" void read_nebulae(nebulae_list&nebulae){ ifstream nebulae_file(params.filename_nebulae.c_str()); nebula current_nebula; nebulae_file>>current_nebula; while(nebulae_file){ /*53:*/ #line 1908 "pp3.w" string catalogue; stringstream number; if(current_nebula.messier> 0){ catalogue= "\\Messier{"; number< 0){ catalogue= "\\NGC{"; number< 0){ catalogue= "\\IC{"; number<>current_nebula; } } /*:52*//*54:*/ #line 1933 "pp3.w" struct point{ double x,y; point(const double x,const double y):x(x),y(y){} point():x(0.0),y(0.0){} }; /*:54*//*55:*/ #line 1955 "pp3.w" struct boundary{ vector points; vector constellations; bool belongs_to_constellation(const string constellation)const; }; typedef vector boundaries_list; /*:55*//*56:*/ #line 1970 "pp3.w" bool boundary::belongs_to_constellation(const string constellation)const{ for(int i= 0;i>(istream&in,boundary&p){ int size; in>>size; if(!in.good())return in; p.points.resize(size); for(int i= 0;i>p.points[i].x>>p.points[i].y; in>>size; p.constellations.resize(size); for(int i= 0;i>p.constellations[i]; return in; } /*:57*//*58:*/ #line 2016 "pp3.w" void read_constellation_boundaries(boundaries_list&boundaries){ ifstream boundaryfile(params.filename_boundaries.c_str()); boundary current_boundary; boundaryfile>>current_boundary; while(boundaryfile){ boundaries.push_back(current_boundary); boundaryfile>>current_boundary; } } /*:58*//*59:*/ #line 2038 "pp3.w" struct boundary_atom:public view_data{ point start,end; boundary_atom(point start,point end); virtual double penalties_with(const double left,const double right, const double top,const double bottom, bool core= true)const; }; /*:59*//*60:*/ #line 2054 "pp3.w" boundary_atom::boundary_atom(point start,point end):start(start),end(end){ x= (start.x+end.x)/2.0; y= (start.y+end.y)/2.0; radius= hypot(end.x-start.x,end.y-start.y)/2.0; radius*= M_PI_2; in_view= visible; with_label= hidden; skip= 0.0; } /*:60*//*61:*/ #line 2075 "pp3.w" /*63:*/ #line 2187 "pp3.w" bool line_intersection(double numerator,double denominator, double zero_point,double slope, double min,double max, double&intersection){ if(denominator==0)return false; const double lambda= numerator/denominator; intersection= zero_point+lambda*slope; return lambda> 0.0&&lambda<1.0&& intersection> min&&intersection intersection_points; if(line_intersection(left-start.x,r.x,start.y,r.y, bottom,top,intersection)) intersection_points.push_back(point(left,intersection)); if(line_intersection(right-start.x,r.x,start.y,r.y, bottom,top,intersection)) intersection_points.push_back(point(right,intersection)); if(line_intersection(top-start.y,r.y,start.x,r.x, left,right,intersection)) intersection_points.push_back(point(intersection,top)); if(line_intersection(bottom-start.y,r.y,start.x,r.x, left,right,intersection)) intersection_points.push_back(point(intersection,bottom)); if(start.x> left&&start.x bottom&&start.y left&&end.x bottom&&end.y connections_list; /*:62*//*64:*/ #line 2206 "pp3.w" double connection::penalties_with(const double left,const double right, const double top,const double bottom, bool core)const { double intersection; point r(end.x-start.x,end.y-start.y); vector intersection_points; if(line_intersection(left-start.x,r.x,start.y,r.y, bottom,top,intersection)) intersection_points.push_back(point(left,intersection)); if(line_intersection(right-start.x,r.x,start.y,r.y, bottom,top,intersection)) intersection_points.push_back(point(right,intersection)); if(line_intersection(top-start.y,r.y,start.x,r.x, left,right,intersection)) intersection_points.push_back(point(intersection,top)); if(line_intersection(bottom-start.y,r.y,start.x,r.x, left,right,intersection)) intersection_points.push_back(point(intersection,bottom)); if(start.x> left&&start.x bottom&&start.y left&&end.x bottom&&end.y>to_catalogue_name; while(file){ if(to_catalogue_name[0]=='#'){ string dummy; getline(file,dummy); }else if(to_catalogue_name==";") from_catalogue_index= 0; else{ file>>to_catalogue_index; if(from_catalogue_index> 0&&to_catalogue_index> 0){ /*66:*/ #line 2283 "pp3.w" int from_index= -1,to_index= -1; for(int i= 0;i>to_catalogue_name; } } /*:65*//*71:*/ #line 2405 "pp3.w" void color::set(ostream&out)const{ out<<"\\newrgbcolor{dummycolor}{"<>(istream&in,color&c){ in>>c.red>>c.green>>c.blue; if(!in ||c.red<0.0||c.red> 1.0 ||c.green<0.0||c.green> 1.0 ||c.blue<0.0||c.blue> 1.0) throw string("Invalid RGB values in input script"); return in; } /*:72*//*73:*/ #line 2432 "pp3.w" ostream&operator<<(ostream&out,const color&c){ if(c.name.empty())throw string("Cannot write unnamed color to stream"); out<<"\\newrgbcolor{"< 1.0)throw string("Invalid x for color interpolation"); const double y= 1.0-x; return color(new_name, y*c1.red+x*c2.red, y*c1.green+x*c2.green, y*c1.blue+x*c2.blue); } /*:74*//*76:*/ #line 2489 "pp3.w" class transformation{ double width,height,rad_per_cm; double a[3][3],a_unscaled[3][3]; inline double stretch_factor(double z)const; public: transformation(const double rectascension, const double declination, const double width,const double height, const double grad_per_cm); bool polar_projection(const double rectascension,const double declination, double&x,double&y)const; double get_rad_per_cm()const{return rad_per_cm;} }; /*:76*//*77:*/ #line 2562 "pp3.w" inline double transformation::stretch_factor(const double z)const{ const double zt= 1.0-z; return 1.0+zt* (1.0/3.0+zt* (2.0/15.0+zt* (2.0/35.0+zt* (8.0/315.0+zt* (8.0/693.0))))); } /*:77*//*78:*/ #line 2587 "pp3.w" transformation::transformation(const double rectascension, const double declination, const double width,const double height, const double grad_per_cm){ const double phi= -(rectascension+12)*15.0*M_PI/180.0; const double delta= declination*M_PI/180.0; const double alpha= -delta+M_PI_2; rad_per_cm= grad_per_cm*M_PI/180.0; a_unscaled[0][0]= sin(phi); a_unscaled[0][1]= cos(phi); a_unscaled[0][2]= 0.0; a_unscaled[1][0]= cos(phi)*cos(alpha); a_unscaled[1][1]= -sin(phi)*cos(alpha); a_unscaled[1][2]= sin(alpha); a_unscaled[2][0]= -cos(phi)*sin(alpha); a_unscaled[2][1]= sin(phi)*sin(alpha); a_unscaled[2][2]= cos(alpha); for(int i= 0;i<3;i++) for(int j= 0;j<3;j++) a[i][j]= a_unscaled[i][j]/rad_per_cm; transformation::width= width; transformation::height= height; } /*:78*//*79:*/ #line 2621 "pp3.w" bool transformation::polar_projection(const double rectascension, const double declination, double&x,double&y)const{ const double phi= rectascension*15.0*M_PI/180.0; const double delta= declination*M_PI/180.0; const double cos_delta= cos(delta); const double x0= cos_delta*cos(phi); const double y0= cos_delta*sin(phi); const double z0= sin(delta); const double z1= a_unscaled[2][0]*x0+a_unscaled[2][1]*y0+a_unscaled[2][2]*z0; if(z1<-DBL_EPSILON)return false; const double stretch= stretch_factor(z1); const double x1= a[0][0]*x0+a[0][1]*y0; const double y1= a[1][0]*x0+a[1][1]*y0+a[1][2]*z0; x= x1*stretch+width/2.0; y= y1*stretch+height/2.0; if(x<0.0||x> width||y<0.0||y> height)return false; return true; } /*:79*//*81:*/ #line 2669 "pp3.w" double calculate_overlap(double left1,double right1,double top1, double bottom1,double left2,double right2, double top2,double bottom2){ const double overlap_left= my_fmax(left1,left2); const double overlap_right= my_fmin(right1,right2); const double overlap_top= my_fmin(top1,top2); const double overlap_bottom= my_fmax(bottom1,bottom2); const double overlap_x= my_fdim(overlap_right,overlap_left); const double overlap_y= my_fdim(overlap_top,overlap_bottom); return overlap_x*overlap_y; } /*:81*//*82:*/ #line 2690 "pp3.w" struct dimension{ double width,height,depth; dimension():width(0.0),height(0.0),depth(0.0){} dimension(const dimension&d):width(d.width),height(d.height), depth(d.depth){} }; typedef map dimensions_list; /*:82*//*83:*/ #line 2708 "pp3.w" /*122:*/ #line 4023 "pp3.w" void create_preamble(ostream&out){ out<<"\\documentclass["< required_names; for(int i= 0;ilabel; if(!current_name.empty())required_names.push_back(current_name); } required_names.unique(); ofstream temp_file("pp3temp.tex"); create_preamble(temp_file); temp_file<<"\n\\begin{document}\n" <<"\\newwrite\\labelsfile\n" <<"\\catcode`\\_=11 % for underscores in the filename\n" <<"\\immediate\\openout\\labelsfile=pp3temp.dat\n" <<"\\catcode`\\_=8\n"; list ::const_iterator p= required_names.begin(); while(p!=required_names.end()) temp_file<<"\\setbox0 = \\hbox{\\Label{"<<*(p++) <<"}}\n \\immediate\\write\\labelsfile{" "\\the\\wd0s \\the\\ht0s \\the\\dp0s}\n"; temp_file<<"\\immediate\\closeout\\labelsfile\n\\end{document}\n"; temp_file.close(); string commandline("latex pp3temp"); if(params.filename_output.empty()) commandline+= " > pp3dump.log"; if(system(commandline.c_str())!=0) throw string("Label dimensions calculations: LaTeX call failed: ") +commandline; ifstream raw_labels_file("pp3temp.dat"); p= required_names.begin(); while(p!=required_names.end()){ string current_width,current_height,current_depth; string current_name; current_name= *(p++); raw_labels_file>>current_width>>current_height>>current_depth; current_width.substr(0,current_width.length()-3); current_height.substr(0,current_height.length()-3); current_depth.substr(0,current_depth.length()-3); dimensions[current_name].width= strtod(current_width.c_str(),0) /72.27*2.54; dimensions[current_name].height= strtod(current_height.c_str(),0) /72.27*2.54; dimensions[current_name].depth= strtod(current_depth.c_str(),0) /72.27*2.54; dimensions[current_name].height+= dimensions[current_name].depth; } /*90:*/ #line 2980 "pp3.w" ofstream cooked_labels_file("labeldimens.dat"); cooked_labels_file.setf(ios::fixed); cooked_labels_file.precision(5); dimensions_list::const_iterator q= dimensions.begin(); while(q!=dimensions.end()){ string current_name; dimension current_dimension; current_name= q->first; current_dimension= (q++)->second; cooked_labels_file<with_label==visible){ if(!dimensions_recalculated&& dimensions.find(current_object->label)==dimensions.end()){ recalculate_dimensions(dimensions,objects); dimensions_recalculated= true; if(dimensions.find(current_object->label)==dimensions.end()) throw string("Update of label dimensions file failed: \"")+ current_object->label+"\" not found"; } current_object->label_width= dimensions[current_object->label].width; current_object->label_height= dimensions[current_object->label].height; current_object->label_depth= dimensions[current_object->label].depth; } } /*:88*/ #line 2714 "pp3.w" for(int i= 0;iin_view==visible&&objects[i]->with_label==visible &&!objects[i]->label_arranged){ /*84:*/ #line 2790 "pp3.w" const double on_object_scope= objects[i]->scope(); for(int j= 0;jin_view==visible){ const double distance= hypot(objects[i]->x-objects[j]->x, objects[i]->y-objects[j]->y); if(distancescope()&& /*85:*/ #line 2803 "pp3.w" (distance> objects[j]->skip|| (objects[j]->with_label==visible&&!objects[j]->label.empty())) /*:85*/ #line 2798 "pp3.w" ) vicinity.push_back(objects[j]); } } /*:84*/ #line 2719 "pp3.w" double best_penalty= DBL_MAX; int best_angle= 0; for(int k= 0;k<8;k++){ objects[i]->label_angle= k; double on_object_left,on_object_right,on_object_top, on_object_bottom; objects[i]-> get_label_boundaries(on_object_left,on_object_right, on_object_top,on_object_bottom); double penalty= 0.0; double rim_width= 2.0*objects[i]->skip; for(int j= 0;j penalties_with(on_object_left,on_object_right, on_object_top,on_object_bottom)+ vicinity[j]-> penalties_with(on_object_left-rim_width, on_object_right+rim_width, on_object_top+rim_width, on_object_bottom-rim_width, false)*params.penalties_rim; } if(on_object_left<0.0||on_object_bottom<0.0|| on_object_right> params.view_frame_width|| on_object_top> params.view_frame_height) penalty+= 10000.0; if(penaltylabel.empty()) if(best_penalty<0.4*params.penalties_threshold* objects[i]->label_height*objects[i]->label_width){ objects[i]->label_angle= best_angle; objects[i]->label_arranged= true; #ifdef DEBUG stringstream penalty; penalty.precision(2); penalty<<" "<label_height*objects[i]->label_width) *100<<"%)"; cerr<<"pp3DEBUG: Object "<label<<' '; const star*s= dynamic_cast (objects[i]); if(s)cerr<constellation; cerr<<" has penalty of"<with_label= hidden; objects[i]->label_arranged= true; } } } } /*:83*//*86:*/ #line 2813 "pp3.w" void print_labels(const objects_list&objects){ for(int i= 0;iin_view==visible&&objects[i]->with_label==visible &&objects[i]->label_arranged){ double left,right,top,bottom; objects[i]->get_label_boundaries(left,right,top,bottom); if(left<0.0||bottom<0.0||right> params.view_frame_width ||top> params.view_frame_height)continue; objects[i]->label_color.set(OUT); OUT<<"\\hbox to 0pt{"; OUT<<"\\hskip"<label; OUT<<"}}\\vskip"<label_depth<<")%\n"; OUT<<"\\psframe[linewidth=0.3pt]("<>dimensions[name].width>>dimensions[name].height >>dimensions[name].depth; getline(file,dummy); getline(file,name); } } /*:87*//*91:*/ #line 3005 "pp3.w" struct text:public view_data{ string contents; double rectascension,declination; text(string t,double r,double d,color c,int angle,bool on_baseline); }; typedef list texts_list; /*:91*//*92:*/ #line 3020 "pp3.w" text::text(string t,double r,double d,color c,int angle,bool on_baseline) :contents(t),rectascension(r),declination(d){ label= string("\\TextLabel{")+t+'}'; with_label= visible; label_angle= angle; view_data::on_baseline= on_baseline; label_arranged= true; label_color= c; radius= skip= 0.0; } /*:92*//*93:*/ #line 3037 "pp3.w" void draw_text_labels(transformation&mytransform,texts_list&texts, objects_list&objects){ texts_list::iterator p= texts.begin(); while(p!=texts.end()){ double x,y; if(mytransform.polar_projection(p->rectascension, p->declination, x,y)){ p->in_view= visible; p->x= x; p->y= y; objects.push_back(&(*p)); } p++; } } /*:93*//*94:*/ #line 3075 "pp3.w" struct flex_label:public view_data{ double rectascension,declination; flex_label(string s,double r,double d,color c,int a,bool b); virtual bool draw(const transformation&mytransform, dimensions_list&dimensions,objects_list&objects) const= 0; }; /*:94*//*95:*/ #line 3091 "pp3.w" flex_label::flex_label(string s,double r,double d,color c,int a,bool b) :rectascension(r),declination(d){ label_color= c; label= string("\\FlexLabel{")+s+'}'; label_angle= a; on_baseline= b; in_view= visible; with_label= hidden; label_arranged= true; } typedef list flexes_list; /*:95*//*96:*/ #line 3108 "pp3.w" struct declination_flex:public flex_label{ declination_flex(string s,double r,double d,color c,int a,bool b) :flex_label(s,r,d,c,a,b){} virtual bool draw(const transformation&mytransform, dimensions_list&dimensions,objects_list&objects) const; virtual double penalties_with(const double left,const double right, const double top,const double bottom, bool core= true)const; }; /*:96*//*97:*/ #line 3139 "pp3.w" bool declination_flex::draw(const transformation&mytransform, dimensions_list&dimensions, objects_list&objects)const{ if(dimensions.find(label)==dimensions.end()) recalculate_dimensions(dimensions,objects); if(dimensions.find(label)==dimensions.end()) throw string("Update of label dimensions file failed: \"")+ label+"\" not found"; const double label_width= dimensions[label].width; const double label_height= dimensions[label].height; const double rectascension_halfwidth= label_width *mytransform.get_rad_per_cm()*180.0/M_PI/15.0 /cos(declination*M_PI/180.0)/2.0; char justification; double path_point_rectascension[3]; path_point_rectascension[0]= rectascension; path_point_rectascension[1]= rectascension-rectascension_halfwidth; path_point_rectascension[2]= rectascension- 2.0*rectascension_halfwidth; switch(label_angle){ case 0:case 1:case 7: justification= 'l'; break; case 2:case 6: justification= 'c'; for(int i= 0;i<3;i++) path_point_rectascension[i]+= rectascension_halfwidth; break; case 3:case 4:case 5: justification= 'r'; for(int i= 0;i<3;i++) path_point_rectascension[i]+= 2.0*rectascension_halfwidth; break; } double lower; switch(label_angle){ case 0:case 4:lower= -0.4;break; case 1:case 2:case 3:lower= 0.0;break; case 5:case 6:case 7:lower= -0.8;break; } double x[3],y[3]; for(int i= 0;i<3;i++) if(!mytransform.polar_projection(path_point_rectascension[i], declination,x[i],y[i])) return false; label_color.set(OUT); OUT<<"\\Label{\\pstextpath["<draw(mytransform,dimensions,objects); } /*:99*//*100:*/ #line 3239 "pp3.w" /*101:*/ #line 3290 "pp3.w" void create_hs_colour(double b_v,string spectral_class){ double hue,saturation; const double bv0= -0.1,bv1= 0.001,bv2= 0.62,bv3= 1.7; const double hue0= 0.6,hue1= 0.47,hue2= 0.17,hue3= 0.0; const double min_saturation= 0.0,max_saturation= 0.2; /*102:*/ #line 3325 "pp3.w" if(b_v> 90.0){ switch(spectral_class[0]){ case'O':b_v= 0.0;break; case'B':b_v= -0.07;break; case'A':b_v= 0.11;break; case'F':b_v= 0.43;break; case'G':b_v= 0.89;break; case'K':b_v= 1.24;break; case'M':b_v= 1.62;break; case'N':b_v= 2.88;break; case'S':b_v= 1.84;break; case'C':b_v= 3.02;break; default:b_v= 0.0;break; } } /*:102*/ #line 3296 "pp3.w" if(b_v bv3)b_v= bv3; if(b_v 0))){ if(mytransform.polar_projection(nebulae[i].rectascension, nebulae[i].declination, nebulae[i].x,nebulae[i].y)){ nebulae[i].in_view= visible; if(nebulae[i].horizontal_angle> 360.0) nebulae[i].diameter_x= nebulae[i].diameter_y= sqrt(nebulae[i].diameter_x*nebulae[i].diameter_y); nebulae[i].radius= nebulae[i].diameter_x/2.0/ mytransform.get_rad_per_cm()*M_PI/180.0; if(nebulae[i].with_label!=hidden) nebulae[i].with_label= visible; if(nebulae[i].radius> params.minimal_nebula_radius){ /*104:*/ #line 3424 "pp3.w" if(nebulae[i].diameter_x==nebulae[i].diameter_y) OUT<<"\\pscircle("< current_line; for(int j= 0;j=2){ if(current_line.size()==2)OUT<<"\\psline"; else OUT<<"\\pscurve"; OUT<<"[liftpen=2]{c-c}"; for(int j= 0;j 0)objects.push_back(new boundary_atom(current_line[j], current_line[j-1])); /*:113*/ #line 3677 "pp3.w" } OUT<<"\\relax\n"; } } /*:112*//*114:*/ #line 3704 "pp3.w" void draw_boundaries(const transformation&mytransform, boundaries_list&boundaries, objects_list&objects, string constellation= string("")){ OUT<<"\\psset{linecolor=boundarycolor,linewidth=" < params.shortest_constellation_line&&r> 0.0){ OUT<<"\\psline{cc-cc}("< > pixels(256); /*69:*/ #line 2361 "pp3.w" ifstream file(params.filename_milkyway.c_str()); double radius; file>>radius; double rectascension,declination,x,y; int pixel; const double cm_per_grad= 1.0/ (mytransform.get_rad_per_cm()*180.0/M_PI); radius*= cm_per_grad/2.54*72.27; file>>rectascension>>declination>>pixel; while(file){ if(mytransform.polar_projection(rectascension,declination,x,y)) pixels[pixel].push_back(point(x,y)); file>>rectascension>>declination>>pixel; } /*:69*/ #line 3810 "pp3.w" for(int i= 1;i>boolean; if(boolean=="on")return true; else if(boolean=="off")return false; else throw string("Expected \"on\" or \"off\" in \"switch\" construct " "in input script"); } /*:11*//*12:*/ #line 518 "pp3.w" string read_string(istream&script){ const string UnexpectedEOS("Unexpected end of input script while reading a" " string parameter"); char c; string contents; while(script.get(c))if(!isspace(c))break; if(!script)throw UnexpectedEOS; if(c!='"'){ script>>contents; if(script)contents.insert(contents.begin(),c);else contents= c; }else{ while(script.get(c)){ if(c=='"')break; if(c=='\\'){ if(!script.get(c)) throw UnexpectedEOS; switch(c){ case'\\':case'"':contents+= c;break; default:throw string("Unknown escape sequence in string"); } }else contents+= c; } if(!script) throw UnexpectedEOS; } return contents; } /*:12*//*13:*/ #line 559 "pp3.w" void read_parameters_from_script(istream&script){ string opcode; script>>opcode; while(opcode!="objects_and_labels"&&script){ if(opcode[0]=='#'){ string rest_of_line; getline(script,rest_of_line); }else /*14:*/ #line 609 "pp3.w" if(opcode=="color"){ string color_name; script>>color_name; if(color_name=="background")script>>params.bgcolor; else if(color_name=="grid")script>>params.gridcolor; else if(color_name=="ecliptic")script>>params.eclipticcolor; else if(color_name=="boundaries") script>>params.boundarycolor; else if(color_name=="highlighted_boundaries") script>>params.hlboundarycolor; else if(color_name=="stars")script>>params.starcolor; else if(color_name=="nebulae")script>>params.nebulacolor; else if(color_name=="labels")script>>params.labelcolor; else if(color_name=="text_labels") script>>params.textlabelcolor; else if(color_name=="constellation_lines") script>>params.clinecolor; else if(color_name=="milky_way")script>>params.milkywaycolor; else throw string("Undefined \"color\" construct" " in input script: \"")+color_name+'"'; } /*:14*/ #line 568 "pp3.w" else /*15:*/ #line 645 "pp3.w" if(opcode=="line_width"){ string line_name; script>>line_name; if(line_name=="grid")script>>params.linewidth_grid; else if(line_name=="ecliptic") script>>params.linewidth_ecliptic; else if(line_name=="boundaries") script>>params.linewidth_boundary; else if(line_name=="highlighted_boundaries") script>>params.linewidth_hlboundary; else if(line_name=="nebulae") script>>params.linewidth_nebula; else if(line_name=="constellation_lines") script>>params.linewidth_cline; else throw string("Undefined \"line_width\" construct" " in input script: \"")+line_name+'"'; } /*:15*/ #line 570 "pp3.w" else /*16:*/ #line 681 "pp3.w" if(opcode=="line_style"){ string line_name; script>>line_name; if(line_name=="grid")script>>params.linestyle_grid; else if(line_name=="ecliptic") script>>params.linestyle_ecliptic; else if(line_name=="boundaries") script>>params.linestyle_boundary; else if(line_name=="highlighted_boundaries") script>>params.linestyle_hlboundary; else if(line_name=="nebulae") script>>params.linestyle_nebula; else if(line_name=="constellation_lines") script>>params.linestyle_cline; else throw string("Undefined \"line_width\" construct" " in input script: \"")+line_name+'"'; } /*:16*/ #line 572 "pp3.w" else /*17:*/ #line 721 "pp3.w" if(opcode=="switch"){ string switch_name; script>>switch_name; if(switch_name=="milky_way") params.milkyway_visible= read_boolean(script); else if(switch_name=="nebulae") params.nebulae_visible= read_boolean(script); else if(switch_name=="colored_stars") params.colored_stars= read_boolean(script); else if(switch_name=="grid") params.show_grid= read_boolean(script); else if(switch_name=="ecliptic") params.show_ecliptic= read_boolean(script); else if(switch_name=="boundaries") params.show_boundaries= read_boolean(script); else if(switch_name=="constellation_lines") params.show_lines= read_boolean(script); else if(switch_name=="labels") params.show_labels= read_boolean(script); else if(switch_name=="eps_output") params.create_eps= read_boolean(script); else if(switch_name=="pdf_output") params.create_pdf= read_boolean(script); else throw string("Undefined \"switch\" construct" " in input script: \"")+switch_name+'"'; } /*:17*/ #line 574 "pp3.w" else /*18:*/ #line 789 "pp3.w" if(opcode=="penalties"){ string penalty_name; double value; script>>penalty_name>>value; value/= 1000.0; if(penalty_name=="stars") params.penalties_star= value; else if(penalty_name=="labels") params.penalties_label= value; else if(penalty_name=="nebulae") params.penalties_nebula= value; else if(penalty_name=="boundaries") params.penalties_boundary= value; else if(penalty_name=="boundaries_rim") params.penalties_boundary_rim= value; else if(penalty_name=="constellation_lines") params.penalties_cline= value; else if(penalty_name=="constellation_lines_rim") params.penalties_cline_rim= value; else if(penalty_name=="threshold") params.penalties_threshold= value; else if(penalty_name=="rim") params.penalties_rim= value; else throw string("Undefined \"penalties\" construct" " in input script: \"")+penalty_name+'"'; } /*:18*/ #line 576 "pp3.w" else /*19:*/ #line 853 "pp3.w" if(opcode=="filename"){ string object_name; script>>object_name; if(object_name=="output") params.filename_output= read_string(script); else if(object_name=="stars") params.filename_stars= read_string(script); else if(object_name=="nebulae") params.filename_nebulae= read_string(script); else if(object_name=="label_dimensions") params.filename_dimensions= read_string(script); else if(object_name=="constellation_lines") params.filename_lines= read_string(script); else if(object_name=="boundaries") params.filename_boundaries= read_string(script); else if(object_name=="milky_way") params.filename_milkyway= read_string(script); else if(object_name=="latex_preamble") params.filename_preamble= read_string(script); else if(object_name=="include"){ if(!params.filename_include.empty()) throw string("Nesting depth of include files greater" " than one"); params.filename_include= read_string(script); ifstream included_script(params.filename_include.c_str()); if(!included_script.good()) cerr<<"pp3: Warning: included file " <>param_name; if(param_name=="center_rectascension") script>>params.center_rectascension; else if(param_name=="center_declination") script>>params.center_declination; else if(param_name=="box_width") script>>params.view_frame_width; else if(param_name=="box_height") script>>params.view_frame_height; else if(param_name=="grad_per_cm") script>>params.grad_per_cm; else if(param_name=="constellation") params.constellation= read_string(script); else if(param_name=="shortest_constellation_line") script>>params.shortest_constellation_line; else if(param_name=="label_skip") script>>params.label_skip; else if(param_name=="minimal_nebula_radius") script>>params.minimal_nebula_radius; else if(param_name=="faintest_cluster_magnitude") script>>params.faintest_cluster_magnitude; else if(param_name=="faintest_diffuse_nebula_magnitude") script>>params.faintest_diffuse_nebula_magnitude; else if(param_name=="faintest_star_magnitude") script>>params.faintest_star_magnitude; else if(param_name=="minimal_star_radius") script>>params.minimal_star_radius; else if(param_name=="faintest_star_disk_magnitude") script>>params.faintest_star_disk_magnitude; else if(param_name=="faintest_star_with_label_magnitude") script>>params.faintest_star_with_label_magnitude; else if(param_name=="star_scaling") script>>params.star_scaling; else if(param_name=="fontsize") script>>params.font_size; else throw string("Undefined \"set\" construct in input script: \"") +param_name+'"'; } /*:20*/ #line 580 "pp3.w" else throw string("Undefined opcode in input script: \"") +opcode+'"'; script>>opcode; } } /*:13*//*21:*/ #line 998 "pp3.w" typedef map index_list; /*:21*//*23:*/ #line 1041 "pp3.w" bool assure_valid_catalogue_index(const int index,const index_list&catalogue, const string catalogue_name){ if(catalogue.find(index)==catalogue.end()){ cerr<<"pp3: Warning: Invalid "< &flamsteed){ bool found= true; if(flamsteed.find(constellation)==flamsteed.end())found= false; else if(flamsteed[constellation].find(index)== flamsteed[constellation].end())found= false; if(!found)cerr<<"pp3: Warning: Invalid Flamsteed number: " < &flamsteed, vector &found_stars,vector &found_nebulae){ found_stars.clear(); found_nebulae.clear(); string catalogue_name; int catalogue_index; script>>catalogue_name; while(script&&catalogue_name!=";"){ script>>catalogue_index; if(catalogue_index<=0){ stringstream error_message; error_message<<"Invalid index: "<>catalogue_name; } } /*:24*//*25:*/ #line 1131 "pp3.w" view_data*identify_object(istream&script,index_list&ngc, index_list&ic,index_list&messier, index_list&henry_draper, map &flamsteed, stars_list&stars,nebulae_list&nebulae){ string catalogue_name; int catalogue_index; script>>catalogue_name>>catalogue_index; if(!script)throw string("Unexpected end of input script"); if(catalogue_name=="NGC"){ if(assure_valid_catalogue_index(catalogue_index,ngc,"NGC")) return&nebulae[ngc[catalogue_index]]; }else if(catalogue_name=="IC"){ if(assure_valid_catalogue_index(catalogue_index,ic,"IC")) return&nebulae[ic[catalogue_index]]; }else if(catalogue_name=="M"){ if(assure_valid_catalogue_index(catalogue_index,messier,"M")) return&nebulae[messier[catalogue_index]]; }else if(catalogue_name=="HD"){ if(assure_valid_catalogue_index(catalogue_index,henry_draper)) return&stars[henry_draper[catalogue_index]]; }else{ if(assure_valid_catalogue_index(catalogue_index, catalogue_name,flamsteed)) return&stars[flamsteed[catalogue_name][catalogue_index]]; } return 0; } /*:25*//*26:*/ #line 1174 "pp3.w" void read_objects_and_labels(istream&script, const dimensions_list&dimensions, objects_list&objects,stars_list&stars, nebulae_list&nebulae, texts_list&texts, flexes_list&flexes, const transformation&mytransform, bool included= false){ if(!params.filename_include.empty()&&!included){ ifstream included_file(params.filename_include.c_str()); /*27:*/ #line 1230 "pp3.w" string token; included_file>>token; while(included_file){ if(token[0]=='#')getline(included_file,token); else if(token=="objects_and_labels")break; included_file>>token; } /*:27*/ #line 1185 "pp3.w" read_objects_and_labels(included_file,dimensions,objects,stars, nebulae,texts,flexes,mytransform,true); } string opcode; script>>opcode; if(!script)return; /*22:*/ #line 1012 "pp3.w" const int max_ngc= 7840,max_ic= 5386,max_messier= 110; index_list ngc,ic,messier; for(int i= 0;i 0&&nebulae[i].ngc<=max_ngc) ngc[nebulae[i].ngc]= i; if(nebulae[i].ic> 0&&nebulae[i].ic<=max_ic) ic[nebulae[i].ic]= i; if(nebulae[i].messier> 0&&nebulae[i].messier<=max_messier) messier[nebulae[i].messier]= i; } index_list henry_draper; map flamsteed; for(int i= 0;i 0)henry_draper[stars[i].hd]= i; if(stars[i].flamsteed> 0) flamsteed[stars[i].constellation][stars[i].flamsteed]= i; } /*:22*/ #line 1192 "pp3.w" while(script){ if(opcode[0]=='#'){ string rest_of_line; getline(script,rest_of_line); }else /*28:*/ #line 1255 "pp3.w" if(opcode=="reposition"){ string position,semicolon; view_data*current_object= identify_object(script,ngc,ic,messier,henry_draper, flamsteed,stars,nebulae); int angle; bool on_baseline= false; script>>position>>semicolon; if(semicolon!=";") throw string("Expected \";\" after \"reposition\" command"); /*29:*/ #line 1276 "pp3.w" if(position=="E"||position=="E_")angle= 0; else if(position=="NE")angle= 1; else if(position=="N")angle= 2; else if(position=="NW")angle= 3; else if(position=="W"||position=="W_")angle= 4; else if(position=="SW")angle= 5; else if(position=="S")angle= 6; else if(position=="SE")angle= 7; else throw string("Undefined position angle: ")+position; on_baseline= position[position.length()-1]=='_'; /*:29*/ #line 1267 "pp3.w" if(current_object){ current_object->label_angle= angle; current_object->with_label= visible; current_object->on_baseline= on_baseline; current_object->label_arranged= true; } } /*:28*/ #line 1198 "pp3.w" else /*30:*/ #line 1293 "pp3.w" if(opcode=="set_label_text"){ view_data*current_object= identify_object(script,ngc,ic,messier,henry_draper, flamsteed,stars,nebulae); if(current_object)current_object->label= read_string(script); } /*:30*/ #line 1200 "pp3.w" else /*35:*/ #line 1409 "pp3.w" if(opcode=="text"){ string token,contents,position("NE"); double rectascension,declination; contents= read_string(script); script>>token; if(token!="at")throw string("\"at\" in \"text\" command expected"); script>>rectascension>>declination; script>>token; int angle= 1; bool on_baseline= false; enum{kind_text_label,kind_flex_declination}label_kind = kind_text_label; double step_rectascension= -1.0; double step_declination= -1.0; while(script&&token!=";"){ if(token=="color")script>>params.textlabelcolor; else if(token=="towards"){ script>>position; /*29:*/ #line 1276 "pp3.w" if(position=="E"||position=="E_")angle= 0; else if(position=="NE")angle= 1; else if(position=="N")angle= 2; else if(position=="NW")angle= 3; else if(position=="W"||position=="W_")angle= 4; else if(position=="SW")angle= 5; else if(position=="S")angle= 6; else if(position=="SE")angle= 7; else throw string("Undefined position angle: ")+position; on_baseline= position[position.length()-1]=='_'; /*:29*/ #line 1429 "pp3.w" } else if(token=="along"){ script>>token; if(token=="declination"){ label_kind= kind_flex_declination; }else throw string("Invalid \"along\" option"); } else if(token=="tics"){ script>>token; if(token=="rectascension"){ script>>step_rectascension; if(step_rectascension<=0.0) throw string("Invalid \"tics\" interval"); step_declination= -1.0; }else if(token=="declination"){ script>>step_declination; if(step_declination<=0.0) throw string("Invalid \"tics\" interval"); step_rectascension= -1.0; }else throw string("Invalid \"tics\" option"); }else throw string("Invalid \"text\" option"); script>>token; } if(!script) throw string("Unexpected end of script while scanning \"text\""); if(step_rectascension<=0.0&&step_declination<=0.0){ /*36:*/ #line 1481 "pp3.w" switch(label_kind){ case kind_text_label: texts.push_back(text(contents,rectascension,declination, params.textlabelcolor,angle,on_baseline)); break; case kind_flex_declination: flexes.push_back(new declination_flex(contents,rectascension, declination, params.textlabelcolor,angle, on_baseline)); break; } /*:36*/ #line 1456 "pp3.w" }if(step_rectascension> 0.0){ string user_pattern(contents); double start= rectascension-floor(rectascension/step_rectascension) *step_rectascension; for(rectascension= start;rectascension<24.0; rectascension+= step_rectascension){cerr< 0.0)coordinates<<'+'; coordinates< 0.0){ string user_pattern(contents); double start= declination-floor((declination+90.0)/step_declination) *step_declination; for(declination= start;declination<=90.0; declination+= step_declination){cerr< 0.0)coordinates<<'+'; coordinates< found_stars,found_nebulae; /*31:*/ #line 1305 "pp3.w" if(opcode=="delete_labels"){ search_objects(script,ngc,ic,messier,henry_draper, flamsteed,found_stars,found_nebulae); for(int i= 0;i>opcode; } } /*:26*/ #line 3838 "pp3.w" int main(int argc,char**argv){ try{ /*118:*/ #line 3887 "pp3.w" if(argc==2){ if(argv[1][0]!='-'){ params.in= new ifstream(argv[1]); if(!params.in->good()) throw string("Input script file ")+argv[1] +" not found"; else params.input_file= true; }else if(!strcmp(argv[1],"-"))params.in= &cin;else cerr<<"Invalid argument: "<