编译选项一定要加 -lgdi32 !!!

数据库:#1 #2 #3 #4

A 版

#include <bits/stdc++.h>
#include <windows.h>
#include <conio.h>
#define color(x) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),x)
#define curpos(x,y) SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),{y,x})
using namespace std;
vector<pair<int,int> >lsts[2][20000];set<int>lstp[2], nstp[2];map<pair<int,int>,int> mp,blo;int isid,lstv,lsti;
struct CuSO4{HDC Hdc;
CuSO4() {Hdc=GetDC(GetConsoleWindow());
	for (int i=0; i<100; ++i) {
		for (int j=0; j<100; ++j) {
			SetPixel(Hdc,i,j,0);}}}
void Plot(int x, int y, int R, int G, int B) {
	if (R+G+B) lsts[lstv][lsti].push_back(make_pair(x,y));
	SetPixel(Hdc, y+30, x+30, R+(G<<8)+(B<<16));}
int Get(int x, int y) {
	int tmp = GetPixel(Hdc, y+30, x+30);
	int R = (tmp&((1<<8)-1));
	int G = ((tmp>>8)&((1<<8)-1));
	int B = (tmp>>16);
	return (R<<16)+(G<<8)+B;}
int Get(pair<int,int> p) {
	int x=p.first, y=p.second;
	int tmp = GetPixel(Hdc, y+30, x+30);
	int R = (tmp&((1<<8)-1));
	int G = ((tmp>>8)&((1<<8)-1));
	int B = (tmp>>16);
	return (R<<16)+(G<<8)+B;}
void Plot(int x, int y, int clr) {
	Plot(x, y, (clr>>16), ((clr>>8)&((1<<8)-1)), (clr&((1<<8)-1)));}
void Plot(pair<int,int> x, int clr) {
	mp[x]=clr; blo[x]=isid;
	if ((abs(x.first-400)>400)||(abs(x.second-750)>750)) return;
	Plot(x.first, x.second, (clr>>16), ((clr>>8)&((1<<8)-1)), (clr&((1<<8)-1)));}
int Mix(int ca, int cb, double rt) {
	int Ar=(ca>>16),Ag=((ca>>8)&((1<<8)-1)),Ab=(ca&((1<<8)-1)),
	Br=(cb>>16),Bg=((cb>>8)&((1<<8)-1)),Bb=(cb&((1<<8)-1));
	int R=int(floor(rt*double(Ar)+(1.0-rt)*double(Br)));int G=int(floor(rt*double(Ag)+(1.0-rt)*double(Bg)));int B=int(floor(rt*double(Ab)+(1.0-rt)*double(Bb)));
	return (max(0,min(255,R))<<16)+(max(0,min(255,G))<<8)+max(0,min(255,B));}
int Light(int ca) {
	int Ar=(ca>>16),
	Ag=((ca>>8)&((1<<8)-1)),
	Ab=(ca&((1<<8)-1));
	return Ar+Ag+Ab;}
}Sc;
struct node{double w,j,l,c;int cst;}prest[20000];
vector<node>stlst[2];vector<int>dyo[2];double _ds[20000],_fw[20000],ang=0.0;
int C,prec;double vvrat=2.0;bool nhor=1,marked[2][15000];
bool sort_by_light(node a,node b){return a.l<b.l;}
int Get(pair<int,int>p){return mp[p];}
pair<int,int>getpos(double x,double y){return make_pair(int(round(x))+400,int(round(y))+750);}
int maxl(int a,int b){return (Sc.Light(a)>Sc.Light(b))?a:b;}
const int BrightRed     = 0xFF9999;
const int BrightBlue    = 0x99FFFF;
const int Bright        = 0xFFFFFF;
const int DarkRed       = 0xFF6666;
const int DarkBlue      = 0x6666FF;
const int Selected      = 0xEE0000;
const int Marked        = 0x9999FF;
const int Constellation = 0x66CCFF;
const int Invisible     = 0x006666;
void run(int vcid, int at, double _lim, double _rlim, double deltaw, double deltaj, bool xg) {
	deltaw = fmod(fmod(deltaw+360.0,360.0)+360.0,360.0)/360.0;
	double p1=acos(-1.0), p2=p1*2.0;
	deltaj = fmod(fmod(deltaj+360.0,360.0)+360.0,360.0)/360.0*p2;
	int cc = 0;
	for (int i=0; i<stlst[vcid].size(); ++i) {
		double w=stlst[vcid][i].w*4.0, j=stlst[vcid][i].j, l=stlst[vcid][i].l;
		j = fmod(j+double(at)*deltaj+p2,p2);
		double s=sin(j), c=cos(j);
		double px=-s*w, py=-c*w;
		double lim = _lim;
		int clr = 0x000000;
		double stc = stlst[vcid][i].c;
		if (l<lim) continue;
		double flg = 1.0;
		double PX=px, PY=py;
		if (fabs(py)!=360.0) {
			bool flag = false;
			if (py<0.0) {
				py=-py; flag=true;
			}
			if (fabs(py)<1e-06) {
				px+=360.0; px+=1440.0*deltaw;
				while (px>=720.0) {
					px-=720.0; flg=-flg;
				}
				if (flg<0) px=720.0-px;
				px -= 360.0;
			}
			else {
				double A=0.0, K=py/360.0;
				if (fabs(px)>=1e-06) {
					bool flag = false;
					if (px<0.0) {
						px=-px; flag=true;
					}
					double MX=px*0.5, MY=(py+360.0)*0.5, MK=-(360.0-py)/px;
					MK=-1.0/MK; double MB=MY-MK*MX, OX=-MB/MK;
					double R=sqrt(py*py+(px-OX)*(px-OX)); A=(R+OX)/360.0*90.0;
					double TA=atan2(360.0,-OX), CA=atan2(py,px-OX);
					K = CA/TA;
					if (flag) {
						A=-A; px=-px;
					}
					double AG = TA*K;
					PY=sin(AG)*R; PX=OX+cos(AG)*R;
					if (flag) PX=-PX;
				}
				A += 90.0+360.0*deltaw;
				while (A>=180.0) {
					A-=180.0; flg=-flg;
				}
				if (flg<0) A=180.0-A;
				A -= 90.0;
				px=0; py=K*360.0;
				if (fabs(A)>1e-06) {
					bool flag = false;
					if (A<0.0) {
						flag=true; A=-A;
					}
					double MX=A*2.0, MY=180.0;
					double MK=-360.0/(A*4.0); MK=-1.0/MK;
					double MB=MY-MK*MX, OX=-MB/MK;
					double R=4.0*A-OX, TA=atan2(360.0,-OX);
					double AG = TA*K;
					py=sin(AG)*R; px=OX+cos(AG)*R;
					if (flag) px=-px;
				}
			}
			if (flag) py=-py,PY=-PY;
		}
		if (vcid) px=-px;
		if (at*flg<0) {
			double dss=sqrt(px*px+py*py), dwx, dwy;
			if (dss<1e-06) {
				dwx=1.0; dwy=0.0;
			}
			else {
				dwx=px/dss; dwy=py/dss;
			}
			dss=720.0-dss; px=dwx*dss; py=dwy*dss;
		}
		if (px*px+py*py>720.0*720.0) {
			double dss=sqrt(px*px+py*py), dwx=-px/dss, dwy=-py/dss;
			px+=dwx*1440.0; py+=dwy*1440.0;
		}
		double dss=sqrt(px*px+py*py), ag=_fw[dyo[vcid][i]]=atan2(px,py);
		_fw[dyo[vcid][i]] = -_fw[dyo[vcid][i]]+p1*0.5;
		ag=fmod(ag+fmod(fmod(ang,360.0)+360.0,360.0)/360.0*p2,p2);
		px=sin(ag)*dss; py=cos(ag)*dss;
		_ds[dyo[vcid][i]] = sqrt(px*px+py*py)/4.0;
		bool hor = false;
		if (xg) {
			double ds = sqrt(px*px+py*py)/4.0;
			if ((ds>0.0)&&(ds<=91.0)) {
				double xrc=pow(ds/91.0,5.0); px=px/ds*(ds-xrc); py=py/ds*(ds-xrc);
			}
			ds = sqrt(px*px+py*py)/4.0;
			if (ds>90.0) l=0.0;
			else if (ds>70.0) {
				double rat=(ds-70.0)/20.0; rat=pow(rat,8.0);
				l = max(0.0,l-2.0*rat);
			}
			if (l<lim) continue;
		}
		else {
			double ds=sqrt(px*px+py*py)/4.0; if (ds>90.0) hor=true;
		}
		if (l==0.0) continue;
		if ((nhor)&&(hor)) continue;
		set<int>::iterator it=lstp[vcid].find(i);
		if (it!=lstp[vcid].end()) {
			for (int ii=0; ii<lsts[vcid][i].size(); ++ii) {
				Sc.Plot(lsts[vcid][i][ii].first,lsts[vcid][i][ii].second,0);
			}
			lsts[vcid][i].clear();
			lstp[vcid].erase(it);
		}
		nstp[vcid].insert(i); lstv=vcid; lsti=i;
		++cc;
		double ds = 0.0;
		double lll = _rlim;
		if (l>=lll) {
			ds = (l-lll)*10.0;
			double lum = max(6.0*(l-lll)*10.0+8.0,15.0)/15.0;
			if (stc<0.0) clr=Sc.Mix(BrightRed,Bright,-stc);
			else clr=Sc.Mix(BrightBlue,Bright,stc);
			clr=Sc.Mix(clr,0,lum);
		}
		else {
			double lum=(l-lim)/(lll-lim); lum=((1.0-sqrt(1.0-lum))*11.0+4.0)/15.0;
			if (stc<0.0) clr=Sc.Mix(DarkRed,Bright,-stc);
			else clr=Sc.Mix(DarkBlue,Bright,stc);
			clr = Sc.Mix(clr,0,lum);
		}
		l=(l-lim)/(1.0-lim);
		px*=vvrat; py*=vvrat;
		if (stc==1.0) clr=Selected;
		else if (marked[vcid][i]) clr=Marked;
		else if (hor) clr=Invisible;
		else if (stlst[vcid][i].cst==C) clr=Constellation;
		if (ds==0.0) {
			isid = dyo[vcid][i];
			Sc.Plot(getpos(px,py),maxl(clr,Sc.Get(getpos(px,py))));
			continue;
		}
		for (int ii=-10; ii<=10; ++ii) {
			for (int jj=-10; jj<=10; ++jj) {
				isid = dyo[vcid][i];
				if (double(ii*ii+jj*jj)<=0.0+max(0.0,l-0.9)*0.2) {
					Sc.Plot(getpos(px+ii,py+jj),maxl(clr,Get(getpos(px+ii,py+jj))));
				}
				else if (double(ii*ii+jj*jj)-ds*ds<=ds*2.0) {
					int ccr = Bright;
					if (stc==1.0) ccr=Selected;
					else if (marked[vcid][i]) clr=Marked;
					else if (hor) ccr=Invisible;
					else if (stlst[vcid][i].cst==C) ccr=Constellation;
					ccr = Sc.Mix(0,clr,sqrt((double(ii*ii+jj*jj))/(ds*2.0+ds*ds)));
					Sc.Plot(getpos(px+ii,py+jj),maxl(ccr,Sc.Get(getpos(px+ii,py+jj))));
				}
			}
		}
	}
}
void main2(double _lim, double _rlim, double dw, double dj, double xg) {
	mp.clear(); blo.clear();run(1,-1,_lim,_rlim,dw,dj,xg);run(0,1,_lim,_rlim,dw,dj,xg);}
int tid[20000][2],tl=0;double _w[20000],_j[20000],_l[20000];
void ins(double w,double j,double l,int cst) {
	++tl;_w[tl]=w;_j[tl]=j;_l[tl]=l;
	if (w<0.0) j=360.0-j;
	stlst[((w>=0.0)?0:1)].push_back((node){90.0-fabs(w),j/180.0*acos(-1.0),0.9-l*0.1,0.0,cst});
	tid[tl][0]=((w>=0.0)?0:1); tid[tl][1]=stlst[tid[tl][0]].size()-1;
	dyo[tid[tl][0]].push_back(tl);
}
#define S(a,b,c) {prest[++prec]=(node){a,b,c,0,C};}
void import() {
	#error 请用数据库替代此处 
	++C;S(24.665167,292.176708,4.44)S(27.814222,303.942333,4.50)S(27.097139,313.032208,4.56)S(24.079528,298.365333,4.57)S(27.753556,300.275042,4.66)S(21.390444,289.054333,4.76)S(25.591972,303.816208,4.79)S(21.201167,309.630375,4.81)S(22.610083,297.767042,4.90)S(25.271056,311.218833,4.92)S(19.773389,293.645375,5.00)S(28.057639,313.640167,5.03)S(24.115972,309.632958,5.06)S(23.614417,301.722500,5.08)S(19.798528,291.368917,5.14)S(23.508917,303.876000,5.18)S(28.694861,303.560500,5.19)S(26.262417,290.712000,5.22)S(24.937861,300.505708,5.23)S(24.671139,304.196167,5.30)S(22.325917,314.568125,5.30)S(27.608556,321.916792,5.39)S(23.025556,289.431833,5.46)S(25.771861,295.928833,5.50)S(24.446111,305.514292,5.50)S(26.904139,302.639667,5.51)S(26.809028,302.949875,5.51)S(24.992167,298.006625,5.54)S(24.319389,298.629417,5.56)S(26.461972,309.269417,5.59)S(20.097833,291.555167,5.60)S(28.250528,312.867667,5.66)S(26.174556,321.141542,5.67)S(23.101278,299.794083,5.68)S(21.409667,306.418833,5.68)S(24.274083,320.994750,5.70)S(24.250750,286.659833,5.78)S(24.768694,292.237833,5.82)S(19.891611,291.619542,5.84)S(24.800417,300.436292,5.88)S(26.617111,292.840042,5.89)S(26.478833,303.002917,5.91)S(23.680500,309.645792,5.91)S(25.384111,296.952083,6.00)S(21.554556,288.153000,6.02)S(21.817417,309.794292,6.08)S(26.924417,316.597708,6.13)S(24.914306,291.357792,6.19)S(25.312389,321.030917,6.20)S(21.698750,287.014542,6.22)S(21.874972,302.837583,6.24)S(29.147500,304.381417,6.24)S(27.135417,295.983208,6.27)S(22.814500,284.992167,6.28)S(22.026167,320.058625,6.29)S(20.271778,291.343333,6.31)S(22.585778,294.034792,6.33)S(20.279778,292.337083,6.34)S(24.528417,321.096292,6.35)S(25.805028,307.992458,6.37)S(20.264361,290.945542,6.40)S(25.882611,309.034667,6.40)S(22.452778,295.311042,6.43)S(22.264389,285.455917,6.44)S(28.439667,297.478000,6.45)S(22.941083,300.911708,6.45)S(27.085167,297.482542,6.46)S(26.187917,300.064000,6.49)S(20.985194,308.541583,6.49)S(20.783472,294.574125,6.50)S(22.151500,300.592125,6.50)S(28.522000,313.593292,6.55);
	sort(prest+1,prest+prec+1,sort_by_light);
	for (int i=1; i<=prec; ++i) ins(prest[i].w,prest[i].j,prest[i].l,prest[i].cst);
C=0;}
char buf[1000];
int main() {
	SetConsoleTitle("按任意键继续...");
	color(15);POINT cp;import();getch();vvrat=1.0;
	bool cls=0;double i=90.0,j=90.0-23.18,l=0.5,rat=10,spd=1;bool cl=true, zd=1,xg=0;int xid=0,tmm=time(0);
	for (;;) {
		GetCursorPos(&cp);
		if (!cl) {
			nstp[0].clear(); nstp[1].clear();
		}
		if (cl) {
			if (cls) {
				system("cls"); cls=false;
			}
			for (int ii=0; ii<2; ++ii) {
				for (set<int>::iterator it=lstp[ii].begin(); it!=lstp[ii].end(); ++it) {
					for (int jj=0; jj<lsts[ii][*it].size(); ++jj) {
						Sc.Plot(lsts[ii][*it][jj].first,lsts[ii][*it][jj].second,0);
					}
					lsts[ii][*it].clear();
				}
				lstp[ii].clear(); nstp[ii].swap(lstp[ii]);
			}
			curpos(0,0);
			if (j<=90.0) printf("纬度 %.2f° N\n",90.0-j);
			else printf("纬度 %.2f° S\n",j-90.0);
			double ddg = fmod(fmod(-i,360.0)+360.0+90.0,360.0);
			double hhh = ddg/360.0*24.0;
			double ah=hhh-fmod(hhh,1.0), amm=(hhh-ah)*60.0;
			double am=amm-fmod(amm,1.0), as=(amm-am)*60.0;
			printf("恒星时 %.6f° %.6fh\n(%.0fh %.0fmin %.0fs)\n", ddg, hhh, ah, am, as);
			printf("极限星等 %.1f\n", 10.0*(-l+0.9));
			if (j<=90.0) sprintf(buf,"(%.1f°N,%.0fh %.0fm %.0fs)",90.0-j,ah,am,as);
			else sprintf(buf,"(%.1f°S,%.0fh %.0fm %.0fs)",j-90.0,ah,am,as);
			SetConsoleTitle(buf);
			printf("角度 %.6f\n", fmod(fmod(ang,360.0)+360.0,360.0));
			if (zd) printf("运行中 (x%.3f)           ",spd);
			else printf("                      ");
			printf("\n");
			if (xid) printf("赤纬 %.6f %c            \n赤经 %.6f h           \n星等 %.2f              \n高度 %.6f              \n方位角 %.6f°              ",fabs(_w[xid]),((_w[xid]>=0.0)?'N':'S'),_j[xid]/360.0*24.0,_l[xid],90.0-_ds[xid],fmod(_fw[xid]*180.0/acos(-1.0)+360.0,360.0));
			else printf("                      \n                      \n                      \n                      \n                      \n");
		}
		main2(l,0.2*l+0.4,j,i,xg); cl=false;
		cp.x-=30; cp.y-=50;
		char ch=' '; while (kbhit()) ch=getch();
		cl = true;
		if (ch=='s') {
			if (j>0.0) j=max(j-rat,0.0);
		}
		else if (ch=='w') {
			if (j<180.0) j=min(j+rat,180.0);
		}
		else if (ch=='d') i-=rat;
		else if (ch=='a') i+=rat;
		else if (ch=='g') ang-=rat;
		else if (ch=='f') ang+=rat;
		else if (ch=='G') ang=0.0;
		else if (ch=='F') ang=0.0;
		else if (ch=='o') {
			if (l>0.25) l-=0.01;
			cls=1;
		}
		else if (ch=='p') {
			if (l<1.0) l+=0.01;
			cls=1;
		}
		else if (ch=='O') l=0.25,cls=1;
		else if (ch=='P') l=0.5,cls=1;
		else if (ch=='z') vvrat*=1.2;
		else if (ch=='x') vvrat/=1.2;
		else if (ch=='Z') vvrat=3.0;
		else if (ch=='X') vvrat=1.0;
		else if (ch=='k') spd*=1.2;
		else if (ch=='l') spd/=1.2;
		else if (ch=='K') spd=1.0;
		else if (ch=='L') spd=1.0;
		else if (ch=='t') rat*=1.2,cl=false;
		else if (ch=='y') rat/=1.2,cl=false;
		else if (ch=='T') rat=1.0,cl=false;
		else if (ch=='Y') rat=1.0,cl=false;
		else if (ch=='c') {
			zd=!zd; if (zd) tmm=time(0);
		}
		else if (ch=='q') xg=!xg;
		else if (ch=='h') nhor=!nhor;
		else if (ch=='m') {
			int iid = blo[(pair<int,int>)make_pair(int(cp.y),int(cp.x))];
			for (int ii=-5; ii<=5; ++ii) {
				for (int jj=-5; jj<=5; ++jj) {
					if ((!i)&&(!j)) continue;
					if (iid) continue;
					iid = blo[(pair<int,int>)make_pair(int(cp.y+ii),int(cp.x+jj))];
				}
			}
			if (xid) stlst[tid[xid][0]][tid[xid][1]].c=0.0;
			if (iid) {
				stlst[tid[iid][0]][tid[iid][1]].c=1.0; C=stlst[tid[iid][0]][tid[iid][1]].cst;
			}
			else C=0;
			xid = iid;
		}
		else if (ch=='n') {
			int iid = blo[(pair<int,int>)make_pair(int(cp.y),int(cp.x))];
			for (int ii=-5; ii<=5; ++ii) {
				for (int jj=-5; jj<=5; ++jj) {
					if ((!i)&&(!j)) continue;
					if (iid) continue;
					iid = blo[(pair<int,int>)make_pair(int(cp.y+ii),int(cp.x+jj))];
				}
			}
			if (iid) marked[tid[iid][0]][tid[iid][1]]^=1;
		}
		else cl=false;
		if (zd) {
			int ntm = time(0);
			if (tmm!=ntm) {
				i-=spd*360.0/(23.0*3600.0+56.0*60.0+4.09)*double(ntm-tmm); tmm=ntm;
				cl = true;
			}
		}
	}
	return 0;
}

B 版

#include <bits/stdc++.h>
#include <windows.h>
#include <conio.h>
#define color(x) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),x)
#define curpos(x,y) SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),{y,x})
using namespace std;
vector<pair<int,int> >lsts[2][20000];set<int>lstp[2], nstp[2];map<pair<int,int>,int> mp,blo;int isid,lstv,lsti;
struct CuSO4{HDC Hdc;
CuSO4() {Hdc=GetDC(GetConsoleWindow());
	for (int i=0; i<100; ++i) {
		for (int j=0; j<100; ++j) {
			SetPixel(Hdc,i,j,0);}}}
void Plot(int x, int y, int R, int G, int B) {
	if (R+G+B) lsts[lstv][lsti].push_back(make_pair(x,y));
	SetPixel(Hdc, y+30, x+30, R+(G<<8)+(B<<16));}
int Get(int x, int y) {
	int tmp = GetPixel(Hdc, y+30, x+30);
	int R = (tmp&((1<<8)-1));
	int G = ((tmp>>8)&((1<<8)-1));
	int B = (tmp>>16);
	return (R<<16)+(G<<8)+B;}
int Get(pair<int,int> p) {
	int x=p.first, y=p.second;
	int tmp = GetPixel(Hdc, y+30, x+30);
	int R = (tmp&((1<<8)-1));
	int G = ((tmp>>8)&((1<<8)-1));
	int B = (tmp>>16);
	return (R<<16)+(G<<8)+B;}
void Plot(int x, int y, int clr) {
	Plot(x, y, (clr>>16), ((clr>>8)&((1<<8)-1)), (clr&((1<<8)-1)));}
void Plot(pair<int,int> x, int clr) {
	mp[x]=clr; blo[x]=isid;
	if (((x.first<0)||(x.first>1600))||((x.second<0)||(x.second>2200))) return;
	Plot(x.first, x.second, (clr>>16), ((clr>>8)&((1<<8)-1)), (clr&((1<<8)-1)));}
int Mix(int ca, int cb, double rt) {
	int Ar=(ca>>16),Ag=((ca>>8)&((1<<8)-1)),Ab=(ca&((1<<8)-1)),
	Br=(cb>>16),Bg=((cb>>8)&((1<<8)-1)),Bb=(cb&((1<<8)-1));
	int R=int(floor(rt*double(Ar)+(1.0-rt)*double(Br)));int G=int(floor(rt*double(Ag)+(1.0-rt)*double(Bg)));int B=int(floor(rt*double(Ab)+(1.0-rt)*double(Bb)));
	return (max(0,min(255,R))<<16)+(max(0,min(255,G))<<8)+max(0,min(255,B));}
int Light(int ca) {
	int Ar=(ca>>16),
	Ag=((ca>>8)&((1<<8)-1)),
	Ab=(ca&((1<<8)-1));
	return Ar+Ag+Ab;}
HFONT GetFont(int sz, const char* font) {
	return CreateFont(sz,0,0,0,0,0,0,0,0,0,0,0,0,font);
}
void Display(HFONT font, int x, int y, const char* str, int color=0xFFFFFF) {
	SelectObject(Hdc, font);
	int R = (color&((1<<8)-1));
	int G = ((color>>8)&((1<<8)-1));
	int B = (color>>16);
    SetTextColor(Hdc,(R<<16)|(G<<8)|B); SetBkMode(Hdc,TRANSPARENT);
    TextOut(Hdc, y+30, x+30, str, strlen(str));
}
}Sc;
struct node{double w,j,l,c;int cst;}prest[20000];
vector<node>stlst[2];vector<int>dyo[2];double _ds[20000],_fw[20000],ang=0.0;
int C,prec;double vvrat=2.0;bool nhor=1,marked[2][15000];
bool sort_by_light(node a,node b){return a.l<b.l;}
int Get(pair<int,int>p){return mp[p];}
pair<int,int>getpos(double x,double y){return make_pair(int(round(x))+400,int(round(y))+750);}
int maxl(int a,int b){return (Sc.Light(a)>Sc.Light(b))?a:b;}
const int BrightRed	 = 0xFF9999;
const int BrightBlue	= 0x99FFFF;
const int Bright		= 0xFFFFFF;
const int DarkRed	   = 0xFF6666;
const int DarkBlue	  = 0x6666FF;
const int Selected	  = 0xEE0000;
const int Marked		= 0x9999FF;
const int Constellation = 0x66CCFF;
const int Invisible	 = 0x006666;
void run(int vcid, int at, double _lim, double _rlim, double deltaw, double deltaj, bool xg) {
	deltaw = fmod(fmod(deltaw+360.0,360.0)+360.0,360.0)/360.0;
	double p1=acos(-1.0), p2=p1*2.0;
	deltaj = fmod(fmod(deltaj+360.0,360.0)+360.0,360.0)/360.0*p2;
	int cc = 0;
	for (int i=0; i<stlst[vcid].size(); ++i) {
		double w=stlst[vcid][i].w*4.0, j=stlst[vcid][i].j, l=stlst[vcid][i].l;
		j = fmod(j+double(at)*deltaj+p2,p2);
		double s=sin(j), c=cos(j);
		double px=-s*w, py=-c*w;
		double lim = _lim;
		int clr = 0x000000;
		double stc = stlst[vcid][i].c;
		if (l<lim) continue;
		double flg = 1.0;
		double PX=px, PY=py;
		if (fabs(py)!=360.0) {
			bool flag = false;
			if (py<0.0) {
				py=-py; flag=true;
			}
			if (fabs(py)<1e-06) {
				px+=360.0; px+=1440.0*deltaw;
				while (px>=720.0) {
					px-=720.0; flg=-flg;
				}
				if (flg<0) px=720.0-px;
				px -= 360.0;
			}
			else {
				double A=0.0, K=py/360.0;
				if (fabs(px)>=1e-06) {
					bool flag = false;
					if (px<0.0) {
						px=-px; flag=true;
					}
					double MX=px*0.5, MY=(py+360.0)*0.5, MK=-(360.0-py)/px;
					MK=-1.0/MK; double MB=MY-MK*MX, OX=-MB/MK;
					double R=sqrt(py*py+(px-OX)*(px-OX)); A=(R+OX)/360.0*90.0;
					double TA=atan2(360.0,-OX), CA=atan2(py,px-OX);
					K = CA/TA;
					if (flag) {
						A=-A; px=-px;
					}
					double AG = TA*K;
					PY=sin(AG)*R; PX=OX+cos(AG)*R;
					if (flag) PX=-PX;
				}
				A += 90.0+360.0*deltaw;
				while (A>=180.0) {
					A-=180.0; flg=-flg;
				}
				if (flg<0) A=180.0-A;
				A -= 90.0;
				px=0; py=K*360.0;
				if (fabs(A)>1e-06) {
					bool flag = false;
					if (A<0.0) {
						flag=true; A=-A;
					}
					double MX=A*2.0, MY=180.0;
					double MK=-360.0/(A*4.0); MK=-1.0/MK;
					double MB=MY-MK*MX, OX=-MB/MK;
					double R=4.0*A-OX, TA=atan2(360.0,-OX);
					double AG = TA*K;
					py=sin(AG)*R; px=OX+cos(AG)*R;
					if (flag) px=-px;
				}
			}
			if (flag) py=-py,PY=-PY;
		}
		if (vcid) px=-px;
		if (at*flg<0) {
			double dss=sqrt(px*px+py*py), dwx, dwy;
			if (dss<1e-06) {
				dwx=1.0; dwy=0.0;
			}
			else {
				dwx=px/dss; dwy=py/dss;
			}
			dss=720.0-dss; px=dwx*dss; py=dwy*dss;
		}
		if (px*px+py*py>720.0*720.0) {
			double dss=sqrt(px*px+py*py), dwx=-px/dss, dwy=-py/dss;
			px+=dwx*1440.0; py+=dwy*1440.0;
		}
		double dss=sqrt(px*px+py*py), ag=_fw[dyo[vcid][i]]=atan2(px,py);
		_fw[dyo[vcid][i]] = -_fw[dyo[vcid][i]]+p1*0.5;
		ag=fmod(ag+fmod(fmod(ang,360.0)+360.0,360.0)/360.0*p2,p2);
		px=sin(ag)*dss; py=cos(ag)*dss;
		_ds[dyo[vcid][i]] = sqrt(px*px+py*py)/4.0;
		bool hor = false;
		if (xg) {
			double ds = sqrt(px*px+py*py)/4.0;
			if ((ds>0.0)&&(ds<=91.0)) {
				double xrc=pow(ds/91.0,5.0); px=px/ds*(ds-xrc); py=py/ds*(ds-xrc);
			}
			ds = sqrt(px*px+py*py)/4.0;
			if (ds>90.0) l=0.0;
			else if (ds>70.0) {
				double rat=(ds-70.0)/20.0; rat=pow(rat,8.0);
				l = max(0.0,l-2.0*rat);
			}
			if (l<lim) continue;
		}
		else {
			double ds=sqrt(px*px+py*py)/4.0; if (ds>90.0) hor=true;
		}
		if (l==0.0) continue;
		if ((nhor)&&(hor)) continue;
		set<int>::iterator it=lstp[vcid].find(i);
		if (it!=lstp[vcid].end()) {
			for (int ii=0; ii<lsts[vcid][i].size(); ++ii) {
				Sc.Plot(lsts[vcid][i][ii].first,lsts[vcid][i][ii].second,0);
			}
			lsts[vcid][i].clear();
			lstp[vcid].erase(it);
		}
		nstp[vcid].insert(i); lstv=vcid; lsti=i;
		++cc;
		double ds = 0.0;
		double lll = _rlim;
		if (l>=lll) {
			ds = (l-lll)*10.0;
			double lum = max(6.0*(l-lll)*10.0+8.0,15.0)/15.0;
			if (stc<0.0) clr=Sc.Mix(BrightRed,Bright,-stc);
			else clr=Sc.Mix(BrightBlue,Bright,stc);
			clr=Sc.Mix(clr,0,lum);
		}
		else {
			double lum=(l-lim)/(lll-lim); lum=((1.0-sqrt(1.0-lum))*11.0+4.0)/15.0;
			if (stc<0.0) clr=Sc.Mix(DarkRed,Bright,-stc);
			else clr=Sc.Mix(DarkBlue,Bright,stc);
			clr = Sc.Mix(clr,0,lum);
		}
		l=(l-lim)/(1.0-lim);
		px*=vvrat; py*=vvrat;
		if (stc==1.0) clr=Selected;
		else if (marked[vcid][i]) clr=Marked;
		else if (hor) clr=Invisible;
		else if (stlst[vcid][i].cst==C) clr=Constellation;
		if (ds==0.0) {
			isid = dyo[vcid][i];
			Sc.Plot(getpos(px,py),maxl(clr,Sc.Get(getpos(px,py))));
			continue;
		}
		for (int ii=-10; ii<=10; ++ii) {
			for (int jj=-10; jj<=10; ++jj) {
				isid = dyo[vcid][i];
				if (double(ii*ii+jj*jj)<=0.0+max(0.0,l-0.9)*0.2) {
					Sc.Plot(getpos(px+ii,py+jj),maxl(clr,Get(getpos(px+ii,py+jj))));
				}
				else if (double(ii*ii+jj*jj)-ds*ds<=ds*2.0) {
					int ccr = Bright;
					if (stc==1.0) ccr=Selected;
					else if (marked[vcid][i]) clr=Marked;
					else if (hor) ccr=Invisible;
					else if (stlst[vcid][i].cst==C) ccr=Constellation;
					ccr = Sc.Mix(0,clr,sqrt((double(ii*ii+jj*jj))/(ds*2.0+ds*ds)));
					Sc.Plot(getpos(px+ii,py+jj),maxl(ccr,Sc.Get(getpos(px+ii,py+jj))));
				}
			}
		}
	}
}
void main2(double _lim, double _rlim, double dw, double dj, double xg) {
	mp.clear(); blo.clear();run(1,-1,_lim,_rlim,dw,dj,xg);run(0,1,_lim,_rlim,dw,dj,xg);}
int tid[20000][2],tl=0;double _w[20000],_j[20000],_l[20000];
void ins(double w,double j,double l,int cst) {
	++tl;_w[tl]=w;_j[tl]=j;_l[tl]=l;
	if (w<0.0) j=360.0-j;
	stlst[((w>=0.0)?0:1)].push_back((node){90.0-fabs(w),j/180.0*acos(-1.0),0.9-l*0.1,0.0,cst});
	tid[tl][0]=((w>=0.0)?0:1); tid[tl][1]=stlst[tid[tl][0]].size()-1;
	dyo[tid[tl][0]].push_back(tl);
}
#define S(a,b,c) {prest[++prec]=(node){a,b,c,0,C};}
void import() {
	#error 将数据库导入此处 
	++C;S(24.665167,292.176708,4.44)S(27.814222,303.942333,4.50)S(27.097139,313.032208,4.56)S(24.079528,298.365333,4.57)S(27.753556,300.275042,4.66)S(21.390444,289.054333,4.76)S(25.591972,303.816208,4.79)S(21.201167,309.630375,4.81)S(22.610083,297.767042,4.90)S(25.271056,311.218833,4.92)S(19.773389,293.645375,5.00)S(28.057639,313.640167,5.03)S(24.115972,309.632958,5.06)S(23.614417,301.722500,5.08)S(19.798528,291.368917,5.14)S(23.508917,303.876000,5.18)S(28.694861,303.560500,5.19)S(26.262417,290.712000,5.22)S(24.937861,300.505708,5.23)S(24.671139,304.196167,5.30)S(22.325917,314.568125,5.30)S(27.608556,321.916792,5.39)S(23.025556,289.431833,5.46)S(25.771861,295.928833,5.50)S(24.446111,305.514292,5.50)S(26.904139,302.639667,5.51)S(26.809028,302.949875,5.51)S(24.992167,298.006625,5.54)S(24.319389,298.629417,5.56)S(26.461972,309.269417,5.59)S(20.097833,291.555167,5.60)S(28.250528,312.867667,5.66)S(26.174556,321.141542,5.67)S(23.101278,299.794083,5.68)S(21.409667,306.418833,5.68)S(24.274083,320.994750,5.70)S(24.250750,286.659833,5.78)S(24.768694,292.237833,5.82)S(19.891611,291.619542,5.84)S(24.800417,300.436292,5.88)S(26.617111,292.840042,5.89)S(26.478833,303.002917,5.91)S(23.680500,309.645792,5.91)S(25.384111,296.952083,6.00)S(21.554556,288.153000,6.02)S(21.817417,309.794292,6.08)S(26.924417,316.597708,6.13)S(24.914306,291.357792,6.19)S(25.312389,321.030917,6.20)S(21.698750,287.014542,6.22)S(21.874972,302.837583,6.24)S(29.147500,304.381417,6.24)S(27.135417,295.983208,6.27)S(22.814500,284.992167,6.28)S(22.026167,320.058625,6.29)S(20.271778,291.343333,6.31)S(22.585778,294.034792,6.33)S(20.279778,292.337083,6.34)S(24.528417,321.096292,6.35)S(25.805028,307.992458,6.37)S(20.264361,290.945542,6.40)S(25.882611,309.034667,6.40)S(22.452778,295.311042,6.43)S(22.264389,285.455917,6.44)S(28.439667,297.478000,6.45)S(22.941083,300.911708,6.45)S(27.085167,297.482542,6.46)S(26.187917,300.064000,6.49)S(20.985194,308.541583,6.49)S(20.783472,294.574125,6.50)S(22.151500,300.592125,6.50)S(28.522000,313.593292,6.55);
	sort(prest+1,prest+prec+1,sort_by_light);
	for (int i=1; i<=prec; ++i) ins(prest[i].w,prest[i].j,prest[i].l,prest[i].cst);
C=0;}
char buf[1000];
char content[1000]; vector<string> outstr, lststr;
void outputtext() {
	for (int i=0; i<lststr.size(); ++i) Sc.Display(Sc.GetFont(32,"华文楷体"),i*36,0,lststr[i].data(),0x000000);
	lststr.clear(); bool sel=false;
	for (int i=0; i<outstr.size(); ++i) {
		if (outstr[i]=="已选中 :") sel=true;
		Sc.Display(Sc.GetFont(32,"华文楷体"),i*36,0,outstr[i].data(),(sel)?0x66CCFF:0x9999FF);
		lststr.push_back(outstr[i]);
	}
}
int main() {
	SetConsoleTitle("按任意键继续...");
	color(15);POINT cp;import();getch();vvrat=1.0;
	bool cls=0;double i=90.0,j=90.0-23.18,l=0.5,rat=10,spd=1;bool cl=true, zd=1,xg=0;int xid=0,tmm=time(0);
	double Rat=1.5, DeltaX=-60.0, DeltaY=-30.0;
	for (;;) {
		GetCursorPos(&cp);
		if (!cl) {
			nstp[0].clear(); nstp[1].clear();
		}
		if (cl) {
			if (cls) {
				system("cls"); cls=false;
			}
			for (int ii=0; ii<2; ++ii) {
				for (set<int>::iterator it=lstp[ii].begin(); it!=lstp[ii].end(); ++it) {
					for (int jj=0; jj<lsts[ii][*it].size(); ++jj) {
						Sc.Plot(lsts[ii][*it][jj].first,lsts[ii][*it][jj].second,0);
					}
					lsts[ii][*it].clear();
				}
				lstp[ii].clear(); nstp[ii].swap(lstp[ii]);
			}
			curpos(0,0); outstr.clear();
			if (j<=90.0) {
				sprintf(content,"纬度 %.2f° N",90.0-j); outstr.push_back(content);
			}
			else {
				sprintf(content,"纬度 %.2f° S",j-90.0); outstr.push_back(content);
			}
			double ddg = fmod(fmod(-i,360.0)+360.0+90.0,360.0);
			double hhh = ddg/360.0*24.0;
			double ah=hhh-fmod(hhh,1.0), amm=(hhh-ah)*60.0;
			double am=amm-fmod(amm,1.0), as=(amm-am)*60.0;
			sprintf(content, "恒星时 %.6f° %.6fh\n(%.0fh %.0fmin %.0fs)\n", ddg, hhh, ah, am, as);
			outstr.push_back(content);
			sprintf(content, "极限星等 %.1f\n", 10.0*(-l+0.9));
			outstr.push_back(content);
			if (j<=90.0) sprintf(buf,"(%.1f°N,%.0fh %.0fm %.0fs)",90.0-j,ah,am,as);
			else sprintf(buf,"(%.1f°S,%.0fh %.0fm %.0fs)",j-90.0,ah,am,as);
			SetConsoleTitle(buf);
			sprintf(content, "角度 %.6f\n", fmod(fmod(ang,360.0)+360.0,360.0));
			outstr.push_back(content);
			if (zd) {
				sprintf(content,"运行中 (x%.3f)",spd); outstr.push_back(content);
			}
			if (xid) {
				outstr.push_back("已选中 :");
				sprintf(content,"赤纬 %.6f %c",fabs(_w[xid]),((_w[xid]>=0.0)?'N':'S')); outstr.push_back(content);
				sprintf(content,"赤经 %.6f h",_j[xid]/360.0*24.0); outstr.push_back(content);
				sprintf(content,"星等 %.2f",_l[xid]); outstr.push_back(content);
				sprintf(content,"高度 %.6f°",90.0-_ds[xid]); outstr.push_back(content);
				sprintf(content,"方位角 %.6f°",fmod(_fw[xid]*180.0/acos(-1.0)+360.0,360.0)); outstr.push_back(content);
			}
			outputtext();
		}
		main2(l,0.2*l+0.4,j,i,xg); cl=false;
		cp.y=round(double(cp.y)*Rat+DeltaX);
		cp.x=(double(cp.x)*Rat+DeltaY);
		char ch=' '; while (kbhit()) ch=getch();
		cl = true;
		if (ch=='s') {
			if (j>0.0) j=max(j-rat,0.0);
		}
		else if (ch=='w') {
			if (j<180.0) j=min(j+rat,180.0);
		}
		else if (ch=='d') i-=rat;
		else if (ch=='a') i+=rat;
		else if (ch=='g') ang-=rat;
		else if (ch=='f') ang+=rat;
		else if (ch=='G') ang=0.0;
		else if (ch=='F') ang=0.0;
		else if (ch=='o') {
			if (l>0.25) l-=0.01;
			cls=1;
		}
		else if (ch=='p') {
			if (l<1.0) l+=0.01;
			cls=1;
		}
		else if (ch=='O') l=0.25,cls=1;
		else if (ch=='P') l=0.5,cls=1;
		else if (ch=='z') vvrat*=1.2;
		else if (ch=='x') vvrat/=1.2;
		else if (ch=='Z') vvrat=3.0;
		else if (ch=='X') vvrat=1.0;
		else if (ch=='k') spd*=1.2;
		else if (ch=='l') spd/=1.2;
		else if (ch=='K') spd=1.0;
		else if (ch=='L') spd=1.0;
		else if (ch=='t') rat*=1.2,cl=false;
		else if (ch=='y') rat/=1.2,cl=false;
		else if (ch=='T') rat=1.0,cl=false;
		else if (ch=='Y') rat=1.0,cl=false;
		else if (ch=='c') {
			zd=!zd; if (zd) tmm=time(0);
		}
		else if (ch=='q') xg=!xg;
		else if (ch=='h') nhor=!nhor;
		else if (ch=='m') {
			int iid = blo[(pair<int,int>)make_pair(int(cp.y),int(cp.x))];
			for (int ii=-5; ii<=5; ++ii) {
				for (int jj=-5; jj<=5; ++jj) {
					if ((!i)&&(!j)) continue;
					if (iid) continue;
					iid = blo[(pair<int,int>)make_pair(int(cp.y+ii),int(cp.x+jj))];
				}
			}
			if (xid) stlst[tid[xid][0]][tid[xid][1]].c=0.0;
			if (iid) {
				stlst[tid[iid][0]][tid[iid][1]].c=1.0; C=stlst[tid[iid][0]][tid[iid][1]].cst;
			}
			else C=0;
			xid = iid;
		}
		else if (ch=='n') {
			int iid = blo[(pair<int,int>)make_pair(int(cp.y),int(cp.x))];
			for (int ii=-5; ii<=5; ++ii) {
				for (int jj=-5; jj<=5; ++jj) {
					if ((!i)&&(!j)) continue;
					if (iid) continue;
					iid = blo[(pair<int,int>)make_pair(int(cp.y+ii),int(cp.x+jj))];
				}
			}
			if (iid) marked[tid[iid][0]][tid[iid][1]]^=1;
		}
		else cl=false;
		if (zd) {
			int ntm = time(0);
			if (tmm!=ntm) {
				i-=spd*360.0/(23.0*3600.0+56.0*60.0+4.09)*double(ntm-tmm); tmm=ntm;
				cl = true;
			}
		}
	}
	return 0;
}