Previous: clppl3 Up: ../plot79_c.html Next: clpsh3


CLPSH2

       SUBROUTINE  CLPSH2 (NEDGE, NORMAL, PIPE, XOLD, INCX, YOLD, INCY,
      X     NOLD, XNEW, YNEW, NNEW, MAXNEW)
 C$    (2-D Sutherland-Hodgman Polygon Clip to General Polygon)
 C$    Clip a 2-D polygon to the visible part of a general polygon
 C$    defined by  normal vectors  from each  of its  edges.   The
 C$    output of the clip is a new polygon.  The arguments are:
 C$
 C$    NEDGE..........Number  of clipping edges.  The  dimensional
 C$                   dependencies   are   NORMAL(3,NEDGE),    and
 C$                   PIPE(9,NEDGE).
 C$    NORMAL(*,*)....REAL  array  of  normals  (A,B,C)   defining
 C$                   equations of clipping edges Ax + By + C = 0.
 C$                   The normals point to the visible side of the
 C$                   edges.  NORMAL(*,K) is  the normal for  edge
 C$                   k.
 C$    PIPE(*,*)......REAL working  array  with 9*NEDGE entries.
 C$    XOLD(*)........REAL  array  of  x  coordinates  of  polygon
 C$                   vertices.
 C$    INCX...........Increment between successive coordinates  in
 C$                   XOLD(*) (normally 1).
 C$    YOLD(*)........REAL  array  of  y  coordinates  of  polygon
 C$                   vertices.
 C$    INCY...........Increment between successive coordinates  in
 C$                   YOLD(*) (normally 1).
 C$    NOLD...........Number of polygon vertices.   Vertex NOLD is
 C$                   implicitly connected  to vertex  1 to  close
 C$                   the polygon.
 C$
 C$    The output arguments are:
 C$
 C$    XNEW(*)........x coordinates of clipped polygon vertices.
 C$    YNEW(*)........y coordinates of clipped polygon vertices.
 C$    NNEW...........Number of clipped polygon vertices.   Vertex
 C$                   NNEW is implicitly connected to vertex 1  to
 C$                   close the  polygon.   NNEW will  usually  be
 C$                   less than NOLD,  but it may  be as large  as
 C$                   (3*NOLD+1)/2.    This   case   arises   when
 C$                   adjacent vertices lie  on opposite sides  of
 C$                   the clipping edge,  with NOLD/2 visible  and
 C$                   (NOLD+1)/2  hidden;   each   hidden   vertex
 C$                   contributes two new vertices on the clipping
 C$                   edge, giving a total of NOLD+1 new vertices,
 C$                   which  added  to  the  NOLD/2  old  ones  is
 C$                   (3*NOLD+1)/2.
 C$    MAXNEW.........Maximum  number of vertex  entries available
 C$                   in  XNEW(*)  and   YNEW(*).   NNEW  is   not
 C$                   permitted  to   exceed   this   value,   and
 C$                   additional  vertices  simply  overwrite  the
 C$                   last one.
 C$
 C$    If an  increment INCX  or INCY  is negative,  the  starting
 C$    vertex is taken as (1-NOLD)*INC +  1 instead of 1, so  that
 C$    the array is stepped through in reverse order.
 C$
 C$    The algorithm  is based  on the  reentrant polygon  clipper
 C$    originally proposed by I.E.  Sutherland and G.W.   Hodgman,
 C$    "Reentrant Polygon Clipping", Comm.  ACM 17, 32-42  (1974).
 C$
 C$    The effect of this routine can be equivalently be  obtained
 C$    by calling the single edge clipper, CLPPL2, repeatedly  for
 C$    each  successive   clipping  edge.    This  would   require
 C$    intermediate storage for at least  2 extra polygons if  the
 C$    input polygon is  to be  preserved.  The  advantage of  the
 C$    Sutherland-Hodgman algorithm  is that  as  soon as  a  line
 C$    segment is output from the clipping against one edge, it is
 C$    immediately passed on for  clipping against the next  edge.
 C$    Intermediate storage is therefore limited to three vertices
 C$    (the line segment  endpoints and the  saved initial  vertex
 C$    required to close the polygon) at each clipping stage, plus
 C$    two dot products, and two flags which are easily stored  in
 C$    a single word.   Thus for 2-D  points, 9 working  locations
 C$    are required  for  each  clipping edge.   The  dot  product
 C$    storage could be  eliminated at the  expense of  additional
 C$    calculation, but is hardly  excessive considering that  few
 C$    applications require more than 6 clipping edges.
 C$
 C$    The algorithm is essentially  a series of clippers  running
 C$    in parallel and  communicating with their  neighbors via  a
 C$    pipeline (in Unix terminology).  The  output of one is  the
 C$    input to the next, and if the next stage consumes its input
 C$    fast enough, its input buffer need never hold more than two
 C$    vertices.  This would be straightforward to implement in  a
 C$    language supporting coroutines, but since FORTRAN does  not
 C$    have  this  facility,  we   must  program  it   explicitly.
 C$    Obviously, if  the  clippers  were  actually  operating  in
 C$    independently  and  in  parallel  (apart  from   occasional
 C$    waiting on input),  the pipeline buffers  would have to  be
 C$    large enough to hold a complete polygon in the worst  case.
 C$    The trick  (and  the  complication)  is  to  superimpose  a
 C$    controller which prevents any  one process from  outputting
 C$    more than 2 vertices to its neighbor process.
 C$
 C$    The controller is  implemented as a  loop with  initialize,
 C$    process, and terminate steps, where each cycle through  the
 C$    loop  gives   control  to   just  one   clipping   process.
 C$    Initialization is just  the trivial copying  of input  from
 C$    the pipeline  into local  variables.  The  process step  is
 C$    also simple; it clips the current line segment against  the
 C$    current clipping edge and outputs 0 or 1 points to the next
 C$    stage, consuming exactly one  vertex from its input  buffer
 C$    to do  so.  The  difficult part  is the  termination  stage
 C$    which acts as  the pipeline controller  to select the  next
 C$    stage, and the comments in the procedure below describe the
 C$    steps which must be taken to do this.
 C$    (18-DEC-82)