home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume8
/
xfig2.8
/
part03
/
curve.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-02
|
3KB
|
139 lines
/*
* FIG : Facility for Interactive Generation of figures
*
* Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
* January 1985.
* 1st revision : Aug 1985.
*
* %W% %G%
*/
#include "fig.h"
#include "resources.h"
#include "paintop.h"
#define round(a) ((int)((a) + .5))
/* This routine plot two dimensional curve defined by a second degree
polynomial of the form :
2 2
f(x, y) = ax + by + g = 0
(x0,y0) is the starting point as well as ending point of the curve.
The curve will translate with the offset xoff and yoff.
This algorithm is derived from the eight point algorithm in :
"An Improved Algorithm for the generation of Nonparametric Curves"
by Bernard W. Jordan, William J. Lennon and Barry D. Holm, IEEE
Transaction on Computers Vol C-22, No. 12 December 1973.
Will fill the curve if area_fill is != 0
*/
curve(window, xstart, ystart, xend, yend, direction,
a, b, xoff, yoff, val, thick, style, style_val, area_fill)
Window window;
int xstart, ystart, xend, yend, a, b, xoff, yoff;
int direction, val, thick, style, area_fill;
float style_val;
{
int dfx, dfy, dfxx, dfyy;
int falpha, fx, fy, fxy, absfx, absfy, absfxy;
int margin, test_succeed, x, y, deltax, deltay, inc, dec;
int npoints;
int max_points;
XPoint *points;
if (a == 0 || b == 0)
return;
max_points = a + b + 1; /* 1 for end point */
if (max_points > 4000)
max_points = 4000;
if ((points = (XPoint *) malloc(max_points*sizeof(XPoint))) == 0)
{
fprintf(stderr,"curve(): No memory\n");
return;
}
x = xstart;
y = ystart;
dfx = 2 * a * xstart;
dfy = 2 * b * ystart;
dfxx = 2 * a;
dfyy = 2 * b;
falpha = 0;
if (direction) {
inc = 1; dec = -1;
}
else {
inc = -1; dec = 1;
}
if (xstart == xend && ystart == yend) {
test_succeed = margin = 1;
}
else {
test_succeed = 3; margin = 3;
}
npoints = 0;
while (test_succeed) {
if (npoints >= (max_points-1))
{
XPoint *tmp_p;
max_points += a + b;
if (max_points > 4000)
break; /* stop! It is not closing */
if ((tmp_p = (XPoint *) realloc(points, max_points*sizeof(XPoint))) == 0)
{
fprintf(stderr,"curve(): No memory(realloc)\n");
break;
}
free(points);
points = tmp_p;
}
points[npoints].x = (short) xoff+x;
points[npoints].y = (short) yoff-y;
npoints++;
if (dfy < 0)
deltax = inc;
else
deltax = dec;
if (dfx < 0)
deltay = dec;
else
deltay = inc;
fx = falpha + dfx * deltax + a;
fy = falpha + dfy * deltay + b;
fxy = fx + fy - falpha;
absfx = abs(fx); absfy = abs(fy); absfxy = abs(fxy);
if ((absfxy <= absfx) && (absfxy <= absfy))
falpha = fxy;
else if (absfy <= absfx) {
deltax = 0; falpha = fy;
}
else {
deltay = 0; falpha = fx;
}
x = x + deltax; y = y + deltay;
dfx = dfx + dfxx * deltax;
dfy = dfy + dfyy * deltay;
if (abs(x - xend) < margin && abs(y - yend) < margin)
test_succeed--;
}
if (margin == 1) /* end points should touch */
{
points[npoints].x = (short) xoff+xstart;
points[npoints].y = (short) yoff-ystart;
}
pw_lines(window, points, npoints, val? PAINT: ERASE,
thick, style, style_val, area_fill);
free(points);
}