v06i006: HPGL to PostScript converter (Part 4 of 6)

Brandon S. Allbery - comp.sources.misc allbery at uunet.UU.NET
Sun Jan 22 06:31:03 AEST 1989


Posting-number: Volume 6, Issue 6
Submitted-by: federico at actisb.UUCP (Federico Heinz)
Archive-name: yahp2ps/part04

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 6)."
# Contents:  COPYING circle.c edge.c
# Wrapped by federico at actisb on Wed Jan  4 13:34:48 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'COPYING' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'COPYING'\"
else
echo shar: Extracting \"'COPYING'\" \(7122 characters\)
sed "s/^X//" >'COPYING' <<'END_OF_FILE'
X
X		    yahp2ps GENERAL PUBLIC LICENSE
X		    (Clarified 11 Feb 1988)
X
X Copyright (C) 1988 Richard M. Stallman
X Everyone is permitted to copy and distribute verbatim copies
X of this license, but changing it is not allowed.  You can also
X use this wording to make the terms for other programs. 
X
X  The license agreements of most software companies keep you at the
Xmercy of those companies.  By contrast, my general public license is
Xintended to give everyone the right to share yahp2ps.  To make sure that
Xyou get the rights I want you to have, I need to make restrictions that
Xforbid anyone to deny you these rights or to ask you to surrender the
Xrights.  Hence this license agreement. 
X
X  Specifically, I want to make sure that you have the right to give away
Xcopies of yahp2ps, that you receive source code or else can get it if
Xyou want it, that you can change yahp2ps or use pieces of it in new free
Xprograms, and that you know you can do these things. 
X
X  To make sure that everyone has such rights, I have to forbid you to
Xdeprive anyone else of these rights.  For example, if you distribute
Xcopies of yahp2ps, you must give the recipients all the rights that you
Xhave.  You must make sure that they, too, receive or can get the source
Xcode.  And you must tell them their rights. 
X
X  Also, for my own protection, I must make certain that everyone finds
Xout that there is no warranty for yahp2ps.  If yahp2ps is modified by
Xsomeone else and passed on, I want its recipients to know that what they
Xhave is not what I distributed, so that any problems introduced by
Xothers will not reflect on my reputation. 
X
X  Therefore I (Federico Heinz) make the following terms which say what
Xyou must do to be allowed to distribute or change yahp2ps. 
X
X
X			COPYING POLICIES
X
X  1.  You may copy and distribute verbatim copies of yahp2ps source code
Xas you receive it, in any medium, provided that you conspicuously and
Xappropriately publish on each copy a valid copyright notice "Copyright
X(C) 1988 Federico Heinz." (or with whatever year is appropriate); keep
Xintact the notices on all files that refer to this License Agreement and
Xto the absence of any warranty; and give any other recipients of the
Xyahp2ps program a copy of this License Agreement along with the program. 
XYou may charge a distribution fee for the physical act of transferring a
Xcopy. 
X
X  2.  You may modify your copy or copies of yahp2ps or any portion of
Xit, and copy and distribute such modifications under the terms of
XParagraph 1 above, provided that you also do the following:
X
X    a) cause the modified files to carry prominent notices stating
X    that you changed the files and the date of any change; and
X
X    b) cause the whole of any work that you distribute or publish,
X    that in whole or in part contains or is a derivative of yahp2ps or
X    any part thereof, to be licensed at no charge to all third
X    parties on terms identical to those contained in this License
X    Agreement (except that you may choose to grant more extensive
X    warranty protection to some or all third parties, at your option).
X
X    c) You may charge a distribution fee for the physical act of
X    transferring a copy, and you may at your option offer warranty
X    protection in exchange for a fee.
X
XMere aggregation of another unrelated program with this program (or its
Xderivative) on a volume of a storage or distribution medium does not bring
Xthe other program under the scope of these terms.
X
X  3.  You may copy and distribute yahp2ps (or a portion or derivative of
Xit, under Paragraph 2) in object code or executable form under the terms
Xof Paragraphs 1 and 2 above provided that you also do one of the
Xfollowing:
X
X    a) accompany it with the complete corresponding machine-readable
X    source code, which must be distributed under the terms of
X    Paragraphs 1 and 2 above; or,
X
X    b) accompany it with a written offer, valid for at least three
X    years, to give any third party free (except for a nominal
X    shipping charge) a complete machine-readable copy of the
X    corresponding source code, to be distributed under the terms of
X    Paragraphs 1 and 2 above; or,
X
X    c) accompany it with the information you received as to where the
X    corresponding source code may be obtained.  (This alternative is
X    allowed only for noncommercial distribution and only if you
X    received the program in object code or executable form alone.)
X
XFor an executable file, complete source code means all the source code for
Xall modules it contains; but, as a special exception, it need not include
Xsource code for modules which are standard libraries that accompany the
Xoperating system on which the executable file runs.
X
X  4.  You may not copy, sublicense, distribute or transfer yahp2ps
Xexcept as expressly provided under this License Agreement.  Any attempt
Xotherwise to copy, sublicense, distribute or transfer yahp2ps is void
Xand your rights to use the program under this License agreement shall be
Xautomatically terminated.  However, parties who have received computer
Xsoftware programs from you with this License Agreement will not have
Xtheir licenses terminated so long as such parties remain in full
Xcompliance. 
X
X  5.  If you wish to incorporate parts of yahp2ps into other free
Xprograms whose distribution conditions are different, write to the
XFederico Heinz, Beusselstr.  21, D-1000 Berlin 21, West Germany.  I have
Xnot yet worked out a simple rule that can be stated here, but I will
Xoften permit this.  I will be guided by the two goals of preserving the
Xfree status of all derivatives of my free software and of promoting the
Xsharing and reuse of software. 
X
XYour comments and suggestions about my licensing policies and my
Xsoftware are welcome! Please contact the Federico Heinz, Beusselstr. 21,
XD-1000 Berlin 21, West Germany, or call (+49 30) 396 77 92. 
X
X		       NO WARRANTY
X
X  BECAUSE yahp2ps IS LICENSED FREE OF CHARGE, I PROVIDE ABSOLUTELY NO
XWARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT WHEN
XOTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD M. 
XSTALLMAN AND/OR OTHER PARTIES PROVIDE yahp2ps "AS IS" WITHOUT WARRANTY
XOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
XTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
XPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF yahp2ps
XIS WITH YOU.  SHOULD yahp2ps PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
XNECESSARY SERVICING, REPAIR OR CORRECTION. 
X
X IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. 
XSTALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY WHO
XMAY MODIFY AND REDISTRIBUTE yahp2ps AS PERMITTED ABOVE, BE LIABLE TO YOU
XFOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
XINCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY
XTO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
XINACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
XPROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) yahp2ps, EVEN IF YOU HAVE
XBEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY
XOTHER PARTY. 
X
END_OF_FILE
if test 7122 -ne `wc -c <'COPYING'`; then
    echo shar: \"'COPYING'\" unpacked with wrong size!
fi
# end of 'COPYING'
fi
if test -f 'circle.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'circle.c'\"
else
echo shar: Extracting \"'circle.c'\" \(9416 characters\)
sed "s/^X//" >'circle.c' <<'END_OF_FILE'
X/*
X        HPGL to PostScript converter
X   Copyright (C) 1988 (and following) Federico Heinz
X
Xyahp2ps is distributed in the hope that it will be useful, but WITHOUT ANY
XWARRANTY.  No author or distributor accepts responsibility to anyone
Xfor the consequences of using it or for whether it serves any
Xparticular purpose or works at all, unless he says so in writing.
XRefer to the Free Software Foundation's General Public License for full details.
X
XEveryone is granted permission to copy, modify and redistribute yahp2ps,
Xbut only under the conditions described in the GNU General Public
XLicense.  A copy of this license is supposed to have been given to you
Xalong with yahp2ps so you can know your rights and responsibilities.  It
Xshould be in a file named COPYING.  Among other things, the copyright
Xnotice and this notice must be preserved on all copies.
X
XIn other words, go ahead and share yahp2ps, but don't try to stop
Xanyone else from sharing it farther.  Help stamp out software hoarding!
X
Xyahp2ps is TOTALLY unrelated to GNU or the Free Software Foundation,
Xit is only released under the same conditions.
X
X    For bug reports, wishes, etc. send e-mail to
X
X    ...!mcvax!unido!tub!actisb!federico  (from Europe)
X    ...!uunet!pyramid!actisb!federico    (from anywhere else)
X
X    For Physical mail:
X
X    Federico Heinz
X    Beusselstr. 21
X    1000 Berlin 21
X
X    Tel. (+49 30) 396 77 92
X
X*/
X/**************************************************************************
X
X   Arithmetical support for circle/arc stuff
X
X**************************************************************************/
X
X#include <ctype.h>
X#include "defs.h"
X#include "circle.h"
X#include "io.h"
X
X
X/**************************************************************************
X
X  Trigonometry stuff, where I can give free fly to my floating-point
X  hate and my love for letting the compiler do the job.
X
X**************************************************************************/
X
X
X
X/* Table to convert the normalized angle returned by octantAngle to
X   it's "equivalent" in the specified octant */
X
X
Xtypedef struct
X  { int     sign;
X    Number  base;
X    Boolean swappedFncts;
X    int     cosineFactor;
X    int     sineFactor;
X  } Octant;
X
X
X
Xstatic Octant OctantTable[]=
X  { { 1, Zero,         False,  1,  1},
X    {-1, OneSquare,    True,   1,  1},
X    { 1, OneSquare,    True,  -1,  1},
X    {-1, TwoSquares,   False, -1,  1},
X    { 1, TwoSquares,   False, -1, -1},
X    {-1, ThreeSquares, True,  -1, -1},
X    { 1, ThreeSquares, True,   1, -1},
X    {-1, FullCircle,   False,  1, -1}
X  };
X
X
X/*
X
X  Map an angle to the first octant and return a pointer to the octant
X  conversion structure that enables to do inter-octant mapping. The
X  mapped angle is in INTEGER degrees, not Number.
X
X*/
X
Xstatic Octant *classifyAngle(angle)
X
XNumber *angle;
X
X{ Number result;
X  Octant *octant;
X
X  *angle = *angle % FullCircle;
X  if (*angle < Zero)
X    *angle = FullCircle + *angle;
X  octant = OctantTable + *angle / (OneSquare / 2);
X  result = (*angle % OneSquare) / One;
X  if (result > ((OneSquare / One) / 2))
X    *angle = (OneSquare / One) - result;
X  else
X    *angle = result;
X  return(octant);
X}
X
X
X
X/*
X
X  Normalize the cathetes such that:
X                                    they're both positive
X                                    the X cathete is longer than the Y.
X  Return also a pointer to the octant conversion structure that enables
X  to map an angle from the 1st octant into the cathetes' octant.
X
X*/
X
Xstatic Octant *classifyCathetes(target, cathetes)
X
XCoordinatePair target, cathetes;
X
X{ Number dummy;
X  int    octant;
X
X  if (cathetes[Y] >= Zero)
X  { target[Y] = cathetes[Y];
X    octant = 0;
X  }
X  else
X  { target[Y] = -cathetes[Y];
X    octant = 4;
X  }
X  if (cathetes[X] >= Zero)
X  { target[X] = cathetes[X];
X    if (octant) octant |= 3;
X  }
X  else
X  { target[X] = -cathetes[X];
X    if (!octant) octant |= 3;
X  }
X  if (target[X] < target[Y])
X  { octant ^= 1;
X    dummy = target[X];
X    target[X] = target[Y];
X    target[Y] = dummy;
X  }
X  return(OctantTable + octant);
X}
X
X
X
X/*
X
X  These tables contain the values for the cosine, sine and tangent of
X  all integer angles between 0 and 45 degrees (or at least so says my
X  math library).
X
X*/
X
Xstatic Number CosineTable[] = {
X  10000L,  9998L,  9993L,  9986L,  9975L,  9961L,  9945L,  9925L,
X   9902L,  9876L,  9848L,  9816L,  9781L,  9743L,  9702L,  9659L,
X   9612L,  9563L,  9510L,  9455L,  9396L,  9335L,  9271L,  9205L,
X   9135L,  9063L,  8987L,  8910L,  8829L,  8746L,  8660L,  8571L,
X   8480L,  8386L,  8290L,  8191L,  8090L,  7986L,  7880L,  7771L,
X   7660L,  7547L,  7431L,  7313L,  7193L,  7071L };
X
Xstatic Number SineTable[] = {
X      0L,   174L,   348L,   523L,   697L,   871L,  1045L,  1218L,
X   1391L,  1564L,  1736L,  1908L,  2079L,  2249L,  2419L,  2588L,
X   2756L,  2923L,  3090L,  3255L,  3420L,  3583L,  3746L,  3907L,
X   4067L,  4226L,  4383L,  4539L,  4694L,  4848L,  4999L,  5150L,
X   5299L,  5446L,  5591L,  5735L,  5877L,  6018L,  6156L,  6293L,
X   6427L,  6560L,  6691L,  6819L,  6946L,  7071L };
X
Xstatic int TangentTable[] = {
X      0,   174,   349,   524,   699,   874,  1051,  1227,
X   1405,  1583,  1763,  1943,  2125,  2308,  2493,  2679,
X   2867,  3057,  3249,  3443,  3639,  3838,  4040,  4244,
X   4452,  4663,  4877,  5095,  5317,  5543,  5773,  6008,
X   6248,  6494,  6745,  7002,  7265,  7535,  7812,  8097,
X   8390,  8692,  9004,  9325,  9656, 10000 };
X
X
X/*
X
X  Search the angle corresponding to a certain value in the table.
X
X*/
X
Xstatic int search(value, table)
X
Xint value, table[];
X
X{ int lo, hi, mid;
X
X  lo = 0; hi = 45;
X  while (lo <= hi)
X  { mid = (lo + hi) / 2;
X    if (value < table[mid])
X      hi = mid - 1;
X    else if (value > table[mid])
X      lo = mid + 1;
X    else
X      return(mid);
X  }
X  return((value-table[hi] < table[lo]-value) ? hi : lo);
X}
X
X
X
X/*
X
X  Compute the only 1st-octant angle that can generate these cathetes.
X
X*/
X
Xstatic Number octantAngle(cathetes)
X
XCoordinatePair cathetes;
X
X{ int tangent;
X
X  tangent = (int)divNum(cathetes[Y], cathetes[X]);
X  return(search(tangent, TangentTable) * One);
X}
X
X
X
X/*
X
X  Compute the only angle that can generate these cathetes.
X
X*/
X
Xstatic Number arcTangent(cathetes)
X
XCoordinatePair cathetes;
X
X{ Octant *octant;
X  CoordinatePair normalizedCathetes;
X
X  octant = classifyCathetes(normalizedCathetes, cathetes);
X  return(octantAngle(normalizedCathetes) * octant->sign + octant->base);
X}
X
X
X
X/*
X
X  Compute the cosine of an angle.
X
X*/
X
Xstatic Number cosine(angle)
X
XNumber angle;
X
X{ Octant *octant;
X
X  octant = classifyAngle(&angle);
X  return((octant->swappedFncts ? SineTable[angle] : CosineTable[angle])
X          * octant->cosineFactor);
X}
X
X   
X
X/*
X
X  Compute the sine of an angle.
X
X*/
X
Xstatic Number sine(angle)
X
XNumber angle;
X
X{ Octant *octant;
X
X  octant = classifyAngle(&angle);
X  return((octant->swappedFncts ? CosineTable[angle] : SineTable[angle])
X          * octant->sineFactor);
X}
X
X   
X
X/*************************************************************************
X
X   Coordinate computing stuff
X
X*************************************************************************/
X
X
X/*
X
X  Set target to the coordinates of the point that is located at
X  polar coordinates (radius, angle) from center.
X
X*/
X
Xvoid polarToCartesian(target, center, radius, angle)
X
XCoordinatePair target, center;
XNumber radius, angle;
X
X{ target[X] = center[X] + mulNum(cosine(angle), radius);
X  target[Y] = center[Y] + mulNum(sine(angle), radius);
X}
X
X
X
X
X/*
X
X   Compute radius and angle given an offset to the center.
X
X*/
X
Xvoid cartesianToPolar(radius, angle, offset)
X
XNumber *radius, *angle;
XCoordinatePair offset;
X
X{ Number cosineOfAngle;
X
X  *angle = arcTangent(offset);
X  if (cosineOfAngle = cosine(*angle))	/* Watch out for cos(a) == 0!!! */
X    *radius = divNum(offset[X], cosineOfAngle);
X  else
X    *radius = offset[X] ? offset[X] : offset[Y];
X  if (*radius < 0) *radius = -*radius;
X}
X
X
X
X/*
X
X  Return an angle suitable for a curve operation. It must divide the
X  sweep angle, and must be between the minimum and maximum values specified.
X  In case the sweep angle is a prime number, then compromise must be
X  done. I then take the maxValue angle and make the last step
X  shorter. This is not all compatible with the HP plotters, but then
X  they enter an ENDLESS LOOP when this constellation occurs (at least
X  mine does)
X  
X*/
X
X
XNumber correctedChordAngle(maxValue, sweepAngle, minValue)
X
XNumber maxValue, sweepAngle, minValue;
X
X{ Number i;
X  
X  if (maxValue < 0)     /* Ignore sign */
X    maxValue = -maxValue;
X  maxValue = maxValue % FullCircle;
X  if (maxValue < minValue)
X    return(minValue);
X  if (!(maxValue && (sweepAngle % maxValue)))
X    return(maxValue);	/* High-resolution arc or exact division */
X  i = maxValue - One;
X  while(sweepAngle % i)
X  { i -= One;
X    if (i < minValue) return(maxValue);
X  }
X  return(i);
X}
X
X
X
X/*
X
X  Twist the start and the sweep angles so as to make sense.
X
X*/
X
Xvoid fixUpStartAndSweep(startAngle, sweepAngle)
X
XNumber *startAngle, *sweepAngle;
X
X{ *startAngle = *startAngle % FullCircle;
X  if ((*sweepAngle > FullCircle) || (*sweepAngle < -FullCircle))
X    *sweepAngle = FullCircle;
X}
X
X
X
X/*
X
X  Get the optional chord angle parameter.
X
X*/
X
Xvoid getChordAngle(target, sweepAngle, minValue)
X
XNumber *target;
XNumber sweepAngle, minValue;
X
X{ if (isNumeric(LookAhead))
X    (void)getInteger(target);
X  else
X    *target = DefaultChordAngle;
X  *target = correctedChordAngle(*target, sweepAngle, minValue);
X}
X
END_OF_FILE
if test 9416 -ne `wc -c <'circle.c'`; then
    echo shar: \"'circle.c'\" unpacked with wrong size!
fi
# end of 'circle.c'
fi
if test -f 'edge.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'edge.c'\"
else
echo shar: Extracting \"'edge.c'\" \(7129 characters\)
sed "s/^X//" >'edge.c' <<'END_OF_FILE'
X/*
X        HPGL to PostScript converter
X   Copyright (C) 1988 (and following) Federico Heinz
X
Xyahp2ps is distributed in the hope that it will be useful, but WITHOUT ANY
XWARRANTY.  No author or distributor accepts responsibility to anyone
Xfor the consequences of using it or for whether it serves any
Xparticular purpose or works at all, unless he says so in writing.
XRefer to the Free Software Foundation's General Public License for full details.
X
XEveryone is granted permission to copy, modify and redistribute yahp2ps,
Xbut only under the conditions described in the GNU General Public
XLicense.  A copy of this license is supposed to have been given to you
Xalong with yahp2ps so you can know your rights and responsibilities.  It
Xshould be in a file named COPYING.  Among other things, the copyright
Xnotice and this notice must be preserved on all copies.
X
XIn other words, go ahead and share yahp2ps, but don't try to stop
Xanyone else from sharing it farther.  Help stamp out software hoarding!
X
Xyahp2ps is TOTALLY unrelated to GNU or the Free Software Foundation,
Xit is only released under the same conditions.
X
X    For bug reports, wishes, etc. send e-mail to
X
X    ...!mcvax!unido!tub!actisb!federico  (from Europe)
X    ...!uunet!pyramid!actisb!federico    (from anywhere else)
X
X    For Physical mail:
X
X    Federico Heinz
X    Beusselstr. 21
X    1000 Berlin 21
X
X    Tel. (+49 30) 396 77 92
X
X*/
X/***************************************************************************
X
X   Edge drawing stuff.
X
X***************************************************************************/
X
X
X#include <ctype.h>
X#include "defs.h"
X#include "dispatch.h"
X#include "io.h"
X#include "circle.h"
X#include "penctrl.h"
X
X
X
X
X/**************************************************************************
X
X    Rectangle functions: absolute & relative.
X
X**************************************************************************/
X
X/*
X
X  Draw a rectangle with one corner at current position and the opposite
X  at the specified absolute CoordinatePair.
X
X*/
X
X
Xstatic void doRectangle(oppositeCorner)
X
XCoordinatePair oppositeCorner;
X
X{ CoordinatePair thisCorner;
X  Boolean penWasUp;
X
X  penWasUp = PenIsUp;
X  lowerPen();
X  thisCorner[X] = PenPosition[X]; thisCorner[Y] = PenPosition[Y];
X  doLine(thisCorner[X], oppositeCorner[Y]);
X  doLine(oppositeCorner[X], oppositeCorner[Y]);
X  doLine(oppositeCorner[X], thisCorner[Y]);
X  doLine(thisCorner[X], thisCorner[Y]);
X  if (penWasUp) liftPen();
X}
X
X
X
X
X/*
X
X  Draw a rectangle, interprete the coordinates as absolute.
X
X*/
X
XCommandImplementation rectangleAbsolute()
X
X{ CoordinatePair corner;
X
X  if (getCoordinatePair(corner))
X    doRectangle(corner);
X  endCommand();
X}
X
X
X
X
X/*
X
X  Draw a rectangle, interprete the coordinates relative to PenPosition
X
X*/
X
XCommandImplementation rectangleRelative()
X
X{ CoordinatePair corner;
X
X  if (getCoordinatePair(corner))
X  { corner[X] = PenPosition[X] + corner[X];
X    corner[Y] = PenPosition[Y] + corner[Y];
X    doRectangle(corner);
X  }
X  endCommand();
X}
X
X
X
X
X/***************************************************************************
X
X     Curve functions: wedge, circle and arc
X
X***************************************************************************/
X
X
X
X/*
X
X  Move the pen along an arc. The pen must already be at the start
X  of the arc. The chordAngle should divide the sweepAngle and (of course)
X  be != 0. If it does not divide the sweepAngle, then the last chord
X  will be shorter.
X
X*/
X
Xvoid doArc(center, radius, startAngle, sweepAngle, chordAngle)
X
XCoordinatePair center;
XNumber radius, startAngle, sweepAngle, chordAngle;
X
X{ Number currentAngle, endAngle;
X  CoordinatePair thisPoint;
X  int times;
X
X  times = sweepAngle / chordAngle;
X  if (times < 0)
X  { chordAngle = -chordAngle;
X    times = -times;
X  }
X  currentAngle = startAngle;
X  while (times--)
X  { currentAngle = currentAngle + chordAngle;
X    polarToCartesian(thisPoint, center, radius, currentAngle);
X    doLine(thisPoint[X], thisPoint[Y]);
X  }
X  if (sweepAngle % chordAngle)
X  { polarToCartesian(thisPoint, center, radius, startAngle + sweepAngle);
X    doLine(thisPoint[X], thisPoint[Y]);
X  }
X}
X
X
X
X/*
X
X  Draw a wedge with center at PenPosition.
X
X*/
X
XCommandImplementation wedge()
X
X{ CoordinatePair wedgeCenter, beginOfArc;
X  Number radius, startAngle, sweepAngle, chordAngle;
X  Boolean penWasUp;
X
X  if (getNumber(&radius) &&
X      getInteger(&startAngle) &&
X      getInteger(&sweepAngle))
X  { penWasUp = PenIsUp;
X    fixUpStartAndSweep(&startAngle, &sweepAngle);
X    getChordAngle(&chordAngle, sweepAngle, MinimumChordForWedge);
X    if (chordAngle > MaximumChordAngle)
X      warning("Chord angle out of range.");
X    else
X    { wedgeCenter[X] = PenPosition[X];
X      wedgeCenter[Y] = PenPosition[Y];
X      polarToCartesian(beginOfArc, wedgeCenter, radius, startAngle);
X      lowerPen();
X      doLine(beginOfArc[X],beginOfArc[Y]);
X      doArc(wedgeCenter, radius, startAngle, sweepAngle, chordAngle);
X      doLine(wedgeCenter[X], wedgeCenter[Y]);
X    }
X    if (penWasUp) liftPen();
X    endCommand();
X  }
X}
X
X
X
XCommandImplementation circle()
X
X{ CoordinatePair center, beginOfArc;
X  Number radius, chordAngle;
X  Boolean penWasUp;
X
X  if (getNumber(&radius))
X  { getChordAngle(&chordAngle, FullCircle, Zero);
X    center[X] = PenPosition[X];
X    center[Y] = PenPosition[Y];
X    penWasUp = PenIsUp;
X    liftPen();
X    if (chordAngle)
X    { polarToCartesian(beginOfArc, center, radius, Zero);
X      doLine(beginOfArc[X],beginOfArc[Y]);
X      lowerPen();
X      doArc(center, radius, Zero, FullCircle, chordAngle);
X      liftPen();
X    }
X    else /* smoothest circle */
X    { doHRArc(center, radius, Zero, FullCircle);
X      stroke();
X    }
X    doLine(center[X], center[Y]);
X    if (!penWasUp) lowerPen();
X  }
X  endCommand();
X}
X
X
X
X/*
X
X  Draw an arc using Absolute coordinates.
X
X*/
X
Xstatic void doAbsoluteArc(center, sweepAngle, chordAngle)
X
XCoordinatePair center;
XNumber chordAngle, sweepAngle;
X
X{ Number radius, startAngle;
X  CoordinatePair delta;
X
X  delta[X] = PenPosition[X] - center[X];
X  delta[Y] = PenPosition[Y] - center[Y];
X  cartesianToPolar(&radius, &startAngle, delta);
X  fixUpStartAndSweep(&startAngle, &sweepAngle);
X  if (chordAngle)
X    doArc(center, radius, startAngle, sweepAngle, chordAngle);
X  else /* smoothest circle */
X  { if (!PenIsUp)
X      doHRArc(center, radius, startAngle, sweepAngle);
X    polarToCartesian(PenPosition, center, radius, startAngle + sweepAngle);
X  }
X}
X
X
X
X/*
X
X  Arc Absolute command
X
X*/
X
XCommandImplementation arcAbsolute()
X
X{ CoordinatePair center;
X  Number sweepAngle, chordAngle;
X  
X  if (getCoordinatePair(center) &&
X      getInteger(&sweepAngle))
X  { getChordAngle(&chordAngle, sweepAngle, Zero);
X    doAbsoluteArc(center, sweepAngle, chordAngle);
X  }
X  endCommand();
X}
X
X
X
X/*
X
X  Arc Relative command
X
X*/
X
XCommandImplementation arcRelative()
X
X{ CoordinatePair center;
X  Number sweepAngle, chordAngle;
X  
X  if (getCoordinatePair(center) &&
X      getInteger(&sweepAngle))
X  { getChordAngle(&chordAngle, sweepAngle, Zero);
X    center[X] = PenPosition[X] + center[X];
X    center[Y] = PenPosition[Y] + center[Y];
X    doAbsoluteArc(center, sweepAngle, chordAngle);
X  }
X  endCommand();
X}
END_OF_FILE
if test 7129 -ne `wc -c <'edge.c'`; then
    echo shar: \"'edge.c'\" unpacked with wrong size!
fi
# end of 'edge.c'
fi
echo shar: End of archive 4 \(of 6\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0



More information about the Comp.sources.misc mailing list