#include #define N 100 using namespace std; float XL=0.1; float XR=0.1; float YL=0.1; float YR=0.1; float vertex_R=.1; float border_width=.01; float output_scale = 100; string border_color="#616161"; string label = "none"; string font_family = "Atkinson Hyperlegible"; string font_color = "white"; string Xdir="right"; string Ydir="down"; string output_file="g2s_output.svg"; string output_shape="default"; map color_map,label_map; const map float_config_item{ {"OutputScale",&output_scale}, //输出比例 {"XL",&XL}, //左边框留白比例 {"XR",&XR}, //右边框留白比例 {"YL",&YL}, //上边框留白比例 {"YR",&YR}, //下边框留白比例 {"R",&vertex_R}, //点的半径 {"Thickness",&border_width} //点的边框粗细 }; const map string_config_item{ {"BorderColor",&border_color}, //点的边框和边的颜色 {"Label",&label}, // 标签格式 {"FontFamily",&font_family}, // 标签字体 {"FontColor",&font_color}, // 标签颜色 {"Xaxis",&Xdir}, //x轴正方向 {"Yaxis",&Ydir}, //y轴正方向 {"OutputFile",&output_file}, //输出文件名 {"OutputShape",&output_shape} //输出形状 }; const map> string_config_item_options{ {"Label",{"a","A","1","none"}}, {"Xaxis",{"left","right"}}, {"Yaxis",{"up","down"}}, {"OutputShape",{"default","square"}} }; //ColorMap: 颜色映射表 void getstring(string &s) { getchar(); s.clear(); char ch=getchar(); while(ch!='\"') s+=ch,ch=getchar(); } void printlist(vector vec) { fprintf(stderr,R"("%s")",vec[0].c_str()); for(size_t i=1;i+11) fprintf(stderr,R"( and "%s")",vec.back().c_str()); } void init() { for(int line=1;;line++) { char ch=getchar(); while(ch!='-'&&!isalpha(ch)) ch=getchar(); if(ch=='-') { while(ch=='-') ch=getchar(); break; } string s; while(isalpha(ch)) s+=ch,ch=getchar(); if(float_config_item.find(s)!=float_config_item.end()) cin>>*(float_config_item.at(s)); else if(string_config_item.find(s)!=string_config_item.end()) { getstring(*(string_config_item.at(s))); if(string_config_item_options.find(s)!=string_config_item_options.end()) { bool bel=0; auto vec=string_config_item_options.at(s); string ss=s; s=*string_config_item.at(s); for(string t:vec) bel|=(s==t); if(!bel) { fprintf(stderr,R"(Error on line %d: "%s" is not a valid option of "%s" Valid options: )",line,s.c_str(),ss.c_str()); printlist(vec); fprintf(stderr,".\n"); exit(1); } } } else if(s=="ColorMap") { s.clear(); ch=getchar(); while(ch!='=') s+=ch,ch=getchar(); getstring(color_map[s]); } else if(s=="LabelMap") { s.clear(); ch=getchar(); while(ch!='=') s+=ch,ch=getchar(); getstring(label_map[s]); } else { fprintf(stderr,R"(Error on line %d: "%s" is not a valid config item. Valid config items: )",line,s.c_str()); vector vec; for(const auto &it:float_config_item) vec.push_back(it.first); for(const auto &it:string_config_item) vec.push_back(it.first); printlist(vec); fprintf(stderr,".\n"); exit(1); } } } struct vec { float x,y; void operator += (vec a) {x+=a.x,y+=a.y;} void operator -= (vec a) {x-=a.x,y-=a.y;} void operator *= (float a) {x*=a,y*=a;} vec operator + (vec a) const {vec b=(*this);b+=a;return b;} vec operator - (vec a) const {vec b=(*this);b-=a;return b;} vec operator * (float a) const {vec b=(*this);b*=a;return b;} float norm() const {return sqrt(x*x+y*y);} }; vec calc(vec a,vec b) { vec c=b-a; c*=(vertex_R-border_width/2)/c.norm(); return a+c; } void printlabel(vec p,string s) { if(label_map.find(s)!=label_map.end()) s=label_map.at(s); printf(R"(%s )", font_family.c_str(), font_color.c_str(), vertex_R, p.x, p.y+vertex_R*0.3, s.c_str()); } int n,m; float minX,minY,maxX,maxY; string pc[N]; vec p[N]; void printhelp(char* name) { printf( "g2s the 6east svg graph generator, built on %s.\n" "Usage: %s \n" ,__DATE__,name); exit(1); } int main(int argc,char** argv) { if(argc!=2) printhelp(argv[0]); freopen(argv[1],"r",stdin); init(); freopen(output_file.c_str(),"w",stdout); vertex_R*=output_scale; border_width*=output_scale; cin>>n; //输入点数(int) for(int i=1;i<=n;i++) { cin>>p[i].x>>p[i].y>>pc[i]; //输入第i个点的横坐标(float)、纵坐标(float)、半径(float)和颜色(string) p[i].x*=output_scale,p[i].y*=output_scale; if(Xdir=="left") p[i].x=-p[i].x; if(Ydir=="up") p[i].y=-p[i].y; if(color_map.find(pc[i])!=color_map.end()) pc[i]=color_map.find(pc[i])->second; if(i==1) minX=maxX=p[i].x,minY=maxY=p[i].y; if(p[i].xmaxX) maxX=p[i].x; if(p[i].ymaxY) maxY=p[i].y; } if(output_shape=="square") { float delta=((maxX-minX)-(maxY-minY))*0.5; if(delta>0) minY-=delta,maxY+=delta; else delta=-delta,minX-=delta,maxX+=delta; } minX-=vertex_R,minY-=vertex_R; maxX+=vertex_R,maxY+=vertex_R; float X=minX-(maxX-minX)*XL; float Y=minY-(maxY-minY)*YL; for(int i=1;i<=n;i++) p[i].x-=X,p[i].y-=Y; X=(maxX-X)+(maxX-minX)*XR; Y=(maxY-Y)+(maxY-minY)*YR; printf(R"( )", X, Y, X, Y); for(int i=1;i<=n;i++) { printf(R"( )",pc[i].c_str(),border_width,border_color.c_str(),border_width*0.7,p[i].x,p[i].y,vertex_R); } cin>>m; //输入边数(int) for(int i=1;i<=m;i++) { int a,b; cin>>a>>b; //输入端点编号(int[1,n]) vec A=calc(p[a],p[b]); vec B=calc(p[b],p[a]); printf(R"( )",border_width,border_color.c_str(),border_width*0.7,A.x,A.y,B.x,B.y); } if (label == "A" || label == "a") { for (int i = 1; i <= n; ++i) { printlabel(p[i],string{char(i + label[0] - 1)}); } } else if(label=="1") { for (int i = 1; i <= n; ++i) { printlabel(p[i],to_string(i)); } } puts(""); return 0; }