home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / new / misc / sci / splines / bezier.c < prev    next >
C/C++ Source or Header  |  1994-09-16  |  3KB  |  84 lines

  1. /* The routines in this file are copyright (c) 1987 by Helene (Lee) Taran.
  2.  * Permission is granted for use and free distribution as long as the
  3.  * original author's name is included with the code.
  4.  */
  5.  
  6. /*
  7.  * Reformatted, and modified to compile without warnings and errors
  8.  * under SAS/C -6.5x by gduncan@philips.oz.au (GMD). This included
  9.  * proto generation, renaming of some literals to avoid name collisions,
  10.  * and Amiga Version string (also displayed in Title bar).
  11.  * No original version number, this version arbitrarily named 1.1. 
  12.  * - otherwise no functional changes.
  13.  * GMD - Sep 94
  14.  */
  15.  
  16. #include "all.h"
  17.  
  18. /* Midpoint: returns the midpoint of the line through <p0> and <p1> */
  19.  
  20. void
  21. Midpoint (m, p0, p1)
  22.      REAL_POINT *m, *p0, *p1;
  23. {
  24.   m->x = (p0->x + p1->x) / 2;
  25.   m->y = (p0->y + p1->y) / 2;
  26. }
  27.  
  28.  
  29. /* TickMark : returns the point that is n/d of the way 
  30.  * between <p0> and <p1>. If you just want to divide the line in
  31.  * half use Midpoint.
  32.  */
  33.  
  34. void
  35. TickMark (t, n, d, p0, p1)
  36.      REAL_POINT *t;
  37.      int n, d;
  38.      REAL_POINT *p0, *p1;
  39. {
  40.   t->x = p0->x + (p1->x - p0->x) * n / d;
  41.   t->y = p0->y + (p1->y - p0->y) * n / d;
  42. }
  43.  
  44.  
  45. /* DrawBezierArc: draws a bezier arc between the 4 given points by
  46.  * recursively subdividing the curve until each segment is close
  47.  * enough to be rendered as a line.
  48.  * Assumes that your window <w> has been initialized and opened and that
  49.  * in addition to the intuition library, the graphics library is open
  50.  */
  51.  
  52. void
  53. DrawBezierArc (w, p000, p001, p011, p111)
  54.      WINDOW *w;            /* draw the arc in this window */
  55.      REAL_POINT *p000, *p001, *p011, *p111;    /* bezier control points */
  56. {
  57.   REAL_POINT p00t, p0t1, pt11, p0tt, ptt1, pttt;
  58.   float delta1 = (p001->x * p011->y - p001->y * p011->x) -
  59.   (p000->x * p011->y - p000->y * p011->x) +
  60.   (p000->x * p001->y - p000->y * p001->x);
  61.  
  62.   float delta2 = (p111->x * p011->y - p111->y * p011->x) -
  63.   (p000->x * p011->y - p000->y * p011->x) +
  64.   (p000->x * p111->y - p000->y * p111->x);
  65.  
  66.   if (ABS (delta1) + ABS (delta2) <= CLOSENESS)
  67.     {                /* so close, just draw a line */
  68.       Move (w->RPort, (long) p000->x, (long) p000->y);
  69.       Draw (w->RPort, (long) p111->x, (long) p111->y);
  70.     }
  71.   else
  72.     {                /* divide the arc into two smaller bezier arcs */
  73.       Midpoint (&p00t, p000, p001);
  74.       Midpoint (&p0t1, p001, p011);
  75.       Midpoint (&pt11, p011, p111);
  76.       Midpoint (&p0tt, &p00t, &p0t1);
  77.       Midpoint (&ptt1, &p0t1, &pt11);
  78.       Midpoint (&pttt, &p0tt, &ptt1);
  79.       DrawBezierArc (w, p000, &p00t, &p0tt, &pttt);
  80.       DrawBezierArc (w, &pttt, &ptt1, &pt11, p111);
  81.     }
  82. }
  83. /*--*/
  84.