示例#1
0
/*
  @method DistanceList
  @discussion Allocate storage for an n-unit unitList.
  @throws KII_bad_alloc
*/
DistanceList::DistanceList(const FLOAT xlocs[], const FLOAT ylocs[], 
			   const VectorMatrix& radii) 
  : unitList(NULL), numUnits(radii.Size()), numOverlap(0)
{
  // Since this is a symmetric array, there's no need to store
  // information for unit n (all that information is already in the
  // lists for units 1..n-1
  if ((unitList = new ListItem[numUnits-1]) == NULL)
    throw KII_bad_alloc("Failed allocating memory for DistanceList.");

  // Fill the lists. For unit i, we need only store information for
  // connections to units i+1..n, as earlier units already have the
  // information for their connections with i.
  FLOAT tempDist, tempDist2, tempDelta, deltaX, deltaY;
  for (int u1=0; u1<numUnits-1; u1++) {
    unitList[u1].radius = radii[u1];
    for (int u2=u1+1; u2<numUnits; u2++) {
      deltaX = xlocs[u1]-xlocs[u2];
      deltaY = ylocs[u1]-ylocs[u2];
      tempDist2 = deltaX*deltaX + deltaY*deltaY;
      tempDist = sqrt(tempDist2);
      tempDelta = tempDist - (radii[u1]+radii[u2]);
      if (tempDelta < 0.0) {
	unitList[u1].overlapping.push_back(SublistItem(u2, radii[u2], tempDist,
						       tempDist2, tempDelta));
	numOverlap++;
      } else {
	unitList[u1].nonOverlapping.push_back(SublistItem(u2, radii[u2],
							  tempDist, tempDist2, tempDelta));
      }
    }
  }
}
示例#2
0
/*
  @method Update
  @discussion Update the DistanceList information based on the given
  new radii.
  @param radii unit connectivity radii must have same number of
  elements as numUnits
  @throws KII_invalid_argument
*/
void DistanceList::Update(const VectorMatrix& radii)
{
  if (radii.Size() != numUnits)
    throw KII_invalid_argument("Wrong number of elements in radii for distance update.");

#ifdef DEBUG2
  cerr << "Updating DistanceList with radii " << radii << endl;
#endif
  FLOAT tempDelta;
  SublistItem tempItem;
  list<SublistItem>::iterator u2iter;
  // Iterate through all units
  for (int u1=0; u1<numUnits-1; u1++) {
#ifdef DEBUG2
    cerr << u1 << ", ";
#endif
    // Update unit connection radius
    unitList[u1].radius = radii[u1];
    // Iterate over all overlapping and non-overlapping other units
    // First, overlapping:
    u2iter = unitList[u1].overlapping.begin();
    while (u2iter != unitList[u1].overlapping.end()) {
      // Compute and update other unit's information
      u2iter->radius = radii[u2iter->otherUnit];
      tempDelta = u2iter->dist - (unitList[u1].radius+u2iter->radius);
      u2iter->Delta = tempDelta;
      // Move it if non-overlapping, if necessary (Delta>=0). If the
      // move occurs, the iterator will point to the next item. If
      // not, then the iterator must be advanced explicitly.
      if (tempDelta >= 0) {
	tempItem = *u2iter;
	u2iter = unitList[u1].overlapping.erase(u2iter);
	unitList[u1].nonOverlapping.push_back(tempItem);
	numOverlap--;
      } else
	u2iter++;
    }
    // Then, non-overlapping:
    u2iter = unitList[u1].nonOverlapping.begin();
    while (u2iter != unitList[u1].nonOverlapping.end()) {
      // Compute and update other unit's information
      u2iter->radius = radii[u2iter->otherUnit];
      tempDelta = u2iter->dist - (unitList[u1].radius+u2iter->radius);
      u2iter->Delta = tempDelta;
      // Move it if overlapping, if necessary (Delta<0). If the
      // move occurs, the iterator will point to the next item. If
      // not, then the iterator must be advanced explicitly.
      if (tempDelta < 0) {
	tempItem = *u2iter;
	u2iter = unitList[u1].nonOverlapping.erase(u2iter);
	unitList[u1].overlapping.push_back(tempItem);
	numOverlap++;
#ifdef DLDEBUG
	cerr << "\tDL::Update(): overlap of " << u1 << " and " << tempItem.otherUnit
	     << " with radii " << unitList[u1].radius << " and " << tempItem.radius
	     << ", respectively" << endl;
#endif
      } else
	u2iter++;
    }
  }  // end for (int u1-0; ...)
#ifdef DEBUG2
  cerr << "done." << endl;;
#endif
}