szdytom 792d099976 完成问题5和6
Signed-off-by: szdytom <szdytom@163.com>
2023-04-21 13:34:54 +08:00

108 lines
3.6 KiB
C++

#include<bits/stdc++.h>
#define N 100
using namespace std;
struct vec
{
float x,y;
void operator += (const vec &a) {x+=a.x,y+=a.y;}
void operator -= (const vec &a) {x-=a.x,y-=a.y;}
void operator *= (float a) {x*=a,y*=a;}
vec operator + (const vec &a) const {vec b=(*this);b+=a;return b;}
vec operator - (const vec &a) const {vec b=(*this);b-=a;return b;}
vec operator * (float a) const {vec b=(*this);b*=a;return b;}
float norm(){return sqrt(x*x+y*y);}
}p[N];
const float XL=0.1; //左边框留白比例
const float XR=0.1; //右边框留白比例
const float YL=0.1; //上边框留白比例
const float YR=0.1; //下边框留白比例
const float vertex_R=.1; //点的半径
const float border_width=.01; //点的边框粗细
const string border_color="#616161"; //点的边框和边的颜色
const map<string,string> mp{{"b","#29B6F6"},{"r","#FF7043"}}; //颜色映射表
const string label = "A"; // 标签格式
const string font_family = "Ubuntu Mono"; // 字体
const string font_color = "white"; // 标签颜色
const float output_scale = 100;
vec calc(vec a,vec b)
{
vec c=b-a;
c*=(vertex_R-border_width/2)/c.norm();
return a+c;
}
int n,m;
float minX,minY,maxX,maxY;
string pc[N];
void printhelp(const char* name)
{
printf(
"g2s the 6east svg graph generator, built on %s.\n"
"Usage: %s <inputfile> <outputfile>\n"
,__DATE__,name);
exit(1);
}
int main(int argc,char** argv)
{
if(argc!=3) printhelp(argv[0]);
freopen(argv[1],"r",stdin);
freopen(argv[2],"w",stdout);
cin>>n; //输入点数(int)
for(int i=1;i<=n;i++)
{
cin>>p[i].x>>p[i].y>>pc[i];
//输入第i个点的横坐标(float)、纵坐标(float)、半径(float)和颜色(string)
if(mp.find(pc[i])!=mp.end()) pc[i]=mp.find(pc[i])->second;
if(i==1) minX=maxX=p[i].x,minY=maxY=p[i].y;
if(p[i].x<minX) minX=p[i].x;
else if(p[i].x>maxX) maxX=p[i].x;
if(p[i].y<minY) minY=p[i].y;
else if(p[i].y>maxY) maxY=p[i].y;
}
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"(<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="%f" height="%f" viewBox="0 0 %f %f" version="1.1">)",
X * output_scale, Y * output_scale, X * output_scale, Y * output_scale);
for(int i=1;i<=n;i++)
{
cout<<"<circle style=\"fill-rule:evenodd;fill:"<<pc[i]<<
";fill-opacity:1;stroke-width:"<<border_width*output_scale<<
";stroke-linecap:square;stroke-linejoin:miter;stroke:"<<border_color<<
";stroke-miterlimit:"<<border_width*0.7*output_scale<<
";\" cx=\""<<p[i].x*output_scale<<"\" cy=\""<<p[i].y*output_scale<<"\" r=\""<<vertex_R*output_scale<<"\"/>"<<endl;
}
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]);
cout<<"<path style=\"fill:none;stroke-width:"<<border_width*output_scale<<
";stroke-linecap:butt;stroke-linejoin:miter;stroke:"<<border_color<<
";stroke-miterlimit:"<<border_width*0.7*output_scale<<
";\" d=\"M "<<A.x*output_scale<<" "<<A.y*output_scale<<" L "<<B.x*output_scale<<" "<<B.y*output_scale<<" \"/>"<<endl;
}
if (label == "A" || label == "a") {
for (int i = 1; i <= n; ++i) {
printf(R"(<text font-family="%s" fill="%s" font-size="%f" style="text-anchor: middle;dominant-baseline: middle;"><tspan x="%f" y="%f">%c</tspan></text>
)", font_family.c_str(), font_color.c_str(), vertex_R * output_scale, p[i].x * output_scale, p[i].y * output_scale, i + label[0] - 1);
}
}
cout<<"</svg>"<<endl;
return 0;
}