source: tags/initial/GDE/PHYLIP/drawgram.c

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.1 KB
Line 
1#include "drawgraphics.h"
2
3/* Version 3.52c.  Copyright (c) 1986-1993 by Joseph Felsenstein and
4  Christopher A. Meacham.  Additional code written by Hisashi Horino,
5  Sean Lamont, Andrew Keefe, and Akiko Fuseki.
6  Permission is granted to copy, distribute, and modify this
7  program provided that (1) this copyright message is not removed
8  and (2) no fee is charged for this program. */
9
10FILE *treefile,  *plotfile;
11char pltfilename[100];
12long     ntips, nextnode,  strpwide, strpdeep,strpdiv,
13        strptop, strpbottom, payge, numlines;
14boolean  preview, previewing, dotmatrix,
15         haslengths, uselengths, empty, rescaled;
16double xmargin, ymargin, topoflabels, rightoflabels, leftoflabels,
17       tipspacing,maxheight, scale, xscale, yscale, xoffset, yoffset,
18       nodespace, stemlength, treedepth, xnow, ynow, xunitspercm, yunitspercm,
19       xsize, ysize, xcorner, ycorner, labelheight,labelrotation,expand, rooty,
20       bscale;
21       striptype stripe;
22       plottertype plotter, oldplotter, previewer;
23       growth grows;
24       treestyle style;
25       node *root;
26node *nodep[maxnodes];
27       fonttype font;
28       long filesize;
29Char   ch;
30char   fontname[64];
31
32       enum {  yes, no} penchange,oldpenchange;
33static enum {  weighted, intermediate, centered, inner, vshaped} nodeposition;
34
35
36openfile(fp,filename,mode,application,perm)
37FILE **fp;
38char *filename;
39char *mode;
40char *application;
41char *perm;
42{
43  FILE *of;
44  char file[100];
45  strcpy(file,filename);
46  while (1){
47    of = fopen(file,mode);
48    if (of)
49      break;
50    else {
51      switch (*mode){
52      case 'r':
53        printf("%s:  can't read %s\n",application,file);
54        file[0] = '\0';
55        while (file[0] =='\0'){
56          printf("Please enter a new filename>");
57          gets(file);}
58        break;
59      case 'w':
60        printf("%s: can't write %s\n",application,file);
61        file[0] = '\0';
62        while (file[0] =='\0'){
63          printf("Please enter a new filename>");
64          gets(file);}
65        break;
66      }
67    }
68  }
69  *fp=of;
70  if (perm != NULL)
71    strcpy(perm,file);
72}
73
74void uppercase(ch)
75Char *ch;
76{  /* make ch upper-case */
77   *ch = (islower(*ch) ?  toupper(*ch) : (*ch));
78}  /* uppercase */
79
80void getch(c)
81Char *c;
82{  /* get next nonblank character */
83  do {
84    *c=getc(treefile); }
85  while ((*c == ' ')||(*c == '\n')||(*c == '\t'));
86  }  /* getch */
87
88Void processlength(p)
89node *p;
90{
91  long  digit, ordzero;
92  double valyew, divisor;
93  boolean pointread, minusread;
94
95  ordzero = '0';
96  pointread = false;
97  minusread = false;
98  valyew = 0.0;
99  divisor = 1.0;
100  getch(&ch);
101  digit = ch - ordzero;
102  while (((unsigned long)digit <= 9) | (ch == '.') || (ch == '-')){
103        if (ch == '.')   pointread = true;
104   else if (ch == '-')   minusread = true;
105   else {
106        valyew = valyew * 10.0 + digit;
107        if (pointread)
108          divisor *= 10.0;
109      }
110        getch(&ch);
111        digit = ch - ordzero;
112      }
113 if (!minusread)
114 p->oldlen = valyew / divisor;
115 else
116 p->oldlen = 0.0;
117  /* processlength */
118}
119
120void addelement(p, q)
121node **p, *q;
122{
123  /* read in and add next part of tree, it will be node p
124     and will be hooked to pointer q */
125  node *pfirst;
126  long n;
127  boolean notlast;
128
129  nextnode++;
130  *p = (node *)Malloc((long)sizeof(node));
131  nodep[nextnode - 1] = *p;
132  if (ch == '(') {
133    (*p)->tip = false;
134    (*p)->tipsabove = 0;
135    pfirst = *p;
136    notlast = true;
137    while (notlast) {
138      (*p)->next = (node *)Malloc((long)sizeof(node));
139      *p = (*p)->next;
140      (*p)->tip = false;
141      getch(&ch);
142      addelement(&(*p)->back, *p);
143      pfirst->tipsabove += (*p)->back->tipsabove;
144      if (ch == ')') {
145        notlast = false;
146        do {
147          getch(&ch);
148        } while (ch != ':' && ch != ',' && ch != ')' && ch != '[' && ch != ';');
149      }
150    }
151    (*p)->next = pfirst;
152    *p = pfirst;
153  } else {
154    (*p)->tip = true;
155    (*p)->tipsabove = 1;
156    ntips++;
157    n = 1;
158    do {
159      if (ch == '_')
160        ch = ' ';
161      if (!ebcdic && (ch & 255) == 255)
162        ch = '\'';
163      if (!ebcdic && (ch & 255) > 175)
164        ch -= 48;
165      if (!ebcdic && (ch & (~127)) != 0)
166        ch -= 64;
167      if (n < maxnch)
168        (*p)->nayme[n - 1] = ch;
169      if (eoln(treefile)) {
170        fscanf(treefile, "%*[^\n]");
171        getc(treefile);
172      }
173      ch = getc(treefile);
174      n++;
175    } while (ch != ':' && ch != ',' && ch != ')');
176    if (n > maxnch)
177      n = maxnch + 1;
178    (*p)->naymlength = n - 1;
179  }
180  if (ch == ':')
181    processlength(*p);
182  else
183    haslengths = (haslengths && q == NULL);
184  (*p)->back = q;
185}  /* addelement */
186
187
188void treeread()
189{
190  /* read a tree from the treefile and set up nodes and pointers */
191  haslengths = true;
192  ntips = 0;
193  nextnode = 0;
194  getch(&ch);
195  addelement(&root, NULL);
196  fscanf(treefile, "%*[^\n]");
197  getc(treefile);
198  uselengths = haslengths;
199}  /* treeread */
200
201
202
203void initialparms()
204{
205  /* initialize parameters */
206  getplotter();
207  plotrparms();
208  if (dotmatrix)
209    numlines = (long)floor(yunitspercm * ysize + 0.5) / strpdeep;
210  xmargin = 0.08 * xsize;
211  ymargin = 0.08 * ysize;
212  xscale = xunitspercm;
213  yscale = yunitspercm;
214  style =  cladogram;
215  grows = vertical;
216  labelrotation = 45.0;
217  nodespace = 3.0;
218  stemlength = 0.05;
219  treedepth = 0.5 / 0.95;
220  rescaled = true;
221  bscale = 1.0;
222  if (uselengths)
223    nodeposition = intermediate;
224  else
225    nodeposition = vshaped;
226}  /* initialparms */
227
228
229long showparms()
230{
231  long i;
232  long numtochange;
233  char input[32];
234  Char ch, ch2,trash;
235
236  putchar('\n');
237  if (previewer == tek)
238    printf("%c\f", escape);
239  else {
240    for (i = 1; i <= 24; i++)
241      putchar('\n');
242  }
243  printf("Here are the settings: \n\n");
244  printf(" (1)               Tree grows:  ");
245  printf((grows == vertical) ? "Vertically\n" : "Horizontally\n");
246  printf(" (2)            Style of tree:  %s\n",
247         (style == cladogram) ? "Cladogram" :
248         (style == phenogram)  ? "Phenogram" :
249         (style == curvogram) ? "Curvogram" :
250         (style == eurogram)  ? "Eurogram"  : "Swoopogram");
251
252
253  printf(" (3)       Use branch lengths:  ");
254  if (haslengths) {
255    if (uselengths)
256      printf("Yes\n");
257    else
258      printf("No\n");
259  } else
260    printf("(no branch lengths available)\n");
261  printf(" (4)          Angle of labels:");
262  if (labelrotation < 10.0)
263    printf("%5.1f\n", labelrotation);
264  else
265    printf("%6.1f\n", labelrotation);
266  if (plotter == ray) {
267    printf(" (5)       Horizontal margins:%6.2f pixels\n", xmargin);
268    printf(" (5)         Vertical margins:%6.2f pixels\n", ymargin);
269  } else {
270    printf(" (5)       Horizontal margins:%6.2f cm\n", xmargin);
271    printf(" (5)         Vertical margins:%6.2f cm\n", ymargin);
272  }
273  printf(" (6)   Scale of branch length:");
274  if (rescaled)
275    printf("  Automatically rescaled\n");
276  else
277    printf("  Fixed:%6.2f cm per unit branch length\n", bscale);
278  printf(" (7)    Depth/Breadth of tree:%6.2f\n", treedepth);
279  printf(" (8)   Stem-length/tree-depth:%6.2f\n", stemlength);
280  printf(" (9) Character ht / tip space:%8.4f\n", 1.0 / nodespace);
281  printf("(10)          Ancestral nodes:  %s\n",
282         (nodeposition == weighted)     ? "Weighted"     :
283         (nodeposition == intermediate) ? "Intermediate" :
284         (nodeposition == centered)     ? "Centered"     :
285         (nodeposition == inner)        ? "Inner"        :
286         "So tree is V-shaped");
287  if (plotter == lw)
288    printf("(11)          Font           :  %s\n",fontname);
289
290  printf("\n Do you want to accept these? (Yes or No)\n");
291  for (;;) {
292    printf(" Type Y or N or the number (1-%2ld) of the one to change:\n",
293           ((plotter == lw) ? 11L : 10L));
294    gets(input);
295    uppercase(&input[0]);
296    numtochange = atoi(input);
297    ch = input[0];
298    if ((ch == 'Y' || ch == 'N') || (numtochange >= 1 && numtochange <= 11))
299      break;
300  }
301 return (ch == 'Y') ? -1 : numtochange;
302}  /* showparms */
303
304
305void getparms(numtochange)
306long numtochange;
307{
308  /* get from user the relevant parameters for the plotter and diagram */
309  Char ch,trash;
310  boolean ok;
311
312  if (numtochange == 0) {
313    do {
314      printf(" Type the number of one that you want to change (1-%2ld):\n",
315             ((plotter == lw) ? 11L : 10L));
316      scanf("%hd%*[^\n]", &numtochange);
317      trash=getchar();
318    } while (numtochange < 1 || numtochange > ((plotter == lw) ? 11 : 10));
319  }
320  switch (numtochange) {
321
322  case 1:
323    if (grows == vertical)
324      grows = horizontal;
325    else
326      grows = vertical;
327    break;
328
329  case 2:
330    printf("\nWhat style tree is this to be:\n");
331    printf("   Cladogram, Phenogram, curVogram, Eurogram,");
332    printf("  or Swoopogram\n");
333    printf(" (C, P, V, E, or S)\n");
334    do {
335      printf(" Choose one: \n");
336      scanf("%c%*[^\n]", &ch);
337      trash=getchar();
338      uppercase(&ch);
339    } while (ch != 'C' && ch != 'P' && ch != 'V' && ch != 'E' && ch != 'S');
340    switch (ch) {
341
342    case 'C':
343      style = cladogram;
344      break;
345
346    case 'P':
347      style = phenogram;
348      break;
349
350    case 'E':
351      style = eurogram;
352      break;
353
354    case 'S':
355      style = swoopogram;
356      break;
357
358    case 'V':
359      style = curvogram;
360      break;
361    }
362    break;
363
364  case 3:
365    if (haslengths) {
366      uselengths = !uselengths;
367      if (!uselengths)
368        nodeposition = vshaped;
369      else
370        nodeposition = intermediate;
371    } else {
372      printf("Cannot use lengths since not all of them exist\n");
373      uselengths = false;
374    }
375    break;
376
377  case 4:
378    printf("\n(Considering the tree as if it \"grew\" vertically:)\n");
379    printf("Are the labels to be plotted vertically (90),\n");
380    printf(" horizontally (0), or at a 45-degree angle?\n");
381    do {
382      printf(" Choose an angle in degrees from 90 to 0:\n");
383      scanf("%lf%*[^\n]", &labelrotation);
384      trash=getchar();
385      uppercase(&ch);
386    } while (labelrotation < 0.0 && labelrotation > 90.0);
387    break;
388
389  case 5:
390    printf("\nThe tree will be drawn to fit in a rectangle which has \n");
391    printf(" margins in the horizontal and vertical directions of:\n");
392    if (plotter == ray)
393      printf("%6.2f pixels (horizontal margin) and%6.2f pixels (vertical margin)\n",
394             xmargin, ymargin);
395    else
396      printf("%6.2f cm (horizontal margin) and%6.2f cm (vertical margin)\n",
397             xmargin, ymargin);
398    putchar('\n');
399    do {
400      if (plotter == ray)
401        printf(" New value (in pixels) of horizontal margin?\n");
402      else
403        printf(" New value (in cm) of horizontal margin?\n");
404      scanf("%lf%*[^\n]", &xmargin);
405      trash=getchar();
406      ok = ((unsigned)xmargin < xsize / 2.0);
407      if (!ok)
408        printf(" Impossible value.  Please retype it.\n");
409    } while (!ok);
410    do {
411      if (plotter == ray)
412        printf(" New value (in pixels) of vertical margin?\n");
413      else
414        printf(" New value (in cm) of vertical margin?\n");
415      scanf("%lf%*[^\n]", &ymargin);
416      trash=getchar();
417      ok = ((unsigned)ymargin < ysize / 2.0);
418      if (!ok)
419        printf(" Impossible value.  Please retype it.\n");
420    } while (!ok);
421    break;
422
423  case 6:
424    rescaled = !rescaled;
425    if (!rescaled) {
426      printf("Centimeters per unit branch length?\n");
427      scanf("%lf%*[^\n]", &bscale);
428      trash=getchar();
429    }
430    break;
431
432  case 7:
433    printf("New value of depth of tree as fraction of its breadth?\n");
434    scanf("%lf%*[^\n]", &treedepth);
435    trash=getchar();
436    break;
437
438  case 8:
439    do {
440      printf("New value of stem length as fraction of tree depth?\n");
441      scanf("%lf%*[^\n]", &stemlength);
442      trash=getchar();
443    } while ((unsigned)stemlength >= 0.9);
444    break;
445
446  case 9:
447    printf("New value of character height as fraction of tip spacing?\n");
448    scanf("%lf%*[^\n]", &nodespace);
449    trash=getchar();
450    nodespace = 1.0 / nodespace;
451    break;
452
453  case 10:
454    printf("Should interior node positions:\n");
455    printf(" be Intermediate between their immediate descendants,\n");
456    printf("    Weighted average of tip positions\n");
457    printf("    Centered among their ultimate descendants\n");
458    printf("    iNnermost of immediate descendants\n");
459    printf(" or so that tree is V-shaped\n");
460    do {
461      printf(" (type I, W, C, N or V):\n");
462      scanf("%c%*[^\n]", &ch);
463      trash=getchar();
464      uppercase(&ch);
465    } while (ch != 'I' && ch != 'W' && ch != 'C' && ch != 'N' && ch != 'V');
466    switch (ch) {
467
468    case 'W':
469      nodeposition = weighted;
470      break;
471
472    case 'I':
473      nodeposition = intermediate;
474      break;
475
476    case 'C':
477      nodeposition = centered;
478      break;
479
480    case 'N':
481      nodeposition = inner;
482      break;
483
484    case 'V':
485      nodeposition = vshaped;
486      break;
487    }
488    break;
489  case 11:
490    printf("Enter font name or \"Hershey\" for the default font\n");
491    gets(fontname);
492    break;
493  }
494}  /* getparms */
495
496
497
498void calctraverse(p, lengthsum,tipx)
499node *p;
500double lengthsum;
501double *tipx;
502{
503  /* traverse to establish initial node coordinates */
504  double x1, y1, x2, y2, x3, w1, w2, sumwx, sumw, nodeheight, rr;
505  node *pp, *plast;
506
507  if (p == root)
508    nodeheight = 0.0;
509  else if (uselengths)
510    nodeheight = lengthsum + p->oldlen;
511  else
512    nodeheight = 1.0;
513  if (nodeheight > maxheight)
514    maxheight = nodeheight;
515  if (p->tip) {
516    p->xcoord = *tipx;
517    if (uselengths)
518      p->ycoord = nodeheight;
519    else
520      p->ycoord = 1.0;
521    *tipx += tipspacing;
522    return;
523  }
524  sumwx = 0.0;
525  sumw = 0.0;
526  pp = p->next;
527  x3 = 0.0;
528  do {
529    calctraverse(pp->back, nodeheight,tipx);
530    sumw += pp->back->tipsabove;
531    sumwx += pp->back->tipsabove * pp->back->xcoord;
532    if (fabs(pp->back->xcoord - 0.5) < fabs(x3 - 0.5))
533      x3 = pp->back->xcoord;
534    plast = pp;
535    pp = pp->next;
536  } while (pp != p);
537  x1 = p->next->back->xcoord;
538  x2 = plast->back->xcoord;
539  y1 = p->next->back->ycoord;
540  y2 = plast->back->ycoord;
541  rr = 2 * (1.0 - stemlength) * treedepth * maxheight;
542  switch (nodeposition) {
543
544  case weighted:
545    w1 = y1 - nodeheight;
546    w2 = y2 - nodeheight;
547    if (w1 + w2 <= 0.0)
548      p->xcoord = (x1 + x2) / 2.0;
549    else
550      p->xcoord = (w2 * x1 + w1 * x2) / (w1 + w2);
551    break;
552
553  case intermediate:
554    p->xcoord = (x1 + x2) / 2.0;
555    break;
556
557  case centered:
558    p->xcoord = sumwx / sumw;
559    break;
560
561  case inner:
562    p->xcoord = x3;
563    break;
564
565  case vshaped:
566    p->xcoord = (x1 + x2 + (y1 - y2) / rr) / 2.0;
567    break;
568  }
569  if (uselengths) {
570    p->ycoord = nodeheight;
571    return;
572  }
573  if (nodeposition != inner) {
574    p->ycoord = (y1 + y2 - sqrt((y1 + y2) * (y1 + y2) - 4 * (y1 * y2 -
575                 rr * rr * (x2 - p->xcoord) * (p->xcoord - x1)))) / 2.0;
576
577    return;
578  }
579  if (fabs(x1 - 0.5) > fabs(x2 - 0.5)) {
580    p->ycoord = y1 + x1 - x2;
581    w1 = y2 - p->ycoord;
582  } else {
583    p->ycoord = y2 + x1 - x2;
584    w1 = y1 - p->ycoord;
585  }
586  if (w1 < epsilon)
587    p->ycoord -= fabs(x1 - x2);
588}  /* calctraverse */
589
590
591void calculate()
592{
593  /* compute coordinates for tree */
594  double tipx;
595  double sum, maxtextlength, textlength, firstlet, fontheight, angle;
596  long i;
597  for (i = 0; i < nextnode; i++)
598    nodep[i]->xcoord = 0.0;
599  for (i = 0; i < nextnode; i++)
600    nodep[i]->ycoord = 0.0;
601  maxheight = 0.0;
602  maxtextlength = 0.0;
603  if (nodep[0]->naymlength > 0)
604    firstlet = lengthtext(nodep[0]->nayme, 1L,font);
605  else
606    firstlet = 0.0;
607  sum = 0.0;
608  tipx = 0.0;
609    for (i = 0; i < nextnode; i++) {
610    if (nodep[i]->tip) {
611      textlength = lengthtext(nodep[i]->nayme, nodep[i]->naymlength,font);
612      if (textlength > maxtextlength)
613        maxtextlength = textlength;
614    }
615  }
616  fontheight = font[2];
617  angle = pi * labelrotation / 180.0;
618  maxtextlength /= fontheight;
619  textlength /= fontheight;
620  firstlet /= fontheight;
621  if (ntips > 1)
622    labelheight = 1.0 / (nodespace * (ntips - 1));
623  else
624    labelheight = 1.0 / nodespace;
625  if (angle < pi / 6.0)
626    tipspacing = (nodespace + cos(angle) * (maxtextlength - 0.5)) * labelheight;
627  else if (ntips > 1)
628    tipspacing = 1.0 / (ntips - 1.0);
629  else
630    tipspacing = 1.0;
631  topoflabels = labelheight *
632                (1.0 + sin(angle) * (maxtextlength - 0.5) + cos(angle) * 0.5);
633  rightoflabels = labelheight *
634                  (cos(angle) * (textlength - 0.5) + sin(angle) * 0.5);
635  leftoflabels = labelheight * (cos(angle) * firstlet * 0.5 + sin(angle) * 0.5);
636  calctraverse(root, sum, &tipx);
637  rooty = root->ycoord;
638  for (i = 0; i < nextnode; i++) {
639    if (rescaled) {
640      nodep[i]->xcoord *= 1.0 - stemlength;
641      nodep[i]->ycoord = stemlength * treedepth + (1.0 - stemlength) *
642            treedepth * (nodep[i]->ycoord - rooty) / (maxheight - rooty);
643    } else {
644      nodep[i]->xcoord = nodep[i]->xcoord * (maxheight - rooty) / treedepth;
645      nodep[i]->ycoord = stemlength / (1 - stemlength) * (maxheight - rooty) +
646                         nodep[i]->ycoord;
647    }
648  }
649  rooty = 0.0;
650}  /* calculate */
651
652
653void rescale()
654{
655  /* compute coordinates of tree for plot or preview device */
656  long i;
657  double treeheight, treewidth, extrax, extray, temp;
658
659  treeheight = 0.0;
660  for (i = 0; i < nextnode; i++) {
661    if (nodep[i]->ycoord > treeheight)
662      treeheight = nodep[i]->ycoord;
663  }
664  treewidth = (ntips - 1) * tipspacing + rightoflabels + leftoflabels;
665  if (rescaled) {
666    leftoflabels *= 1.0 - stemlength;
667    rightoflabels *= 1.0 - stemlength;
668    treewidth *= 1.0 - stemlength;
669  } else {
670    if (uselengths) {
671      labelheight = labelheight * (maxheight - rooty) / treedepth;
672      topoflabels = topoflabels * (maxheight - rooty) / treedepth;
673      leftoflabels = leftoflabels * (maxheight - rooty) / treedepth;
674      rightoflabels = rightoflabels * (maxheight - rooty) / treedepth;
675      treewidth = treewidth * (maxheight - rooty) / treedepth;
676    }
677  }
678  treeheight += topoflabels;
679  if (grows == vertical) {
680    if (!rescaled)
681      expand = bscale;
682    else {
683      expand = (xsize - 2 * xmargin) / treewidth;
684      if ((ysize - 2 * ymargin) / treeheight < expand)
685        expand = (ysize - 2 * ymargin) / treeheight;
686    }
687    extrax = (xsize - 2 * xmargin - treewidth * expand) / 2.0;
688    extray = (ysize - 2 * ymargin - treeheight * expand) / 2.0;
689  } else {
690    if (!rescaled)
691      expand = bscale;
692    else {
693      expand = (ysize - 2 * ymargin) / treewidth;
694      if ((xsize - 2 * xmargin) / treeheight < expand)
695        expand = (xsize - 2 * xmargin) / treeheight;
696    }
697    extrax = (xsize - 2 * xmargin - treeheight * expand) / 2.0;
698    extray = (ysize - 2 * ymargin - treewidth * expand) / 2.0;
699  }
700  for (i = 0; i < nextnode; i++) {
701    nodep[i]->xcoord = expand * (nodep[i]->xcoord + leftoflabels);
702    nodep[i]->ycoord = expand * (nodep[i]->ycoord - rooty);
703    if (grows == horizontal) {
704      temp = nodep[i]->ycoord;
705      nodep[i]->ycoord = expand * treewidth - nodep[i]->xcoord;
706      nodep[i]->xcoord = temp;
707    }
708    nodep[i]->xcoord += xmargin + extrax;
709    nodep[i]->ycoord += ymargin + extray;
710  }
711  if (grows == vertical)
712    rooty = ymargin + extray;
713  else
714    rooty = xmargin + extrax;
715}  /* rescale */
716
717
718
719void plottree(p, q)
720node *p, *q;
721{
722  /* plot part or all of tree on the plotting device */
723  long i;
724  double x1, y1, x2, y2, x3, y3, f, g, h, fract, minny, miny;
725  node *pp;
726
727  x2 = xscale * (xoffset + p->xcoord);
728  y2 = yscale * (yoffset + p->ycoord);
729  if (p != root) {
730    x1 = xscale * (xoffset + q->xcoord);
731    y1 = yscale * (yoffset + q->ycoord);
732    plot(penup, x1, y1);
733    switch (style) {
734
735    case cladogram:
736      plot(pendown, x2, y2);
737      break;
738
739    case phenogram:
740      if (grows == vertical)
741        plot(pendown, x2, y1);
742      else
743        plot(pendown, x1, y2);
744      plot(pendown, x2, y2);
745      break;
746
747    case curvogram:
748      for (i = 1; i <= segments; i++) {
749        f = (double)i / segments;
750        g = (double)i / segments;
751        h = 1.0 - sqrt(1.0 - g * g);
752        if (grows == vertical) {
753          x3 = x1 * (1.0 - f) + x2 * f;
754          y3 = y1 + (y2 - y1) * h;
755        } else {
756          x3 = x1 + (x2 - x1) * h;
757          y3 = y1 * (1.0 - f) + y2 * f;
758        }
759        plot(pendown, x3, y3);
760      }
761      break;
762
763    case eurogram:
764      if (grows == vertical)
765        plot(pendown, x2, (2 * y1 + y2) / 3);
766      else
767        plot(pendown, (2 * x1 + x2) / 3, y2);
768      plot(pendown, x2, y2);
769      break;
770
771    case swoopogram:
772      if ((grows == vertical && fabs(y1 - y2) >= epsilon) ||
773          (grows == horizontal && fabs(x1 - x2) >= epsilon)) {
774        if (grows == vertical)
775          miny = p->ycoord;
776        else
777          miny = p->xcoord;
778        pp = q->next;
779        while (pp != q) {
780          if (grows == vertical)
781            minny = pp->back->ycoord;
782          else
783            minny = pp->back->xcoord;
784          if (minny < miny)
785            miny = minny;
786          pp = pp->next;
787        }
788        if (grows == vertical)
789          miny = yscale * (yoffset + miny);
790        else
791          miny = xscale * (xoffset + miny);
792        if (grows == vertical)
793          fract = 0.3333 * (miny - y1) / (y2 - y1);
794        else
795          fract = 0.3333 * (miny - x1) / (x2 - x1);
796        for (i = 1; i <= segments; i++) {
797          f = (double)i / segments;
798          if (f < fract)
799            g = f / fract;
800          else
801            g = (f - fract) / (1.0 - fract);
802          if (f < fract)
803            h = fract * sqrt(1.0 - (1.0 - g) * (1.0 - g));
804          else
805            h = fract + (1.0 - fract) * (1.000001 - sqrt(1.000001 - g * g));
806          if (grows == vertical) {
807            x3 = x1 * (1.0 - f) + x2 * f;
808            y3 = y1 + (y2 - y1) * h;
809          } else {
810            x3 = x1 + (x2 - x1) * h;
811            y3 = y1 * (1.0 - f) + y2 * f;
812          }
813          plot(pendown, x3, y3);
814        }
815      }
816      break;
817    }
818  } else {
819    if (grows == vertical) {
820      x1 = xscale * (xoffset + p->xcoord);
821      y1 = yscale * (yoffset + rooty);
822    } else {
823      x1 = xscale * (xoffset + rooty);
824      y1 = yscale * (yoffset + p->ycoord);
825    }
826    plot(penup, x1, y1);
827    plot(pendown, x2, y2);
828  }
829  if (p->tip)
830    return;
831  pp = p->next;
832  while (pp != p) {
833    plottree(pp->back, p);
834    pp = pp->next;
835  }
836}  /* plottree */
837
838
839
840void plotlabels(fontname)
841char *fontname;
842{
843  long i;
844  double compr, dx, dy, angle;
845  node *lp;
846
847  compr = xunitspercm / yunitspercm;
848  if (penchange == yes)
849    changepen(labelpen);
850  angle = labelrotation * pi / 180.0;
851  for (i = 0; i < (nextnode); i++) {
852    if (nodep[i]->tip) {
853      lp = nodep[i];
854      dx = labelheight * expand * -0.70710 * cos(angle + pi / 4.0);
855      dy = labelheight * expand * (1.0 - 0.70710 * sin(angle + pi / 4.0));
856      if (grows == vertical)
857        plottext(lp->nayme, lp->naymlength,
858                 labelheight * expand * xscale / compr, compr,
859                 xscale * (lp->xcoord + dx + xoffset),
860                 yscale * (lp->ycoord + dy + yoffset),
861                 -labelrotation, font,fontname);
862      else
863        plottext(lp->nayme, lp->naymlength, labelheight * expand * yscale,
864                 compr, xscale * (lp->xcoord + dy + xoffset),
865                 yscale * (lp->ycoord - dx + yoffset), 90.0 - labelrotation,
866                 font,fontname);
867    }
868  }
869  if (penchange == yes)
870    changepen(treepen);
871}  /* plotlabels */
872
873
874
875main(argc, argv)
876long argc;
877Char *argv[];
878{
879  long i,n,stripedepth;
880  boolean canbeplotted;
881
882#ifdef MAC
883  OSErr retcode;
884  FInfo  fndrinfo;
885  macsetup("Drawgram","Preview");
886#endif
887#ifdef TURBOC
888  if ((registerbgidriver(EGAVGA_driver) <0) ||
889      (registerbgidriver(Herc_driver) <0)   ||
890      (registerbgidriver(CGA_driver) <0)){
891    printf("Graphics error: %s ",grapherrormsg(graphresult()));
892    exit(-1);}
893#endif
894  strcpy(fontname,"Hershey");
895
896  openfile(&plotfile,PLOTFILE,"w",argv[0],pltfilename);
897  openfile(&treefile,TREEFILE,"r",argv[0],NULL);
898
899  printf("DRAWGRAM from PHYLIP version %s\n",VERSION);
900  printf("Reading tree ... \n");
901  treeread();
902
903  printf("Tree has been read.\nLoading the font .... \n");
904  loadfont(font,argv[0]);
905  printf("Font loaded.\n");
906  previewing = false;
907  initialparms();
908  canbeplotted = false;
909  while (!canbeplotted) {
910    do {
911      n=showparms();
912      if (!= -1)
913        getparms(n);
914    } while (!= -1);
915    calculate();
916    rescale();
917    canbeplotted = true;
918    if (preview)
919      canbeplotted=plotpreview(fontname,&xoffset,&yoffset,&scale,ntips,root);
920  }
921  if (dotmatrix) {
922     stripedepth = allocstripe(stripe,(strpwide/8),
923                            ((long)(yunitspercm * ysize)));
924     strpdeep = stripedepth;
925     strpdiv  = stripedepth;
926     }
927  previewing = false;
928  initplotter(ntips,fontname);
929  numlines = dotmatrix ? ((long)floor(yunitspercm * ysize + 0.5)/strpdeep) : 1;
930  if (plotter != ibmpc)
931    printf("Writing plot file ...\n");
932  drawit(fontname,&xoffset,&yoffset,numlines,root);
933  finishplotter();
934  FClose(plotfile);
935  FClose(treefile);
936  printf("Finished.\nEnd of run.\n");
937#ifdef MAC
938if (plotter == pict){
939  retcode=GetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);
940  fndrinfo.fdType='PICT';
941  fndrinfo.fdCreator='MDRW';
942  retcode=SetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);}
943if (plotter == lw){
944  retcode=GetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);
945  fndrinfo.fdType='TEXT';
946  retcode=SetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);}
947#endif
948  exit(0);
949}
950
951
952
953int eof(f)
954FILE *f;
955{
956    register long ch;
957
958    if (feof(f))
959        return 1;
960    if (f == stdin)
961        return 0;
962    ch = getc(f);
963    if (ch == EOF)
964        return 1;
965    ungetc(ch, f);
966    return 0;
967}
968
969
970int eoln(f)
971FILE *f;
972{
973    register long ch;
974
975    ch = getc(f);
976    if (ch == EOF)
977        return 1;
978    ungetc(ch, f);
979    return (ch == '\n');
980}
981
982void memerror()
983{
984printf("Error allocating memory\n");
985exit(-1);
986}
987
988MALLOCRETURN *mymalloc(x)
989long x;
990{
991MALLOCRETURN *mem;
992mem = (MALLOCRETURN *)malloc((size_t)x);
993if (!mem)
994     memerror();
995else
996     return (MALLOCRETURN *)mem;
997
998}
999
Note: See TracBrowser for help on using the repository browser.