📄 plot.c
字号:
ra *= c; dec *= c; if(dec == 0) d1 = c, d2 = c; else if(dec < 0) d1 = c, d2 = 0; else d1 = 0, d2 = c; }else if(r->type==SAO || r->type==NGC || r->type==Planet || r->type==Abell){ ra = r->ngc.ra; dec = r->ngc.dec; d1 = 0, d2 = 0, r0 = 0; }else continue; if(dec+d2+extradec > decmax) decmax = dec+d2+extradec; if(dec-d1-extradec < decmin) decmin = dec-d1-extradec; if(folded){ ra -= 180*c; if(ra < 0) ra += 360*c; } if(ra+r0+extrara > ramax) ramax = ra+r0+extrara; if(ra-extrara < ramin) ramin = ra-extrara; } if(decmax > 90*c) decmax = 90*c; if(decmin < -90*c) decmin = -90*c; if(ramin < 0) ramin += 360*c; if(ramax >= 360*c) ramax -= 360*c; if(quantize){ /* quantize to degree boundaries */ ramin -= ramin%m5; if(ramax%m5 != 0) ramax += m5-(ramax%m5); if(decmin > 0) decmin -= decmin%c; else decmin -= c - (-decmin)%c; if(decmax > 0){ if(decmax%c != 0) decmax += c-(decmax%c); }else if(decmax < 0){ if(decmax%c != 0) decmax += ((-decmax)%c); } } if(folded){ if(ramax-ramin > 270*c){ fprint(2, "ra range too wide %ld°\n", (ramax-ramin)/c); return -1; } }else if(ramax-ramin > 270*c){ folded = 1; return bbox(0, 0, quantize); } return 1;}intinbbox(DAngle ra, DAngle dec){ int min; if(dec < decmin) return 0; if(dec > decmax) return 0; min = ramin; if(ramin > ramax){ /* straddling 0h0m */ min -= 360*c; if(ra > 180*c) ra -= 360*c; } if(ra < min) return 0; if(ra > ramax) return 0; return 1;}intgridra(long mapdec){ mapdec = abs(mapdec)+c/2; mapdec /= c; if(mapdec < 60) return m5; if(mapdec < 80) return 2*m5; if(mapdec < 85) return 4*m5; return 8*m5;}#define GREY (nogrey? display->white : grey)voidplot(char *flags){ int i, j, k; char *t; long x, y; int ra, dec; int m; Point p, pts[10]; Record *r; Rectangle rect, r1; int dx, dy, nogrid, textlevel, nogrey, zenithup; Image *scr; char *name, buf[32]; double v; if(plotopen() < 0) return; nogrid = 0; nogrey = 0; textlevel = 1; dx = 512; dy = 512; zenithup = 0; for(;;){ if(t = alpha(flags, "nogrid")){ nogrid = 1; flags = t; continue; } if((t = alpha(flags, "zenith")) || (t = alpha(flags, "zenithup")) ){ zenithup = 1; flags = t; continue; } if((t = alpha(flags, "notext")) || (t = alpha(flags, "nolabel")) ){ textlevel = 0; flags = t; continue; } if((t = alpha(flags, "alltext")) || (t = alpha(flags, "alllabel")) ){ textlevel = 2; flags = t; continue; } if(t = alpha(flags, "dx")){ dx = strtol(t, &t, 0); if(dx < 100){ fprint(2, "dx %d too small (min 100) in plot\n", dx); return; } flags = skipbl(t); continue; } if(t = alpha(flags, "dy")){ dy = strtol(t, &t, 0); if(dy < 100){ fprint(2, "dy %d too small (min 100) in plot\n", dy); return; } flags = skipbl(t); continue; } if((t = alpha(flags, "nogrey")) || (t = alpha(flags, "nogray"))){ nogrey = 1; flags = skipbl(t); continue; } if(*flags){ fprint(2, "syntax error in plot\n"); return; } break; } flatten(); folded = 0; if(bbox(0, 0, 1) < 0) return; if(ramax-ramin<100 || decmax-decmin<100){ fprint(2, "plot too small\n"); return; } scr = allocimage(display, Rect(0, 0, dx, dy), RGB24, 0, DBlack); if(scr == nil){ fprint(2, "can't allocate image: %r\n"); return; } rect = scr->r; rect.min.x += 16; rect = insetrect(rect, 40); if(setmap(ramin, ramax, decmin, decmax, rect, zenithup) < 0){ fprint(2, "can't set up map coordinates\n"); return; } if(!nogrid){ for(x=ramin; ; ){ for(j=0; j<nelem(pts); j++){ /* use double to avoid overflow */ v = (double)j / (double)(nelem(pts)-1); v = decmin + v*(decmax-decmin); pts[j] = map(x, v); } bezspline(scr, pts, nelem(pts), Endsquare, Endsquare, 0, GREY, ZP); ra = x; if(folded){ ra -= 180*c; if(ra < 0) ra += 360*c; } p = pts[0]; p.x -= stringwidth(font, hm5(angle(ra)))/2; string(scr, p, GREY, ZP, font, hm5(angle(ra))); p = pts[nelem(pts)-1]; p.x -= stringwidth(font, hm5(angle(ra)))/2; p.y -= font->height; string(scr, p, GREY, ZP, font, hm5(angle(ra))); if(x == ramax) break; x += gridra(mapdec); if(x > ramax) x = ramax; } for(y=decmin; y<=decmax; y+=c){ for(j=0; j<nelem(pts); j++){ /* use double to avoid overflow */ v = (double)j / (double)(nelem(pts)-1); v = ramin + v*(ramax-ramin); pts[j] = map(v, y); } bezspline(scr, pts, nelem(pts), Endsquare, Endsquare, 0, GREY, ZP); p = pts[0]; p.x += 3; p.y -= font->height/2; string(scr, p, GREY, ZP, font, deg(angle(y))); p = pts[nelem(pts)-1]; p.x -= 3+stringwidth(font, deg(angle(y))); p.y -= font->height/2; string(scr, p, GREY, ZP, font, deg(angle(y))); } } /* reorder to get planets in front of stars */ tolast(nil); tolast("moon"); /* moon is in front of everything... */ tolast("shadow"); /* ... except the shadow */ for(i=0,r=rec; i<nrec; i++,r++){ dec = r->ngc.dec; ra = r->ngc.ra; if(folded){ ra -= 180*c; if(ra < 0) ra += 360*c; } if(textlevel){ name = nameof(r); if(name==nil && textlevel>1 && r->type==SAO){ snprint(buf, sizeof buf, "SAO%ld", r->index); name = buf; } if(name) drawname(scr, nogrey? display->white : alphagrey, name, ra, dec); } if(r->type == Planet){ drawplanet(scr, &r->planet, map(ra, dec)); continue; } if(r->type == SAO){ m = r->sao.mag; if(m == UNKNOWNMAG) m = r->sao.mpg; if(m == UNKNOWNMAG) continue; m = dsize(m); if(m < 3) fillellipse(scr, map(ra, dec), m, m, nogrey? display->white : lightgrey, ZP); else{ ellipse(scr, map(ra, dec), m+1, m+1, 0, display->black, ZP); fillellipse(scr, map(ra, dec), m, m, display->white, ZP); } continue; } if(r->type == Abell){ ellipse(scr, addpt(map(ra, dec), Pt(-3, 2)), 2, 1, 0, lightblue, ZP); ellipse(scr, addpt(map(ra, dec), Pt(3, 2)), 2, 1, 0, lightblue, ZP); ellipse(scr, addpt(map(ra, dec), Pt(0, -2)), 1, 2, 0, lightblue, ZP); continue; } switch(r->ngc.type){ case Galaxy: j = npixels(r->ngc.diam); if(j < 4) j = 4; if(j > 10) k = j/3; else k = j/2; ellipse(scr, map(ra, dec), j, k, 0, lightblue, ZP); break; case PlanetaryN: p = map(ra, dec); j = npixels(r->ngc.diam); if(j < 3) j = 3; ellipse(scr, p, j, j, 0, green, ZP); line(scr, Pt(p.x, p.y+j+1), Pt(p.x, p.y+j+4), Endsquare, Endsquare, 0, green, ZP); line(scr, Pt(p.x, p.y-(j+1)), Pt(p.x, p.y-(j+4)), Endsquare, Endsquare, 0, green, ZP); line(scr, Pt(p.x+j+1, p.y), Pt(p.x+j+4, p.y), Endsquare, Endsquare, 0, green, ZP); line(scr, Pt(p.x-(j+1), p.y), Pt(p.x-(j+4), p.y), Endsquare, Endsquare, 0, green, ZP); break; case DiffuseN: case NebularCl: p = map(ra, dec); j = npixels(r->ngc.diam); if(j < 4) j = 4; r1.min = Pt(p.x-j, p.y-j); r1.max = Pt(p.x+j, p.y+j); if(r->ngc.type != DiffuseN) draw(scr, r1, ocstipple, ocstipple, ZP); line(scr, Pt(p.x-j, p.y-j), Pt(p.x+j, p.y-j), Endsquare, Endsquare, 0, green, ZP); line(scr, Pt(p.x-j, p.y+j), Pt(p.x+j, p.y+j), Endsquare, Endsquare, 0, green, ZP); line(scr, Pt(p.x-j, p.y-j), Pt(p.x-j, p.y+j), Endsquare, Endsquare, 0, green, ZP); line(scr, Pt(p.x+j, p.y-j), Pt(p.x+j, p.y+j), Endsquare, Endsquare, 0, green, ZP); break; case OpenCl: p = map(ra, dec); j = npixels(r->ngc.diam); if(j < 4) j = 4; fillellipse(scr, p, j, j, ocstipple, ZP); break; case GlobularCl: j = npixels(r->ngc.diam); if(j < 4) j = 4; p = map(ra, dec); ellipse(scr, p, j, j, 0, lightgrey, ZP); line(scr, Pt(p.x-(j-1), p.y), Pt(p.x+j, p.y), Endsquare, Endsquare, 0, lightgrey, ZP); line(scr, Pt(p.x, p.y-(j-1)), Pt(p.x, p.y+j), Endsquare, Endsquare, 0, lightgrey, ZP); break; } } flushimage(display, 1); displayimage(scr);}intruncommand(char *command, int p[2]){ switch(rfork(RFPROC|RFFDG|RFNOWAIT)){ case -1: return -1; default: break; case 0: dup(p[1], 1); close(p[0]); close(p[1]); execl("/bin/rc", "rc", "-c", command, nil); fprint(2, "can't exec %s: %r", command); exits(nil); } return 1;}voidparseplanet(char *line, Planetrec *p){ char *fld[6]; int i, nfld; char *s; if(line[0] == '\0') return; line[10] = '\0'; /* terminate name */ s = strrchr(line, ' '); if(s == nil) s = line; else s++; strcpy(p->name, s); for(i=0; s[i]!='\0'; i++) p->name[i] = tolower(s[i]); p->name[i] = '\0'; nfld = getfields(line+11, fld, nelem(fld), 1, " "); p->ra = dangle(getra(fld[0])); p->dec = dangle(getra(fld[1])); p->az = atof(fld[2])*MILLIARCSEC; p->alt = atof(fld[3])*MILLIARCSEC; p->semidiam = atof(fld[4])*1000; if(nfld > 5) p->phase = atof(fld[5]); else p->phase = 0;}voidastro(char *flags, int initial){ int p[2]; int i, n, np; char cmd[256], buf[4096], *lines[20], *fld[10]; snprint(cmd, sizeof cmd, "/bin/astro -p %s", flags); if(pipe(p) < 0){ fprint(2, "can't pipe: %r\n"); return; } if(runcommand(cmd, p) < 0){ close(p[0]); close(p[1]); fprint(2, "can't run astro: %r"); return; } close(p[1]); n = readn(p[0], buf, sizeof buf-1); if(n <= 0){ fprint(2, "no data from astro\n"); return; } if(!initial) Bwrite(&bout, buf, n); buf[n] = '\0'; np = getfields(buf, lines, nelem(lines), 0, "\n"); if(np <= 1){ fprint(2, "astro: not enough output\n"); return; } Bprint(&bout, "%s\n", lines[0]); Bflush(&bout); /* get latitude and longitude */ if(getfields(lines[0], fld, nelem(fld), 1, " ") < 8) fprint(2, "astro: can't read longitude: too few fields\n"); else{ mysid = getra(fld[5])*180./PI; mylat = getra(fld[6])*180./PI; mylon = getra(fld[7])*180./PI; } /* * Each time we run astro, we generate a new planet list * so multiple appearances of a planet may exist as we plot * its motion over time. */ planet = malloc(NPlanet*sizeof planet[0]); if(planet == nil){ fprint(2, "astro: malloc failed: %r\n"); exits("malloc"); } memset(planet, 0, NPlanet*sizeof planet[0]); for(i=1; i<np; i++) parseplanet(lines[i], &planet[i-1]);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -