00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "PsFile.h"
00033 #include <cmath>
00034
00035 namespace Modelib {
00036
00037
00038 using namespace std;
00039
00040
00041
00042 void PSFile::begin_figure(
00043 double _xmin, double _xmax,
00044 double _ymin, double _ymax,
00045
00046 double _hmin, double _hmax,
00047 double _vmin, double _vmax,
00048
00049 int xn, int yn
00050 )
00051 {
00052
00053 save_scales(
00054 _xmin, _xmax, _ymin, _ymax,
00055 _hmin, _hmax, _vmin, _vmax
00056 );
00057
00058 char *date = asctime( localtime( NULL ) );
00059
00060 psfile << "%%!PS-Adobe-2.0 EPSF-2.0" << endl;
00061 psfile << "%%%%CreationDate: "<< date << endl;
00062 psfile << "%%%%BoundingBox: "<< hmin<<' '<<vmin<<' '<<hmax<<' '<<vmax<<endl;
00063 psfile << "%%%%Pages: 1" << endl;
00064 psfile << "%%%%EndComments" << endl;
00065
00066 psfile << "/$maindict 6400 dict def " << endl;
00067 psfile << "$maindict begin" << endl;
00068
00069 define_procs();
00070 define_caption_procs();
00071
00072 psfile << "end" << endl;
00073 psfile << "%%%%EndProlog" << endl;
00074
00075 psfile << "%%%%Page: 1" << endl;
00076 psfile << "$maindict begin" << endl;
00077 psfile << "/savedstate save def" << endl;
00078
00079 setup_page_state(xn, yn);
00080 setup_caption_data();
00081
00082 psfile.flush();
00083 }
00084
00085 void PSFile::end_figure()
00086 {
00087 aux_end_page();
00088 psfile << "%%%%Trailer" << endl;
00089 psfile.flush();
00090 }
00091
00092 void PSFile::begin_document()
00093 {
00094 psfile << "%%!PS-Adobe-2.0" << endl;
00095 psfile << "%%%%Pages: (atend)" << endl;
00096 psfile << "%%%%EndComments" << endl;
00097
00098 psfile << "/$maindict 6400 dict def " << endl;
00099 psfile << "$maindict begin" << endl;
00100
00101 define_procs();
00102 define_caption_procs();
00103
00104 psfile << "end" << endl;
00105 psfile << "%%%%EndProlog" << endl;
00106
00107 psfile.flush();
00108 }
00109
00110 void PSFile::end_document(int npages)
00111 {
00112 psfile << "%%%%Trailer" << endl;
00113 psfile << "%%%%Pages: "<< npages << endl;
00114 psfile.flush();
00115 }
00116
00117 void PSFile::begin_page(
00118 int page,
00119 double _xmin, double _xmax,
00120 double _ymin, double _ymax,
00121
00122 double _hmin, double _hmax,
00123 double _vmin, double _vmax,
00124
00125 int xn, int yn
00126 )
00127 {
00128 char *date = "";
00129 save_scales(
00130 _xmin, _xmax, _ymin, _ymax,
00131 _hmin, _hmax, _vmin, _vmax
00132 );
00133
00134 psfile << "%%%%Page: "<< page << ' ' << page << endl;
00135 psfile << "" << endl;
00136
00137 psfile << "$maindict begin" << endl;
00138 psfile << "/savedstate save def" << endl;
00139
00140 psfile << "%% Print date:" << endl;
00141 psfile << "gsave" << endl;
00142 psfile << " /Courier findfont" << endl;
00143 psfile << " 10 scalefont setfont" << endl;
00144 psfile << " 80 18 moveto" << endl;
00145 psfile << " ("<<date<<" page "<<page<<") show"<<endl;
00146 psfile << "grestore" << endl;
00147 psfile << "" << endl;
00148
00149 setup_page_state(xn, yn);
00150 setup_caption_data();
00151 }
00152
00153 void PSFile::end_page()
00154 {
00155 psfile << "showpage" << endl;
00156 psfile << "" << endl;
00157 aux_end_page();
00158 }
00159
00160 void PSFile::save_scales(
00161 double _xmin, double _xmax,
00162 double _ymin, double _ymax,
00163 double _hmin, double _hmax,
00164 double _vmin, double _vmax
00165 )
00166 {
00167 hmin = _hmin;
00168 hmax = _hmax;
00169 xmin = _xmin;
00170 xmax = _xmax;
00171 xscale = (hmax - hmin)/(xmax - xmin);
00172
00173 vmin = _vmin;
00174 vmax = _vmax;
00175 ymin = _ymin;
00176 ymax = _ymax;
00177 yscale = (vmax - vmin)/(ymax - ymin);
00178
00179 }
00180
00181 void PSFile::define_procs()
00182 {
00183 psfile << "%% Rectangle draw op:" << endl;
00184 psfile << "%% /xlo/ /xhi/ /ylo/ /yhi/ recd --> " << endl;
00185 psfile << "/recd" << endl;
00186 psfile << "{" << endl;
00187 psfile << " gsave" << endl;
00188 psfile << " newpath" << endl;
00189 psfile << " 3 index 2 index moveto" << endl;
00190 psfile << " 2 index 2 index lineto" << endl;
00191 psfile << " 2 index 1 index lineto" << endl;
00192 psfile << " 3 index 1 index lineto" << endl;
00193 psfile << " pop pop pop pop" << endl;
00194 psfile << " closepath" << endl;
00195 psfile << " stroke" << endl;
00196 psfile << " grestore" << endl;
00197 psfile << "} def" << endl;
00198 psfile << "" << endl;
00199
00200 psfile << "%% Rectangle fill op:" << endl;
00201 psfile << "%% /xlo/ /xhi/ /ylo/ /yhi/ /gray/ recf --> " << endl;
00202 psfile << "/recf" << endl;
00203 psfile << "{" << endl;
00204 psfile << " gsave" << endl;
00205 psfile << " setgray" << endl;
00206 psfile << " newpath" << endl;
00207 psfile << " 3 index 2 index moveto" << endl;
00208 psfile << " 2 index 2 index lineto" << endl;
00209 psfile << " 2 index 1 index lineto" << endl;
00210 psfile << " 3 index 1 index lineto" << endl;
00211 psfile << " pop pop pop pop" << endl;
00212 psfile << " closepath" << endl;
00213 psfile << " fill" << endl;
00214 psfile << " grestore" << endl;
00215 psfile << "} def" << endl;
00216 psfile << "" << endl;
00217
00218 psfile << "%% Rectangle fill and stroke op:" << endl;
00219 psfile << "%% /xlo/ /xhi/ /ylo/ /yhi/ /gray/ recfd --> " << endl;
00220 psfile << "/recfd" << endl;
00221 psfile << "{" << endl;
00222 psfile << " gsave" << endl;
00223 psfile << " newpath" << endl;
00224 psfile << " 4 index 3 index moveto" << endl;
00225 psfile << " 3 index 3 index lineto" << endl;
00226 psfile << " 3 index 2 index lineto" << endl;
00227 psfile << " 4 index 2 index lineto" << endl;
00228 psfile << " closepath" << endl;
00229 psfile << " gsave setgray fill grestore" << endl;
00230 psfile << " stroke" << endl;
00231 psfile << " pop pop pop pop" << endl;
00232 psfile << " grestore" << endl;
00233 psfile << "} def" << endl;
00234 psfile << "" << endl;
00235
00236 psfile << "%% Polygon draw op:" << endl;
00237 psfile << "%% /x1/ /y1/ .. /xn/ /yn/ /n/ pold --> " << endl;
00238 psfile << "/pold" << endl;
00239 psfile << "{" << endl;
00240 psfile << " gsave" << endl;
00241 psfile << " newpath" << endl;
00242 psfile << " 3 1 roll moveto" << endl;
00243 psfile << " 1 sub 1 1 3 2 roll { pop lineto } for" << endl;
00244 psfile << " closepath" << endl;
00245 psfile << " stroke" << endl;
00246 psfile << " grestore" << endl;
00247 psfile << "} def" << endl;
00248 psfile << "" << endl;
00249
00250 psfile << "%% Polygon fill op:" << endl;
00251 psfile << "%% /x1/ /y1/ .. /xn/ /yn/ /n/ /gray/ polf --> " << endl;
00252 psfile << "/polf" << endl;
00253 psfile << "{" << endl;
00254 psfile << " gsave" << endl;
00255 psfile << " setgray" << endl;
00256 psfile << " newpath" << endl;
00257 psfile << " 3 1 roll moveto" << endl;
00258 psfile << " 1 sub 1 1 3 2 roll { pop lineto } for" << endl;
00259 psfile << " closepath" << endl;
00260 psfile << " fill" << endl;
00261 psfile << " grestore" << endl;
00262 psfile << "} def" << endl;
00263 psfile << "" << endl;
00264
00265 psfile << "%% Polygon fill and draw op:" << endl;
00266 psfile << "%% /x1/ /y1/ .. /xn/ /yn/ /n/ /gray/ polfd --> " << endl;
00267 psfile << "/polfd" << endl;
00268 psfile << "{" << endl;
00269 psfile << " gsave" << endl;
00270 psfile << " newpath" << endl;
00271 psfile << " 4 2 roll moveto" << endl;
00272 psfile << " exch 1 sub" << endl;
00273 psfile << " %% -- /x1/ /y1/ .. /x[n-1]/ /y[n-1]/ /gray/ /n-1/" << endl;
00274 psfile << " 1 1 3 2 roll { pop 3 1 roll lineto } for" << endl;
00275 psfile << " closepath" << endl;
00276 psfile << " gsave setgray fill grestore" << endl;
00277 psfile << " stroke" << endl;
00278 psfile << " grestore" << endl;
00279 psfile << "} def" << endl;
00280 psfile << "" << endl;
00281
00282 psfile << "%% Circle fill op:" << endl;
00283 psfile << "%% /x/ /y/ /radius/ /gray/ cirf --> " << endl;
00284 psfile << "/cirf" << endl;
00285 psfile << "{" << endl;
00286 psfile << " gsave" << endl;
00287 psfile << " setgray" << endl;
00288 psfile << " newpath" << endl;
00289 psfile << " 0 360 arc" << endl;
00290 psfile << " closepath" << endl;
00291 psfile << " fill" << endl;
00292 psfile << " grestore" << endl;
00293 psfile << "} def" << endl;
00294 psfile << "" << endl;
00295
00296 psfile << "%% Circle draw op:" << endl;
00297 psfile << "%% /x/ /y/ /radius/ cird --> " << endl;
00298 psfile << "/cird" << endl;
00299 psfile << "{" << endl;
00300 psfile << " gsave" << endl;
00301 psfile << " newpath" << endl;
00302 psfile << " 0 360 arc" << endl;
00303 psfile << " closepath" << endl;
00304 psfile << " stroke" << endl;
00305 psfile << " grestore" << endl;
00306 psfile << "} def" << endl;
00307 psfile << "" << endl;
00308
00309 psfile << "%% Circle fill and draw op:" << endl;
00310 psfile << "%% /x/ /y/ /radius/ /gray/ cirfd --> " << endl;
00311 psfile << "/cirfd" << endl;
00312 psfile << "{" << endl;
00313 psfile << " gsave" << endl;
00314 psfile << " 4 1 roll" << endl;
00315 psfile << " newpath" << endl;
00316 psfile << " 0 360 arc" << endl;
00317 psfile << " closepath" << endl;
00318 psfile << " gsave setgray fill grestore" << endl;
00319 psfile << " stroke" << endl;
00320 psfile << " grestore" << endl;
00321 psfile << "} def" << endl;
00322 psfile << "" << endl;
00323
00324 psfile << "%% Lune fill and draw op:" << endl;
00325 psfile << "%% /xc/ /yc/ /rad/ /tilt/ /gray/ lunefd --> " << endl;
00326 psfile << "/lunefd" << endl;
00327 psfile << "{" << endl;
00328 psfile << " gsave" << endl;
00329 psfile << " 5 1 roll" << endl;
00330 psfile << " %% --- gray, xc, yc, rad, tilt" << endl;
00331 psfile << " 4 2 roll" << endl;
00332 psfile << " %% --- gray, rad, tilt, xc, yc" << endl;
00333 psfile << " translate" << endl;
00334 psfile << " %% --- gray, rad, tilt" << endl;
00335 psfile << " rotate" << endl;
00336 psfile << " %% --- gray, rad " << endl;
00337 psfile << " newpath" << endl;
00338 psfile << " dup" << endl;
00339 psfile << " %% --- gray, rad, rad" << endl;
00340 psfile << " dup neg 0" << endl;
00341 psfile << " %% --- gray, rad, rad, -rad, 0" << endl;
00342 psfile << " 3 2 roll 2 mul" << endl;
00343 psfile << " %% --- gray, rad, -rad, 0, 2*rad" << endl;
00344 psfile << " -60 60 arc" << endl;
00345 psfile << " %% --- gray, rad" << endl;
00346 psfile << " dup 0" << endl;
00347 psfile << " %% --- gray, rad, rad, 0" << endl;
00348 psfile << " 3 2 roll 2 mul" << endl;
00349 psfile << " %% --- gray, rad, 0, 2*rad" << endl;
00350 psfile << " 120 240 arc" << endl;
00351 psfile << " closepath" << endl;
00352 psfile << " gsave setgray fill grestore" << endl;
00353 psfile << " stroke" << endl;
00354 psfile << " grestore" << endl;
00355 psfile << "} def" << endl;
00356 psfile << "" << endl;
00357
00358 psfile << "%% Cell fill op:" << endl;
00359 psfile << "%% /xi/ /yi/ celf --> " << endl;
00360 psfile << "/celf" << endl;
00361 psfile << "{" << endl;
00362 psfile << " 3 1 roll " << endl;
00363 psfile << " exch dup " << endl;
00364 psfile << " xstep mul xmin add exch 1 add xstep mul xmin add" << endl;
00365 psfile << " 3 2 roll dup" << endl;
00366 psfile << " ystep mul ymin add exch 1 add ystep mul ymin add" << endl;
00367 psfile << " 5 4 roll " << endl;
00368 psfile << " recf" << endl;
00369 psfile << "} def" << endl;
00370 psfile << "" << endl;
00371
00372 psfile << "%% Triangle fill op:" << endl;
00373 psfile << "%% /xa/ /ya/ /xb/ /yb/ /xc/ /yc/ /gray/ trif --> " << endl;
00374 psfile << "/trif" << endl;
00375 psfile << "{" << endl;
00376 psfile << " gsave" << endl;
00377 psfile << " setgray" << endl;
00378 psfile << " newpath" << endl;
00379 psfile << " moveto" << endl;
00380 psfile << " lineto" << endl;
00381 psfile << " lineto" << endl;
00382 psfile << " closepath" << endl;
00383 psfile << " fill" << endl;
00384 psfile << " grestore" << endl;
00385 psfile << "} def" << endl;
00386 psfile << "" << endl;
00387
00388 psfile << "%% Segment draw op:" << endl;
00389 psfile << "%% /xa/ /ya/ /xb/ /yb/ segd --> " << endl;
00390 psfile << "/segd" << endl;
00391 psfile << "{" << endl;
00392 psfile << " gsave" << endl;
00393 psfile << " newpath" << endl;
00394 psfile << " moveto" << endl;
00395 psfile << " lineto" << endl;
00396 psfile << " stroke" << endl;
00397 psfile << " grestore" << endl;
00398 psfile << "} def" << endl;
00399 psfile << "" << endl;
00400
00401 psfile << "%% Curve draw op:" << endl;
00402 psfile << "%% /xa/ /ya/ /xb/ /yb/ /xc/ /yc/ /xd/ /yd/ arcd --> " << endl;
00403 psfile << "/arcd" << endl;
00404 psfile << "{" << endl;
00405 psfile << " gsave" << endl;
00406 psfile << " newpath" << endl;
00407 psfile << " 8 -2 roll moveto curveto" << endl;
00408 psfile << " stroke" << endl;
00409 psfile << " grestore" << endl;
00410 psfile << "} def" << endl;
00411 psfile << "" << endl;
00412
00413 psfile << "%% Draw an X-value grid line:" << endl;
00414 psfile << "%% /x/ xgrd --> " << endl;
00415 psfile << "/xgrd" << endl;
00416 psfile << "{" << endl;
00417 psfile << " gsave" << endl;
00418 psfile << " newpath" << endl;
00419 psfile << " dup ymin moveto" << endl;
00420 psfile << " ymax lineto" << endl;
00421 psfile << " stroke" << endl;
00422 psfile << " grestore" << endl;
00423 psfile << "} def" << endl;
00424 psfile << "" << endl;
00425
00426 psfile << "%% Draw an Y-value grid line:" << endl;
00427 psfile << "%% /y/ ygrd --> " << endl;
00428 psfile << "/ygrd" << endl;
00429 psfile << "{" << endl;
00430 psfile << " gsave" << endl;
00431 psfile << " newpath" << endl;
00432 psfile << " dup xmin exch moveto" << endl;
00433 psfile << " xmax exch lineto" << endl;
00434 psfile << " stroke" << endl;
00435 psfile << " grestore" << endl;
00436 psfile << "} def" << endl;
00437 psfile << "" << endl;
00438
00439 psfile << "%% Label printing op:" << endl;
00440 psfile << "%% /str/ /xa/ /ya/ /xc/ /yc/ lbsh --> " << endl;
00441 psfile << "/lbsh" << endl;
00442 psfile << "{" << endl;
00443 psfile << " labelfont setfont" << endl;
00444 psfile << " newpath moveto" << endl;
00445 psfile << " %% --- str, xa, ya" << endl;
00446 psfile << " gsave 2 index false charpath flattenpath pathbbox grestore" << endl;
00447 psfile << " %% --- str, xa, ya, lox, loy, hix, hiy" << endl;
00448 psfile << " 3 index 3 index currentpoint " << endl;
00449 psfile << " %% --- str, xa, ya, lox, loy, hix, hiy, lox, loy, cx, cy" << endl;
00450 psfile << " exch 4 1 roll exch sub" << endl;
00451 psfile << " 3 1 roll sub exch" << endl;
00452 psfile << " %% --- str, xa, ya, lox, loy, hix, hiy, cx-lox, cy-loy" << endl;
00453 psfile << " rmoveto" << endl;
00454 psfile << " %% --- str, xa, ya, lox, loy, hix, hiy" << endl;
00455 psfile << " exch 4 1 roll exch sub " << endl;
00456 psfile << " 3 1 roll sub exch" << endl;
00457 psfile << " %% --- str, xa, ya, dx, dy" << endl;
00458 psfile << " exch 4 1 roll mul -1 mul" << endl;
00459 psfile << " 3 1 roll mul -1 mul exch" << endl;
00460 psfile << " %% --- str, -dx*xa, -dy*ya" << endl;
00461 psfile << " rmoveto" << endl;
00462 psfile << " %% --- str" << endl;
00463 psfile << " show" << endl;
00464 psfile << "} def" << endl;
00465 psfile << "" << endl;
00466
00467 psfile.flush();
00468 }
00469
00470 void PSFile::define_caption_procs()
00471 {
00472 psfile << "%% op to move to new caption line:" << endl;
00473 psfile << "%% nl --> " << endl;
00474 psfile << "/nl" << endl;
00475 psfile << "{" << endl;
00476 psfile << " /ytext ytext dytext sub def" << endl;
00477 psfile << " xtext ytext moveto" << endl;
00478 psfile << "} def" << endl;
00479 psfile << "" << endl;
00480
00481 psfile << "%% op to print string at CP without clipping:" << endl;
00482 psfile << "%% /s/ shw --> " << endl;
00483 psfile << "/shw" << endl;
00484 psfile << "{" << endl;
00485 psfile << " gsave" << endl;
00486 psfile << " initclip" << endl;
00487 psfile << " captionfont setfont show" << endl;
00488 psfile << " grestore" << endl;
00489 psfile << "} def" << endl;
00490 psfile << "" << endl;
00491
00492 psfile.flush();
00493 }
00494
00495 void PSFile::setup_page_state(int xn, int yn)
00496 {
00497 double fxn = xn;
00498 double fyn = yn;
00499
00500 psfile << "%% Round joints and caps:" << endl;
00501 psfile << "1 setlinecap 1 setlinejoin" << endl;
00502 psfile << "" << endl;
00503
00504 psfile << "%% Black thin lines:" << endl;
00505 psfile << "0 setlinewidth 0 setgray [ ] 0 setdash" << endl;
00506 psfile << "" << endl;
00507
00508 psfile << "/xmin "<< hmin <<" def %% min plottable x" << endl;
00509 psfile << "/xmax "<< hmax <<" def %% max plottable x" << endl;
00510 psfile << "/xn "<< xn <<" def %% grid cells along x axis" << endl;
00511 psfile << "/xstep "<< ((hmax-hmin)/fxn) <<" def %% x-size of grid cell" << endl;
00512
00513 psfile << "/ymin "<< vmin <<" def %% min plottable y" << endl;
00514 psfile << "/ymax "<< vmax<<" def %% max plottable y" << endl;
00515 psfile << "/yn "<< yn<<" def %% grid cells along y axis" << endl;
00516 psfile << "/ystep "<< ((vmax-vmin)/fyn)<<" def %% y-size of grid cell" << endl;
00517
00518 psfile << "%% Units of measure:" << endl;
00519 psfile << "/pt 1.0 def" << endl;
00520 psfile << "/in pt 72.0 mul def " << endl;
00521 psfile << "/mm pt 72.0 25.4 div mul def" << endl;
00522 psfile << "" << endl;
00523
00524 set_label_font ("Courier", 8.0);
00525
00526 psfile << "%% Set clipping path to boundary of plot area:" << endl;
00527 psfile << "newpath" << endl;
00528 psfile << " xmin ymin moveto" << endl;
00529 psfile << " xmax ymin lineto" << endl;
00530 psfile << " xmax ymax lineto" << endl;
00531 psfile << " xmin ymax lineto" << endl;
00532 psfile << " xmin ymin lineto" << endl;
00533 psfile << "clip" << endl;
00534 psfile << "" << endl;
00535
00536 psfile.flush();
00537 }
00538
00539 void PSFile::setup_caption_data()
00540 {
00541 psfile << "%% Caption text cursor:" << endl;
00542 psfile << "/xtext xmin def" << endl;
00543 psfile << "/ytext ymin def" << endl;
00544 psfile << "/dytext 10 pt mul def" << endl;
00545 psfile << "" << endl;
00546
00547 psfile << "%% Caption font setup:" << endl;
00548 psfile << "/captionfont" << endl;
00549 psfile << " /Courier findfont" << endl;
00550 psfile << " dytext scalefont" << endl;
00551 psfile << "def" << endl;
00552 psfile << "" << endl;
00553 }
00554
00555 void PSFile::aux_end_page()
00556 {
00557 psfile << "savedstate restore" << endl;
00558 psfile << "%% Now we are back to the standard coord system." << endl;
00559 psfile << "" << endl;
00560 psfile << "end %% $maindict" << endl;
00561 psfile << "" << endl;
00562 psfile.flush();
00563 }
00564
00565 void PSFile::begin_section(char *title)
00566 {
00567 psfile << "%% "<< title << endl;
00568 psfile.flush();
00569 }
00570
00571 void PSFile::end_section()
00572 {
00573 psfile << "" << endl;
00574 psfile.flush();
00575 }
00576
00577 void PSFile::add_caption(char *txt)
00578 {
00579 psfile << "nl ";
00580 put_text(txt, ") shw\nnl (");
00581 psfile << " shw" << endl;
00582 psfile.flush();
00583 }
00584
00585 void PSFile::set_label_font(char *font, float size)
00586 {
00587 psfile << "%% Label font setup:" << endl;
00588 psfile << "/labelfont" << endl;
00589 psfile << " /"<< font<<" findfont "<< size<< " pt mul scalefont" << endl;
00590 psfile << "def" << endl;
00591 psfile << "" << endl;
00592 psfile.flush();
00593 }
00594
00595 void PSFile::put_label(
00596 char *text,
00597 double x, double y,
00598 float xalign, float yalign
00599 )
00600 {
00601 double psx = hmin + xscale * (x - xmin);
00602 double psy = vmin + yscale * (y - ymin);
00603 put_text(text, "\\267");
00604 psfile << " ";
00605 psfile << xalign<<' '<<yalign<<' '<<psx<<' '<<psy << " lbsh"<<endl;
00606 psfile.flush();
00607 }
00608
00609 void PSFile::draw_frame ()
00610 {
00611 begin_section("Draw frame around plot area");
00612 psfile << "gsave" << endl;
00613 psfile << "%% Assumes xmax, xmin, ymax, ymin are defined." << endl;
00614 psfile << " initclip" << endl;
00615 psfile << " newpath" << endl;
00616 psfile << " xmin ymin moveto" << endl;
00617 psfile << " xmax ymin lineto" << endl;
00618 psfile << " xmax ymax lineto" << endl;
00619 psfile << " xmin ymax lineto" << endl;
00620 psfile << " xmin ymin lineto" << endl;
00621 psfile << " closepath stroke" << endl;
00622 psfile << "grestore" << endl;
00623 end_section();
00624 }
00625
00626 void PSFile::set_pen(
00627
00628 double gray,
00629 double width,
00630 double dashlength,
00631 double dashspace
00632 )
00633 {
00634 psfile << gray << "setgray" << endl;
00635 psfile << "mm "<<width<<" mul setlinewidth" << endl;
00636 if ((dashlength == 0.0) | (dashspace == 0.0))
00637 {
00638 psfile << "[ ] 0 setdash" << endl;
00639 }
00640 else
00641 {
00642 psfile << "[ "<<dashlength<<" mm mul "<<dashspace<<" mm mul ] 0 setdash"<<endl;
00643 }
00644 psfile << "" << endl;
00645 psfile.flush();
00646 }
00647
00648 void PSFile::draw_segment(
00649
00650 double xa, double ya,
00651 double xb, double yb
00652 )
00653 {
00654 double psxa = hmin + xscale * (xa - xmin);
00655 double psya = vmin + yscale * (ya - ymin);
00656 double psxb = hmin + xscale * (xb - xmin);
00657 double psyb = vmin + yscale * (yb - ymin);
00658 psfile << psxa<<' '<<psya<<' '<<psxb<<' '<<psyb << "segd" << endl;
00659 psfile.flush();
00660 }
00661
00662 void PSFile::draw_curve(
00663
00664 double xa, double ya,
00665 double xb, double yb,
00666 double xc, double yc,
00667 double xd, double yd
00668 )
00669 {
00670 double psxa = hmin + xscale * (xa - xmin);
00671 double psya = vmin + yscale * (ya - ymin);
00672 double psxb = hmin + xscale * (xb - xmin);
00673 double psyb = vmin + yscale * (yb - ymin);
00674 double psxc = hmin + xscale * (xc - xmin);
00675 double psyc = vmin + yscale * (yc - ymin);
00676 double psxd = hmin + xscale * (xd - xmin);
00677 double psyd = vmin + yscale * (yd - ymin);
00678 psfile << psxa<<' '<<psya<<' '<<psxb<<' '<<psyb<<' '<<psxc<<' '<<psyc<<' '<<psxd<<' '<<psyd<<" arcd"<<endl;
00679 psfile.flush();
00680 }
00681
00682 void PSFile::aux_rectangle(
00683
00684 double xlo, double xhi,
00685 double ylo, double yhi,
00686 double gray,
00687 char *op
00688 )
00689 {
00690 double psxlo = hmin + xscale * (xlo - xmin);
00691 double psxhi = hmin + xscale * (xhi - xmin);
00692 double psylo = vmin + yscale * (ylo - ymin);
00693 double psyhi = vmin + yscale * (yhi - ymin);
00694 psfile << psxlo<<' '<<psxhi<<' '<<psylo<<' '<<psyhi;
00695 if (gray >= 0.0) psfile << ' '<< gray;
00696 psfile << " "<< op << endl;
00697 psfile.flush();
00698 }
00699
00700 void PSFile::draw_rectangle(
00701
00702 double xlo, double xhi,
00703 double ylo, double yhi
00704 )
00705 {
00706 aux_rectangle(xlo, xhi, ylo, yhi, -1.0, "recd");
00707 }
00708
00709 void PSFile::fill_rectangle(
00710
00711 double xlo, double xhi,
00712 double ylo, double yhi,
00713 double gray
00714 )
00715 {
00716 aux_rectangle(xlo, xhi, ylo, yhi, gray, "recf");
00717 }
00718
00719 void PSFile::fill_and_draw_rectangle(
00720
00721 double xlo, double xhi,
00722 double ylo, double yhi,
00723 double gray
00724 )
00725 {
00726 aux_rectangle(xlo, xhi, ylo, yhi, gray, "recfd");
00727 }
00728
00729 void PSFile::aux_polygon(
00730 double x[], double y[],
00731 int npoints,
00732 double gray,
00733 char *op
00734 )
00735 {
00736 int i;
00737 if (npoints>6) psfile << "" << endl;
00738 for (i=0; i<npoints; i++)
00739 {
00740 double psxi = hmin + xscale * (x[i] - xmin);
00741 double psyi = vmin + yscale * (y[i] - ymin);
00742 if ((i % 6) == 0)
00743 { if (i>0) psfile << "" << endl; }
00744 else
00745 { psfile << " "; }
00746 psfile << psxi<<' '<<psyi;
00747 }
00748 if (npoints>6) psfile << "" << endl;
00749 psfile << " "<< npoints<<"";
00750 if (gray >= 0.0) psfile << ' ' << gray;
00751 psfile << " "<< op << endl;
00752 psfile.flush();
00753 }
00754
00755 void PSFile::draw_polygon(
00756 double x[], double y[],
00757 int npoints
00758 )
00759 {
00760 aux_polygon(x, y, npoints, -1.0, "pold");
00761 }
00762
00763 void PSFile::fill_polygon(
00764 double x[], double y[],
00765 int npoints,
00766 double gray
00767 )
00768 {
00769 aux_polygon(x, y, npoints, gray, "polf");
00770 }
00771
00772 void PSFile::fill_and_draw_polygon(
00773 double x[], double y[],
00774 int npoints,
00775 double gray
00776 )
00777 {
00778 aux_polygon(x, y, npoints, gray, "polfd");
00779 }
00780
00781 void PSFile::aux_circle(
00782 double xc, double yc, double radius,
00783 double gray,
00784 char *op
00785 )
00786 {
00787 double psxc = hmin + xscale * (xc - xmin);
00788 double psyc = vmin + yscale * (yc - ymin);
00789 double psradius = yscale * radius;
00790 psfile << psxc<<' '<<psyc<<' '<<psradius;
00791 if (gray >= 0.0) psfile << ' ' << gray;
00792 psfile << " "<< op <<endl;
00793 psfile.flush();
00794 }
00795
00796 void PSFile::fill_circle(
00797 double xc, double yc, double radius,
00798 double gray
00799 )
00800 {
00801 aux_circle(xc, yc, radius, gray, "cirf");
00802 }
00803
00804 void PSFile::draw_circle(
00805 double xc, double yc, double radius
00806 )
00807 {
00808 aux_circle(xc, yc, radius, -1.0, "cird");
00809 }
00810
00811 void PSFile::fill_and_draw_circle(
00812 double xc, double yc, double radius,
00813 double gray
00814 )
00815 {
00816 aux_circle(xc, yc, radius, gray, "cirfd");
00817 }
00818
00819 void PSFile::aux_lune(
00820 double xc, double yc, double radius, double tilt,
00821 double gray,
00822 char *op
00823 )
00824 {
00825 double psxc = hmin + xscale * (xc - xmin);
00826 double psyc = vmin + yscale * (yc - ymin);
00827 double psradius = yscale * radius;
00828 double pstilt = tilt * 180.0 / 3.1415926;
00829 psfile << psxc<<' '<< psyc<<' '<<psradius<<' '<<pstilt;
00830 if (gray >= 0.0) psfile << ' ' << gray;
00831 psfile << " "<< op <<endl;
00832 psfile.flush();
00833 }
00834
00835 void PSFile::fill_and_draw_lune(
00836 double xc, double yc, double radius, double tilt,
00837 double gray
00838 )
00839 {
00840 aux_lune(xc, yc, radius, tilt, gray, "lunefd");
00841 }
00842
00843 void PSFile::fill_triangle(
00844 double xa, double ya,
00845 double xb, double yb,
00846 double xc, double yc,
00847 double gray
00848 )
00849 {
00850 double psxa = hmin + xscale * (xa - xmin);
00851 double psya = vmin + yscale * (ya - ymin);
00852 double psxb = hmin + xscale * (xb - xmin);
00853 double psyb = vmin + yscale * (yb - ymin);
00854 double psxc = hmin + xscale * (xc - xmin);
00855 double psyc = vmin + yscale * (yc - ymin);
00856 psfile << psxa<<' '<<psya<<' '<<psxb<<' '<<psyb<<' '<<psxc<<' '<<psyc<<' '<<gray << " trif" << endl;
00857 psfile.flush();
00858 }
00859
00860 void PSFile::fill_grid_cell(int xi, int yi, double gray)
00861 {
00862 psfile << xi<<' '<<yi<<' '<<gray<<" celf"<<endl;
00863 psfile.flush();
00864 }
00865
00866 void PSFile::draw_coord_line (char axis, double coord)
00867 {
00868 double pscoord;
00869 if (axis == 'x')
00870 { pscoord = hmin + xscale * (coord - xmin); }
00871 else if (axis == 'y')
00872 { pscoord = vmin + yscale * (coord - ymin); }
00873 else
00874 {
00875 return;
00876 }
00877 psfile << pscoord<< axis<< "grd"<<endl;
00878 }
00879
00880 void PSFile::draw_grid_lines()
00881 {
00882 psfile << "%% Grid lines:" << endl;
00883 psfile << "gsave" << endl;
00884 psfile << " initclip" << endl;
00885 psfile << " 0 1 xn {" << endl;
00886 psfile << " xstep mul xmin add xgrd" << endl;
00887 psfile << " } for" << endl;
00888 psfile << " 0 1 yn {" << endl;
00889 psfile << " ystep mul ymin add ygrd" << endl;
00890 psfile << " } for" << endl;
00891 psfile << "grestore" << endl;
00892 psfile << "" << endl;
00893 psfile.flush();
00894 }
00895
00896 void PSFile::put_text(char *text, char *newline)
00897 {
00898 char *p;
00899 psfile<<'(';
00900 for (p = text; *p != 0; p++)
00901 {
00902 if (*p == '\n')
00903 { psfile << ""<< newline <<"";}
00904 else if (*p == '(')
00905 { psfile<<'\\'; psfile<<'('; }
00906 else if (*p == ')')
00907 { psfile<<'\\'; psfile<<')'; }
00908 else if (*p == '\t')
00909 { psfile<<' '; psfile<<' '; }
00910 else if (*p == '\\')
00911 { psfile<<'\\'; psfile<<'\\'; }
00912 else if ((*p < ' ') || (*p > '~'))
00913 { psfile << '\\'<< *p << 'o'; }
00914 else
00915 { psfile<<*p; }
00916 }
00917 psfile << ')';
00918 }
00919
00920 PSFile& PSFile::operator<<(const Model& m)
00921 {
00922 psfile << m;
00923 return (*this);
00924 }
00925
00926
00927 }