
/*
  
  FACILITY:  NMMTL
  
  MODULE DESCRIPTION:
  
  Contains nmmtl_evaluate_circles function.
  
  AUTHORS:
  
  Kevin J. Buchs
  
  CREATION DATE:  Thu Jan  2 11:14:27 1992
  
  COPYRIGHT:   Copyright (C) 1992 by Mayo Foundation. All rights reserved.
  
  
  */


/*
 *******************************************************************
 **  INCLUDE FILES
 *******************************************************************
 */

#include "nmmtl.h"


/*
 *******************************************************************
 **  STRUCTURE AND TYPE DEFINITIONS
 *******************************************************************
 */
/*
 *******************************************************************
 **  MACRO DEFINITIONS
 *******************************************************************
 */
/*
 *******************************************************************
 **  PREPROCESSOR CONSTANTS
 *******************************************************************
 */
/*
 *******************************************************************
 **  GLOBALS
 *******************************************************************
 */
/*
 *******************************************************************
 **  FUNCTION DECLARATIONS
 *******************************************************************
 */
/*
 *******************************************************************
 **  FUNCTION DEFINITIONS
 *******************************************************************
 */


/*
  
  FUNCTION NAME:  nmmtl_evaluate_circles
  
  FUNCTIONAL DESCRIPTION:
  
  Takes a circle contour and processes it into a circle segment.
  
  
  FORMAL PARAMETERS:
  
  int cntr_seg
  number of segments to break a contour into
  
  -- No longer used --
  float half_minimum_dimension
  half of the smallest geometric dimension - used to determine if
  segments are broken small enough.
  -- --

  int conductor_counter
  keep count of the conductors
  
  CONTOURS_P contour:
  Conductor or groundwire contour.
  
  CIRCLE_SEGMENTS_P *segments:
  output list of circle segments generated by evaluating the 
  circle found.

  EXTENT_DATA_P extent_data:
  structure of extents of conductor region

  RETURN VALUE:
  
  SUCCESS or FAIL
  
  DESIGN:
  
  Traverse the circle in the order of bottom, right, top and left,
  with each edge originating where the previous one terminated.  As far
  as edge angles go, theta[0] and theta[1] are both 270 degress.
  
  The algorithm to determine the number of elements this should be
  broken into: take the ratio of the length of the side to the total
  perimeter of the circle and multiply by the number of segments to
  break each contour into.  Round up to the next higher integer.  Is
  this element size too large?  Check to see if it is greater than half
  of the smallest conductor edge as given by half_minimum_dimension.
  
  CALLING SEQUENCE:
  
  status = nmmtl_evaluate_circles(cntr_seg,
  conductor_counter,contours,&segments,&extent_data)
  
  
  */


int nmmtl_evaluate_circles(int cntr_seg,
#ifndef NO_HALF_MIN_CHECKING
			   float half_minimum_dimension,
#endif
			   int conductor_counter,
			   CONTOURS_P contour,
			   CIRCLE_SEGMENTS_P *segments,
         EXTENT_DATA_P extent_data)
{
  CIRCLE_SEGMENTS_P new_segment, list;
  
  new_segment = (CIRCLE_SEGMENTS_P)malloc(sizeof(CIRCLE_SEGMENTS));
  new_segment->centerx = (double)contour->x0;
  new_segment->centery = (double)contour->y0;
  new_segment->radius = (double)contour->x1;
  new_segment->conductor = conductor_counter;
  new_segment->epsilon[0] = 0.0;
  new_segment->epsilon[1] = 0.0;
  new_segment->startangle = 0.0;
  new_segment->endangle = 2 * PI;
  new_segment->radians = 2 * PI;
  
  /* straight calculation of number of divisions */
  /* enforce a minimum of 4 */
  new_segment->divisions = (int)(cntr_seg > 3 ? cntr_seg : 4);
  
#ifndef NO_HALF_MIN_CHECKING
  /* is the number of divisions too small ? */
  if((2 * PI * contour->x1)/new_segment->divisions > half_minimum_dimension)
  {
    new_segment->divisions = .99 + (2 * PI * contour->x1)/half_minimum_dimension;
  }
#endif
  
  /* terminate list */
  new_segment->next = NULL;
  
  /* hook up to end of the list */
  /* find the end of the segment list */
  if(*segments == NULL)
  {
    *segments = new_segment;
  }
  else
  {
    list = *segments;

    while(list->next != NULL)
    {
      list = list->next;
    }
    list->next = new_segment;
  }

  /* set up the new extent data */

  /* left conductor extent */
  if(extent_data->left_cond_extent > (new_segment->centerx - new_segment->radius))
    extent_data->left_cond_extent = new_segment->centerx - new_segment->radius;

  /* right conductor extent */
  if(extent_data->right_cond_extent < (new_segment->centerx + new_segment->radius))
    extent_data->right_cond_extent = new_segment->centerx + new_segment->radius;

  /* minimum conductor height above ground plane */
  if(extent_data->min_cond_height > (new_segment->centery - new_segment->radius))
    extent_data->min_cond_height = new_segment->centery - new_segment->radius;

  return(SUCCESS);
}




