home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 7
/
FreshFishVol7.bin
/
new
/
misc
/
sci
/
splines
/
bezier.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-16
|
3KB
|
84 lines
/* The routines in this file are copyright (c) 1987 by Helene (Lee) Taran.
* Permission is granted for use and free distribution as long as the
* original author's name is included with the code.
*/
/*
* Reformatted, and modified to compile without warnings and errors
* under SAS/C -6.5x by gduncan@philips.oz.au (GMD). This included
* proto generation, renaming of some literals to avoid name collisions,
* and Amiga Version string (also displayed in Title bar).
* No original version number, this version arbitrarily named 1.1.
* - otherwise no functional changes.
* GMD - Sep 94
*/
#include "all.h"
/* Midpoint: returns the midpoint of the line through <p0> and <p1> */
void
Midpoint (m, p0, p1)
REAL_POINT *m, *p0, *p1;
{
m->x = (p0->x + p1->x) / 2;
m->y = (p0->y + p1->y) / 2;
}
/* TickMark : returns the point that is n/d of the way
* between <p0> and <p1>. If you just want to divide the line in
* half use Midpoint.
*/
void
TickMark (t, n, d, p0, p1)
REAL_POINT *t;
int n, d;
REAL_POINT *p0, *p1;
{
t->x = p0->x + (p1->x - p0->x) * n / d;
t->y = p0->y + (p1->y - p0->y) * n / d;
}
/* DrawBezierArc: draws a bezier arc between the 4 given points by
* recursively subdividing the curve until each segment is close
* enough to be rendered as a line.
* Assumes that your window <w> has been initialized and opened and that
* in addition to the intuition library, the graphics library is open
*/
void
DrawBezierArc (w, p000, p001, p011, p111)
WINDOW *w; /* draw the arc in this window */
REAL_POINT *p000, *p001, *p011, *p111; /* bezier control points */
{
REAL_POINT p00t, p0t1, pt11, p0tt, ptt1, pttt;
float delta1 = (p001->x * p011->y - p001->y * p011->x) -
(p000->x * p011->y - p000->y * p011->x) +
(p000->x * p001->y - p000->y * p001->x);
float delta2 = (p111->x * p011->y - p111->y * p011->x) -
(p000->x * p011->y - p000->y * p011->x) +
(p000->x * p111->y - p000->y * p111->x);
if (ABS (delta1) + ABS (delta2) <= CLOSENESS)
{ /* so close, just draw a line */
Move (w->RPort, (long) p000->x, (long) p000->y);
Draw (w->RPort, (long) p111->x, (long) p111->y);
}
else
{ /* divide the arc into two smaller bezier arcs */
Midpoint (&p00t, p000, p001);
Midpoint (&p0t1, p001, p011);
Midpoint (&pt11, p011, p111);
Midpoint (&p0tt, &p00t, &p0t1);
Midpoint (&ptt1, &p0t1, &pt11);
Midpoint (&pttt, &p0tt, &ptt1);
DrawBezierArc (w, p000, &p00t, &p0tt, &pttt);
DrawBezierArc (w, &pttt, &ptt1, &pt11, p111);
}
}
/*--*/