function centroid = voronoi_polygon_centroid_2d ( node, neighbor_num, ...
  neighbor_index, node_num, p )

%% VORONOI_POLYGON_CENTROID_2D computes the centroid of a Voronoi polygon in 2D.
%
%  Discussion:
%
%    It is assumed that the Voronoi polygon is finite!  Every Voronoi
%    diagram includes some regions which are infinite, and for those,
%    this formula is not appropriate.
%
%    The routine is given the indices of the nodes that are neighbors of a 
%    given "center" node.  A node is a neighbor of the center node if the
%    Voronoi polygons of the two nodes share an edge.  The triangles of the 
%    Delaunay triangulation are formed from successive pairs of these neighbor 
%    nodes along with the center node.
%
%    The assumption that the polygon is a Voronoi polygon is
%    used to determine the location of the boundaries of the polygon,
%    which are the perpendicular bisectors of the lines connecting
%    the center point to each of its neighbors.
%
%    The finiteness assumption is employed in part in the
%    assumption that the polygon is bounded by the finite
%    line segments from point 1 to 2, 2 to 3, ...,
%    M-1 to M, and M to 1, where M is the number of neighbors.
%
%    It is assumed that this subroutine is being called by a
%    process which has computed the Voronoi diagram of a large
%    set of nodes, so the arrays X and Y are dimensioned by
%    NODE_NUM, which may be much greater than the number of neighbor
%    nodes.
%
%  Modified:
%
%    08 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Atsuyuki Okabe, Barry Boots, Kokichi Sugihara, Sung Nok Chiu,
%    Spatial Tesselations: Concepts and Applications of Voronoi Diagrams,
%    Second Edition,
%    Wiley, 2000, page 490.
%
%  Parameters:
%
%    Input, integer NODE, the index of the node whose Voronoi
%    polygon is to be analyzed.  1 <= NODE <= NODE_NUM.
%
%    Input, integer NEIGHBOR_NUM, the number of neighbor nodes of
%    the given node.
%
%    Input, integer NEIGHBOR_INDEX(NEIGHBOR_NUM), the indices
%    of the neighbor nodes.  These indices are used to access the
%    X and Y arrays.  The neighbor nodes should be listed in the
%    (counter-clockwise) order in which they occur as one circles 
%    the center node.
%
%    Input, integer NODE_NUM, the total number of nodes.
%
%    Input, real P(2,NODE_NUM), the nodes.
%
%    Output, real CENTROID(2), the coordinates of the centroid
%    of the Voronoi polygon of node NODE.
%
  ndim = 2;

  centroid(1:ndim,1) = 0.0;

  if ( node < 1 | node_num < node )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'VORONOI_POLYGON_CENTROID_2D - Fatal error!\n' );
    fprintf ( 1, '  Illegal value of input parameter NODE.\n' );
    error ( 'VORONOI_POLYGON_CENTROID_2D - Fatal error!' )
  end

  pc(1:ndim) = p(1:ndim,node)';

  i = neighbor_num;
  i = neighbor_index(i);

  pi(1:ndim) = p(1:ndim,i)';

  j = 1;
  j = neighbor_index(j);

  pj(1:ndim) = p(1:ndim,j)';

  a = ( pi(1) * pi(1) + pi(2) * pi(2) - pc(1) * pc(1) - pc(2) * pc(2) );
  b = ( pj(1) * pj(1) + pj(2) * pj(2) - pc(1) * pc(1) - pc(2) * pc(2) );
  c = 2.0 * ( ( pi(1) - pc(1) ) * ( pj(2) - pc(2) ) ...
            - ( pj(1) - pc(1) ) * ( pi(2) - pc(2) ) );
  uj(1) = ( a * ( pj(2) - pc(2) ) - b * ( pi(2) - pc(2) )  ) / c;
  uj(2) = ( a * ( pj(1) - pc(1) ) - b * ( pi(1) - pc(1) )  ) / c;

  for i = 1 : neighbor_num

    pi(1:ndim) = pj(1:ndim);
    ui(1:ndim) = uj(1:ndim);

    j = i_wrap ( i+1, 1, neighbor_num );
    pj(1:ndim) = p(1:ndim,j)';

    a = ( pi(1) * pi(1) + pi(2) * pi(2) - pc(1) * pc(1) - pc(2) * pc(2) );
    b = ( pj(1) * pj(1) + pj(2) * pj(2) - pc(1) * pc(1) - pc(2) * pc(2) );
    c = 2.0 * ( ( pi(1) - pc(1) ) * ( pj(2) - pc(2) ) ...
              - ( pj(1) - pc(1) ) * ( pi(2) - pc(2) ) );
    uj(1) = ( a * ( pj(2) - pc(2) ) - b * ( pi(2) - pc(2) )  ) / c;
    uj(2) = ( a * ( pj(1) - pc(1) ) - b * ( pi(1) - pc(1) )  ) / c;

    centroid(1) = centroid(1) + ( ui(2) - uj(2) ) ...
      * ( ( uj(1) + ui(1) )^2 - uj(1) * ui(1) );
    centroid(2) = centroid(2) + ( ui(1) - uj(1) ) ...
      * ( ( uj(2) + ui(2) )^2 - uj(2) * ui(2) );

  end

  area = voronoi_polygon_area_2d ( node, neighbor_num, neighbor_index, ...
    node_num, p );

  centroid(1:ndim) = centroid(1:ndim) / ( 6.0 * area );

  return
end
