home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / fractal / kaos.lha / binsrclib / sgraph.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-14  |  13.2 KB  |  815 lines

  1. /* %W%    %G% */
  2. /* Modified graph.c                            */
  3. /* Modification time: 1987.9.14                */
  4. /* Modified Features:                          */
  5. /* (1)Double Precision is allowed              */
  6. /* (2)Frame is thicker                         */
  7. /* (3)Max and min x & y are shown on top       */
  8. /* (4)The position of a symbol . is readjusted */ 
  9. /*    to conform with a point from "point" */
  10. /*    c plotting subroutine.                   */
  11. /* (5)change of defaults -g 1 -m 0             */
  12. /* (6)changed log10(x) to log(x)/log(10)       */
  13.  
  14. #ifndef lint
  15. static char sccsid[] = "@(#)graph.c    4.2 3/30/83";
  16. #endif
  17.  
  18.  
  19. #include <stdio.h>
  20. #include <ctype.h>
  21. #include <math.h>
  22. #define    INF    HUGE
  23. #define    F    .25
  24.  
  25. struct xy {
  26.     int    xlbf;    /*flag:explicit lower bound*/
  27.     int     xubf;    /*flag:explicit upper bound*/
  28.     int    xqf;    /*flag:explicit quantum*/
  29.     double (*xf)();    /*transform function, e.g. log*/
  30.     double    xa,xb;    /*scaling coefficients*/
  31.     double    xlb,xub;    /*lower and upper bound*/
  32.     double    xquant;    /*quantum*/
  33.     double    xoff;        /*screen offset fraction*/
  34.     double    xsize;        /*screen fraction*/
  35.     int    xbot,xtop;    /*screen coords of border*/    
  36.     double    xmult;    /*scaling constant*/
  37. } xd,yd;
  38. struct val {
  39.     double xv;
  40.     double yv;
  41.     int lblptr;
  42. } *xx;
  43.  
  44. char *labs;
  45. int labsiz;
  46.  
  47. int tick = 50;
  48. /* figure maximizing choice
  49. int top = 4084;
  50. int bot = 284;
  51. */
  52. /* original configuration */
  53. int top = 4000;
  54. int bot = 200;
  55. double absbot;
  56. int    n;
  57. int    erasf = 1;
  58. int    gridf = 1;
  59. int    symbf = 0;
  60. int    absf = 0;
  61. int    transf;
  62. int    brkf;
  63. double    dx;
  64. char    *plotsymb;
  65.  
  66. double    atof();
  67. #define BSIZ 160
  68. #define MAXLINE 10
  69. char    labbuf[BSIZ];
  70. char    headerfile[BSIZ];
  71. char    titlebuf[MAXLINE][BSIZ];
  72.  
  73. char *modes[] = {
  74.     "disconnected",
  75.     "solid",
  76.     "dotted",
  77.     "dotdashed",
  78.     "shortdashed",
  79.     "longdashed"
  80. };
  81. int mode = 0;
  82. char *realloc();
  83. char *malloc();
  84.  
  85. double ident(x)
  86. double x;
  87. {
  88.     return(x);
  89. }
  90.  
  91. main(argc,argv)
  92. char *argv[];
  93. {
  94.     openpl();
  95.     space(0,0,4096,4096);
  96.     init(&xd);
  97.     init(&yd);
  98.     xd.xsize = yd.xsize = 1.;
  99.     xx = (struct val *)malloc((unsigned)sizeof(struct val));
  100.     labs = malloc(1);
  101.     labs[labsiz++] = 0;
  102.     setopt(argc,argv);
  103.     if(erasf)
  104.         erase();
  105.     readin();
  106.     transpose();
  107.     scale(&xd,(struct val *)&xx->xv);
  108.     scale(&yd,(struct val *)&xx->yv);
  109.     draw_all();
  110.     move(1,1);
  111.     closevt();
  112.     return(0);
  113. }
  114.  
  115. draw_all()
  116. {
  117.     axes();
  118.     title();
  119.     plot();
  120. }
  121.  
  122. init(p)
  123. struct xy *p;
  124. {
  125.     p->xf = ident;
  126.     p->xmult = 1;
  127. }
  128.  
  129. setopt(argc,argv)
  130. char *argv[];
  131. {
  132.     int i;
  133.     char *ph1, *ph2;
  134.     char *p1, *p2;
  135.     char *p12, *p22;
  136.     char *p13, *p23;
  137.     char *p14, *p24;
  138.     char *p15, *p25;
  139.     double temp;
  140.     FILE *fp,*fopen();
  141.  
  142.     xd.xlb = yd.xlb = INF;
  143.     xd.xub = yd.xub = -INF;
  144.     while(--argc > 0) {
  145.         argv++;
  146. again:        switch(argv[0][0]) {
  147.         case '-':
  148.             argv[0]++;
  149.             goto again;
  150.         case 'j': /* label for plot */
  151.             p1 = titlebuf[0];
  152.             if (argc>=2) {
  153.                 argv++;
  154.                 argc--;
  155.                 p2 = argv[0];
  156.                 while (*p1++ = *p2++);
  157.             }
  158.             break;
  159.         case 'k': /* label for plot */
  160.             p12 = titlebuf[1];
  161.             if (argc>=2) {
  162.                 argv++;
  163.                 argc--;
  164.                 p22 = argv[0];
  165.                 while (*p12++ = *p22++);
  166.             }
  167.             break;
  168.         case 'l': /* label for plot */
  169.             p13 = titlebuf[2];
  170.             if (argc>=2) {
  171.                 argv++;
  172.                 argc--;
  173.                 p23 = argv[0];
  174.                 while (*p13++ = *p23++);
  175.             }
  176.             break;
  177.         case 'n': /* label for plot */
  178.             p14 = titlebuf[3];
  179.             if (argc>=2) {
  180.                 argv++;
  181.                 argc--;
  182.                 p24 = argv[0];
  183.                 while (*p14++ = *p24++);
  184.             }
  185.             break;
  186.         case 'o': /* label for plot */
  187.             p15 = titlebuf[4];
  188.             if (argc>=2) {
  189.                 argv++;
  190.                 argc--;
  191.                 p25 = argv[0];
  192.                 while (*p15++ = *p25++);
  193.             }
  194.             break;
  195.         case 'f': /* read headers from a file */
  196.             strcpy(headerfile,argv[1]);
  197.             argv++;
  198.             argc--;
  199.             fp = fopen(headerfile,"r");
  200.             if(fp == NULL){
  201.                 printf("The specified header file is not found!\n");
  202.                 exit(-1);
  203.             }
  204.             i=0;
  205.             while(i<MAXLINE && (fgets(titlebuf[i],BSIZ,fp))!= NULL){
  206.                 titlebuf[i][(int)strlen(titlebuf[i])-1]= '\0';
  207.                 i++;
  208.             }
  209.             fclose(fp);
  210.             break;
  211.         case 'd':    /*disconnected,obsolete option*/
  212.         case 'm': /*line mode*/
  213.             mode = 0;
  214.             if(!numb(&temp,&argc,&argv))
  215.                 break;
  216.             if(temp>=sizeof(modes)/sizeof(*modes))
  217.                 mode = 1;
  218.             else if(temp>=0)
  219.                 mode = temp;
  220.             break;
  221.  
  222.         case 'a': /*automatic abscissas*/
  223.             absf = 1;
  224.             dx = 1;
  225.             if(!numb(&dx,&argc,&argv))
  226.                 break;
  227.             if(numb(&absbot,&argc,&argv))
  228.                 absf = 2;
  229.             break;
  230.  
  231.         case 's': /*save screen, overlay plot*/
  232.             erasf = 0;
  233.             break;
  234.  
  235.         case 'g': /*grid style 0 none, 1 ticks, 2 full*/
  236.             gridf = 0;
  237.             if(!numb(&temp,&argc,&argv))
  238.                 temp = argv[0][1]-'0';    /*for caompatibility*/
  239.             if(temp>=0&&temp<=2)
  240.                 gridf = temp;
  241.             break;
  242.  
  243.         case 'c': /*character(s) for plotting*/
  244.             if(argc >= 2) {
  245.                 symbf = 1;
  246.                 plotsymb = argv[1];
  247.                 argv++;
  248.                 argc--;
  249.             }
  250.             break;
  251.  
  252.         case 't':    /*transpose*/
  253.             transf = 1;
  254.             break;
  255.         case 'b':    /*breaks*/
  256.             brkf = 1;
  257.             break;
  258.         case 'x':    /*x limits */
  259.             limread(&xd,&argc,&argv);
  260.             break;
  261.         case 'y':
  262.             limread(&yd,&argc,&argv);
  263.             break;
  264.         case 'h': /*set height of plot */
  265.             if(!numb(&yd.xsize, &argc,&argv))
  266.                 badarg();
  267.             break;
  268.         case 'w': /*set width of plot */
  269.             if(!numb(&xd.xsize, &argc, &argv))
  270.                 badarg();
  271.             break;
  272.         case 'r': /* set offset to right */
  273.             if(!numb(&xd.xoff, &argc, &argv))
  274.                 badarg();
  275.             break;
  276.         case 'u': /*set offset up the screen*/
  277.             if(!numb(&yd.xoff,&argc,&argv))
  278.                 badarg();
  279.             break;
  280.         default:
  281.             badarg();
  282.         }
  283.     }
  284. }
  285.  
  286. limread(p, argcp, argvp)
  287. register struct xy *p;
  288. int *argcp;
  289. char ***argvp;
  290. {
  291.     if(*argcp>1 && (*argvp)[1][0]=='l') {
  292.         (*argcp)--;
  293.         (*argvp)++;
  294.         p->xf = log10;
  295.     }
  296.     if(!numb(&p->xlb,argcp,argvp))
  297.         return;
  298.     p->xlbf = 1;
  299.     if(!numb(&p->xub,argcp,argvp))
  300.         return;
  301.     p->xubf = 1;
  302.     if(!numb(&p->xquant,argcp,argvp))
  303.         return;
  304.     p->xqf = 1;
  305. }
  306.  
  307. numb(np, argcp, argvp)
  308. int *argcp;
  309. double *np;
  310. register char ***argvp;
  311. {
  312.     register char c;
  313.  
  314.     if(*argcp <= 1)
  315.         return(0);
  316.     while((c=(*argvp)[1][0]) == '+')
  317.         (*argvp)[1]++;
  318.     if(!(isdigit(c) || c=='-'&&(*argvp)[1][1]<'A' || c=='.'))
  319.         return(0);
  320.     *np = atof((*argvp)[1]);
  321.     (*argcp)--;
  322.     (*argvp)++;
  323.     return(1);
  324. }
  325.  
  326. readin()
  327. {
  328.     register t;
  329.     struct val *temp;
  330.  
  331.     if(absf==1) {
  332.         if(xd.xlbf)
  333.             absbot = xd.xlb;
  334.         else if(xd.xf==log10)
  335.             absbot = 1;
  336.     }
  337.     for(;;) {
  338.         temp = (struct val *)realloc((char*)xx,
  339.             (unsigned)(n+1)*sizeof(struct val));
  340.         if(temp==0)
  341.             return;
  342.         xx = temp;
  343.         if(absf)
  344.             xx[n].xv = n*dx + absbot;
  345.         else
  346.             if(!getdouble(&xx[n].xv))
  347.                 return;
  348.         if(!getdouble(&xx[n].yv))
  349.             return;
  350.         xx[n].lblptr = -1;
  351.         t = getstring();
  352.         if(t>0)
  353.             xx[n].lblptr = copystring(t);
  354.         n++;
  355.         if(t<0)
  356.             return;
  357.     }
  358. }
  359.  
  360. transpose()
  361. {
  362.     register i;
  363.     double f;
  364.     struct xy t;
  365.     if(!transf)
  366.         return;
  367.     t = xd; xd = yd; yd = t;
  368.     for(i= 0;i<n;i++) {
  369.         f = xx[i].xv; xx[i].xv = xx[i].yv; xx[i].yv = f;
  370.     }
  371. }
  372.  
  373. copystring(k)
  374. {
  375.     register char *temp;
  376.     register i;
  377.     int q;
  378.  
  379.     temp = realloc(labs,(unsigned)(labsiz+1+k));
  380.     if(temp==0)
  381.         return(0);
  382.     labs = temp;
  383.     q = labsiz;
  384.     for(i=0;i<=k;i++)
  385.         labs[labsiz++] = labbuf[i];
  386.     return(q);
  387. }
  388.  
  389. double
  390. modceil(f,t)
  391. double f,t;
  392. {
  393.  
  394.     t = fabs(t);
  395.     return(ceil(f/t)*t);
  396. }
  397.  
  398. double
  399. modfloor(f,t)
  400. double f,t;
  401. {
  402.     t = fabs(t);
  403.     return(floor(f/t)*t);
  404. }
  405.  
  406. getlim(p,v)
  407. register struct xy *p;
  408. struct val *v;
  409. {
  410.     register i;
  411.  
  412.     i = 0;
  413.     do {
  414.         if(!p->xlbf && p->xlb>v[i].xv)
  415.             p->xlb = v[i].xv;
  416.         if(!p->xubf && p->xub<v[i].xv)
  417.             p->xub = v[i].xv;
  418.         i++;
  419.     } while(i < n);
  420. }
  421.  
  422. struct z {
  423.     double lb,ub,mult,quant;
  424. } setloglim(), setlinlim();
  425.  
  426. setlim(p)
  427. register struct xy *p;
  428. {
  429.     double t,delta,sign;
  430.     struct z z;
  431.     int mark[50];
  432.     double lb,ub;
  433.     int lbf,ubf;
  434.  
  435.     lb = p->xlb;
  436.     ub = p->xub;
  437.     delta = ub-lb;
  438.     if(p->xqf) {
  439.         if(delta*p->xquant <=0 )
  440.             badarg();
  441.         return;
  442.     }
  443.     sign = 1;
  444.     lbf = p->xlbf;
  445.     ubf = p->xubf;
  446.     if(delta < 0) {
  447.         sign = -1;
  448.         t = lb;
  449.         lb = ub;
  450.         ub = t;
  451.         t = lbf;
  452.         lbf = ubf;
  453.         ubf = t;
  454.     }
  455.     else if(delta == 0) {
  456.         if(ub > 0) {
  457.             ub = 2*ub;
  458.             lb = 0;
  459.         } 
  460.         else
  461.             if(lb < 0) {
  462.                 lb = 2*lb;
  463.                 ub = 0;
  464.             } 
  465.             else {
  466.                 ub = 1;
  467.                 lb = -1;
  468.             }
  469.     }
  470.     if(p->xf==log10 && lb>0 && ub>lb) {
  471.         z = setloglim(lbf,ubf,lb,ub);
  472.         p->xlb = z.lb;
  473.         p->xub = z.ub;
  474.         p->xmult *= z.mult;
  475.         p->xquant = z.quant;
  476.         if(setmark(mark,p)<2) {
  477.             p->xqf = lbf = ubf = 1;
  478.             lb = z.lb; ub = z.ub;
  479.         } else
  480.             return;
  481.     }
  482.     z = setlinlim(lbf,ubf,lb,ub);
  483.     if(sign > 0) {
  484.         p->xlb = z.lb;
  485.         p->xub = z.ub;
  486.     } else {
  487.         p->xlb = z.ub;
  488.         p->xub = z.lb;
  489.     }
  490.     p->xmult *= z.mult;
  491.     p->xquant = sign*z.quant;
  492. }
  493.  
  494. struct z
  495. setloglim(lbf,ubf,lb,ub)
  496. double lb,ub;
  497. {
  498.     double r,s,t;
  499.     struct z z;
  500.  
  501.     for(s=1; lb*s<1; s*=10) ;
  502.     lb *= s;
  503.     ub *= s;
  504.     for(r=1; 10*r<=lb; r*=10) ;
  505.     for(t=1; t<ub; t*=10) ;
  506.     z.lb = !lbf ? r : lb;
  507.     z.ub = !ubf ? t : ub;
  508.     if(ub/lb<100) {
  509.         if(!lbf) {
  510.             if(lb >= 5*z.lb)
  511.                 z.lb *= 5;
  512.             else if(lb >= 2*z.lb)
  513.                 z.lb *= 2;
  514.         }
  515.         if(!ubf) {
  516.             if(ub*5 <= z.ub)
  517.                 z.ub /= 5;
  518.             else if(ub*2 <= z.ub)
  519.                 z.ub /= 2;
  520.         }
  521.     }
  522.     z.mult = s;
  523.     z.quant = r;
  524.     return(z);
  525. }
  526.  
  527. struct z
  528. setlinlim(lbf,ubf,xlb,xub)
  529. int lbf,ubf;
  530. double xlb,xub;
  531. {
  532.     struct z z;
  533.     double r,s,delta;
  534.     double ub,lb;
  535.  
  536. loop:
  537.     ub = xub;
  538.     lb = xlb;
  539.     delta = ub - lb;
  540.     /*scale up by s, a power of 10, so range (delta) exceeds 1*/
  541.     /*find power of 10 quantum, r, such that delta/10<=r<delta*/
  542.     r = s = 1;
  543.     while(delta*s < 10)
  544.         s *= 10;
  545.     delta *= s;
  546.     while(10*r < delta)
  547.         r *= 10;
  548.     lb *= s;
  549.     ub *= s;
  550.     /*set r=(1,2,5)*10**n so that 3-5 quanta cover range*/
  551.     if(r>=delta/2)
  552.         r /= 2;
  553.     else if(r<delta/5)
  554.         r *= 2;
  555.     z.ub = ubf? ub: modceil(ub,r);
  556.     z.lb = lbf? lb: modfloor(lb,r);
  557.     if(!lbf && z.lb<=r && z.lb>0) {
  558.         xlb = 0;
  559.         goto loop;
  560.     }
  561.     else if(!ubf && z.ub>=-r && z.ub<0) {
  562.         xub = 0;
  563.         goto loop;
  564.     }
  565.     z.quant = r;
  566.     z.mult = s;
  567.     return(z);
  568. }
  569.  
  570. scale(p,v)
  571. register struct xy *p;
  572. struct val *v;
  573. {
  574.     double edge;
  575.  
  576.     getlim(p,v);
  577.     setlim(p);
  578.     edge = top-bot;
  579.     p->xa = p->xsize*edge/((*p->xf)(p->xub) - (*p->xf)(p->xlb));
  580.     p->xbot = bot + edge*p->xoff;
  581.     p->xtop = p->xbot + (top-bot)*p->xsize;
  582.     p->xb = p->xbot - (*p->xf)(p->xlb)*p->xa + .5;
  583. }
  584.  
  585. axes()
  586. {
  587.     register i;
  588.     int mark[50];
  589.     int xn, yn;
  590.  
  591.     if(gridf==0)
  592.         return;
  593.  
  594.     line(xd.xbot,yd.xbot,xd.xtop,yd.xbot);
  595.     cont(xd.xtop,yd.xtop);
  596.     cont(xd.xbot,yd.xtop);
  597.     cont(xd.xbot,yd.xbot);
  598.     line(xd.xbot-2,yd.xbot-2,xd.xtop+2,yd.xbot-2);
  599.     cont(xd.xtop+2,yd.xtop+2);
  600.     cont(xd.xbot-2,yd.xtop+2);
  601.     cont(xd.xbot-2,yd.xbot-2);
  602.     line(xd.xbot-4,yd.xbot-4,xd.xtop+4,yd.xbot-4);
  603.     cont(xd.xtop+4,yd.xtop+4);
  604.     cont(xd.xbot-4,yd.xtop+4);
  605.     cont(xd.xbot-4,yd.xbot-4);
  606.     line(xd.xbot-6,yd.xbot-6,xd.xtop+6,yd.xbot-6);
  607.     cont(xd.xtop+6,yd.xtop+6);
  608.     cont(xd.xbot-6,yd.xtop+6);
  609.     cont(xd.xbot-6,yd.xbot-6);
  610.     line(xd.xbot-8,yd.xbot-8,xd.xtop+8,yd.xbot-8);
  611.     cont(xd.xtop+8,yd.xtop+8);
  612.     cont(xd.xbot-8,yd.xtop+8);
  613.     cont(xd.xbot-8,yd.xbot-8);
  614.  
  615.     xn = setmark(mark,&xd);
  616.     for(i=0; i<xn; i++) {
  617.         if(gridf==2)
  618.             line(mark[i],yd.xbot,mark[i],yd.xtop);
  619.         if(gridf==1) {
  620.             line(mark[i],yd.xbot,mark[i],yd.xbot+tick);
  621.             line(mark[i],yd.xtop-tick,mark[i],yd.xtop);
  622.         }
  623.     }
  624.     yn = setmark(mark,&yd);
  625.     for(i=0; i<yn; i++) {
  626.         if(gridf==2)
  627.             line(xd.xbot,mark[i],xd.xtop,mark[i]);
  628.         if(gridf==1) {
  629.             line(xd.xbot,mark[i],xd.xbot+tick,mark[i]);
  630.             line(xd.xtop-tick,mark[i],xd.xtop,mark[i]);
  631.         }
  632.     }
  633. }
  634.  
  635. setmark(xmark,p)
  636. int *xmark;
  637. register struct xy *p;
  638. {
  639.     int xn = 0;
  640.     double x,xl,xu;
  641.     double q;
  642.     if(p->xf==log10&&!p->xqf) {
  643.         for(x=p->xquant; x<p->xub; x*=10) {
  644.             submark(xmark,&xn,x,p);
  645.             if(p->xub/p->xlb<=100) {
  646.                 submark(xmark,&xn,2*x,p);
  647.                 submark(xmark,&xn,5*x,p);
  648.             }
  649.         }
  650.     } else {
  651.         xn = 0;
  652.         q = p->xquant;
  653.         if(q>0) {
  654.             xl = modceil(p->xlb+q/6,q);
  655.             xu = modfloor(p->xub-q/6,q)+q/2;
  656.         } else {
  657.             xl = modceil(p->xub-q/6,q);
  658.             xu = modfloor(p->xlb+q/6,q)-q/2;
  659.         }
  660.         for(x=xl; x<=xu; x+=fabs(p->xquant))
  661.             xmark[xn++] = (*p->xf)(x)*p->xa + p->xb;
  662.     }
  663.     return(xn);
  664. }
  665. submark(xmark,pxn,x,p)
  666. int *xmark;
  667. int *pxn;
  668. double x;
  669. struct xy *p;
  670. {
  671.     if(1.001*p->xlb < x && .999*p->xub > x)
  672.         xmark[(*pxn)++] = log(x)/log((double)10)*p->xa + p->xb;
  673. }
  674.  
  675. plot()
  676. {
  677.     int ix,iy;
  678.     int i;
  679.     int conn;
  680.  
  681.     conn = 0;
  682.     if(mode!=0)
  683.         linemod(modes[mode]);
  684.     else
  685.         linemod(modes[0]);
  686.     for(i=0; i<n; i++) {
  687.         if(!conv(xx[i].xv,&xd,&ix) ||
  688.            !conv(xx[i].yv,&yd,&iy)) {
  689.             conn = 0;
  690.             continue;
  691.         }
  692.         if(mode!=0) {
  693.             if(conn != 0)
  694.                 cont(ix,iy);
  695.             else
  696.                 move(ix,iy);
  697.             conn = 1;
  698.         }
  699.         conn &= symbol(ix,iy,xx[i].lblptr);
  700.     }
  701.     linemod(modes[1]);
  702. }
  703.  
  704. conv(xv,p,ip)
  705. double xv;
  706. register struct xy *p;
  707. int *ip;
  708. {
  709.     long ix;
  710.     ix = p->xa*(*p->xf)(xv*p->xmult) + p->xb;
  711.     if(ix<p->xbot || ix>p->xtop)
  712.         return(0);
  713.     *ip = ix;
  714.     return(1);
  715. }
  716.  
  717. getdouble(p)
  718. double *p;
  719. {
  720.     register i;
  721.  
  722.     i = scanf("%lf",p);
  723.     return(i==1);
  724. }
  725.  
  726. getstring()
  727. {
  728.     register i;
  729.     char junk[20];
  730.     i = scanf("%1s",labbuf);
  731.     if(i==-1)
  732.         return(-1);
  733.     switch(*labbuf) {
  734.     default:
  735.         if(!isdigit(*labbuf)) {
  736.             ungetc(*labbuf,stdin);
  737.             i = scanf("%s",labbuf);
  738.             break;
  739.         }
  740.     case '.':
  741.     case '+':
  742.     case '-':
  743.         ungetc(*labbuf,stdin);
  744.         return(0);
  745.     case '"':
  746.         i = scanf("%[^\"\n]",labbuf);
  747.         scanf("%[\"]",junk);
  748.         break;
  749.     }
  750.     if(i==-1)
  751.         return(-1);
  752.     return(strlen(labbuf));
  753. }
  754.  
  755.  
  756. symbol(ix,iy,k)
  757. {
  758.  
  759.     if(symbf==0&&k<0) {
  760.         if(mode==0)
  761.             point(ix,iy);
  762.         return(1);
  763.     } 
  764.     else {
  765.         if( strcmp(plotsymb,".") == 0 ){
  766.             move(ix-18,iy-4);
  767.         }
  768.         else{
  769.             move(ix,iy);
  770.         }
  771.         label(k>=0?labs+k:plotsymb);
  772.         move(ix,iy);
  773.         return(!brkf|k<0);
  774.     }
  775. }
  776.  
  777. title()
  778. {
  779.     int i,iy;
  780.  
  781.     linemod(modes[0]);
  782.     iy = 1300;
  783.     for(i=0;i<MAXLINE;i++){
  784.         move(xd.xbot+50,yd.xtop+iy);
  785.         if (titlebuf[i][0]) {
  786.             label(titlebuf[i]);
  787.             iy -= 70;
  788.         }
  789.     }
  790.     iy = 10;
  791.     if(erasf&&gridf) {
  792.         move(xd.xbot+100,iy);
  793.         axlab('x',&xd);
  794.         label("  ");
  795.         move(xd.xbot+2048,iy);
  796.         axlab('y',&yd);
  797.     }
  798. }
  799.  
  800. axlab(c,p)
  801. char c;
  802. struct xy *p;
  803. {
  804.     char buf[50];
  805.     sprintf(buf,"%g -%s%c- %g", p->xlb/p->xmult,
  806.         p->xf==log10?"log ":"", c, p->xub/p->xmult);
  807.     label(buf);
  808. }
  809.  
  810. badarg()
  811. {
  812.     fprintf(stderr,"graph: error in arguments\n");
  813.     exit(1);
  814. }
  815.