示例#1
0
void OrganismCellWorld::floodFillOrganism(unsigned int startCell, bool find)
{
    static unsigned int floodId = 0;
    ++floodId;

    std::vector<unsigned int> open;
    std::vector<unsigned int> closed;
    open.push_back(startCell);

    unsigned int foundOrganism = 0;

    while (!open.empty())
    {
        unsigned int index = open.back();
        open.pop_back();
        closed.push_back(index);

        auto& cell = cells[index];
        cell.lastFlood = floodId;

        if (!cell.alive) continue;

        if (find)
        {
            // Found an organism
            if (cell.organism != 0)
            {
                // Hadn't found one yet, so store it
                if (foundOrganism == 0)
                {
                    foundOrganism = cell.organism;
                }
                // Two organisms touching; pick the lower index
                else if (cell.organism < foundOrganism)
                {
                    foundOrganism = cell.organism;
                }
            }
        }

        for (auto neighbor : getNeighborIndices(index))
        {
            if (cells[neighbor].lastFlood == floodId) continue;
            open.push_back(neighbor);
        }
    }

    // New organism if nothing else was touching (or not trying to find an organism)
    if (foundOrganism == 0)
    {
        foundOrganism = nextOrgIndex;
        ++nextOrgIndex;
    }

    // Set the organism index of everything touching
    for (auto& index : closed)
    {
        cells[index].organism = foundOrganism;
    }
}
示例#2
0
Real
BilinearInterpolation::sample(Real xcoord, Real ycoord)
{
  // first find 4 neighboring points
  int lx = 0; // index of x coordinate of adjacent grid point to left of P
  int ux = 0; // index of x coordinate of adjacent grid point to right of P
  getNeighborIndices(_xAxis, xcoord, lx, ux);

  int ly = 0; // index of y coordinate of adjacent grid point below P
  int uy = 0; // index of y coordinate of adjacent grid point above P
  getNeighborIndices(_yAxis, ycoord, ly, uy);

  Real fQ11 = _zSurface(ly, lx);
  Real fQ21 = _zSurface(ly, ux);
  Real fQ12 = _zSurface(uy, lx);
  Real fQ22 = _zSurface(uy, ux);

  // if point exactly found on a node do not interpolate
  if ((lx == ux) && (ly == uy))
    return fQ11;

  Real x = xcoord;
  Real y = ycoord;
  Real x1 = _xAxis[lx];
  Real x2 = _xAxis[ux];
  Real y1 = _yAxis[ly];
  Real y2 = _yAxis[uy];

  // if xcoord lies exactly on an xAxis node do linear interpolation
  if (lx == ux)
    return fQ11 + (fQ12 - fQ11) * (y - y1) / (y2 - y1);

  // if ycoord lies exactly on an yAxis node do linear interpolation

  if (ly == uy)
    return fQ11 + (fQ21 - fQ11) * (x - x1) / (x2 - x1);

  Real fxy = fQ11 * (x2 - x) * (y2 - y);
  fxy += fQ21 * (x - x1) * (y2 - y);
  fxy += fQ12 * (x2 - x) * (y - y1);
  fxy += fQ22 * (x - x1) * (y - y1);
  fxy /= ((x2 - x1) * (y2 - y1));

  return fxy;
}
示例#3
0
void ContourTree::compute_ST(){

	uint N = 1;
	for (uint i=0; i<dimension; ++i)
		N = N*size[i];

	std::vector<uint> 			neighborIndices;
	std::vector<uint>::iterator neighborIndices_it;

	std::set<uint> 				mergingRegions;
	std::set<uint>::iterator 	mergingRegions_it;

	Leader* tmpLeader;
	Vertex* tmpVertex;
	Leader* deleteLeader;

	std::vector<Vertex*>::iterator vertex_it;

	for (uint i = 0; i < N; ++i) {

		getNeighborIndices(&neighborIndices, indices[i], size, dimension);

		for (neighborIndices_it = neighborIndices.begin(); neighborIndices_it != neighborIndices.end(); ++neighborIndices_it)
			if (elements[*neighborIndices_it]->ST_root)
				mergingRegions.insert(elements[*neighborIndices_it]->ST_root->leader->index);

		if (mergingRegions.size() == 1) {
			elements[*mergingRegions.begin()]->ST_parent = indices[i];
			elements[indices[i]]->ST_root = elements[*mergingRegions.begin()]->ST_root;
			elements[*mergingRegions.begin()]->ST_root->leader->index = indices[i];
		} else if ( mergingRegions.empty() ) {
			tmpLeader						= new Leader;
			tmpVertex						= new Vertex;
			tmpLeader->index 				= indices[i];
			tmpVertex->leader 				= tmpLeader;
			tmpVertex->index 				= indices[i];
			tmpVertex->childrenCount 		= 0;
			tmpLeader->vertices.push_back(tmpVertex);
			elements[indices[i]]->ST_root 	= tmpVertex;
			ST.push_back(tmpVertex);
		}else {
			tmpLeader						= new Leader;
			tmpVertex						= new Vertex;
			tmpLeader->index 				= indices[i];
			tmpVertex->leader 				= tmpLeader;
			tmpVertex->index 				= indices[i];
			tmpVertex->childrenCount 		= 0;
			tmpLeader->vertices.push_back(tmpVertex);
			elements[indices[i]]->ST_root 	= tmpVertex;
			tmpVertex->toVertex 			= NULL;
			ST.push_back(tmpVertex);
			for (mergingRegions_it = mergingRegions.begin(); mergingRegions_it != mergingRegions.end(); ++mergingRegions_it) {
				elements[*mergingRegions_it]->ST_parent = indices[i];
				tmpVertex->childrenVertices.push_back(elements[*mergingRegions_it]->ST_root);
				(tmpVertex->childrenCount)++;
				deleteLeader				= elements[*mergingRegions_it]->ST_root->leader;
				tmpLeader->vertices.insert(tmpLeader->vertices.end(),deleteLeader->vertices.begin(),deleteLeader->vertices.end() );
				for (vertex_it = deleteLeader->vertices.begin(); vertex_it != deleteLeader->vertices.end(); ++vertex_it)
					(*vertex_it)->leader 	= tmpLeader;
				delete deleteLeader;
				elements[*mergingRegions_it]->ST_root->toVertex = elements[indices[i]]->ST_root;
			}
		}

		mergingRegions.clear();
		neighborIndices.clear();

	}

}
示例#4
0
void OrganismCellWorld::redistributeCells()
{
    size_t indexPosCur = indexFromPos(static_cast<int>(posCursor.x), static_cast<int>(posCursor.y));
    if (cells[indexPosCur].organism != 0)
    {
        playerOrganism = cells[indexPosCur].organism;
    }

    for (auto& cell : cells)
    {
        cell.attached = cell.organism == playerOrganism;
    }

    std::map<unsigned, std::vector<size_t>> born;
    std::map<unsigned, std::vector<size_t>> died;
    std::vector<size_t> changed;
    std::set<unsigned> organisms;

    for (size_t i = 0; i < cells.size(); ++i)
    {
        auto& cell = cells[i];

        if (cell.nextAlive && !cell.alive)
        {
            born[cell.organism].push_back(i);
            organisms.insert(cell.organism);
        }
        else if (!cell.nextAlive && cell.alive)
        {
            died[cell.organism].push_back(i);
            organisms.insert(cell.organism);
        }
    }

    // DEBUG ADD/REMOVE FOOD
    if (engine->inputManager.getIntValue(4) > 0) toAdd += 100;
    else if (engine->inputManager.getIntValue(4) < 0) toRemove += 100;

    // Accumulate number of dead cells
    toRemove += decay;

    for (auto organism : organisms)
    {
        auto& orgBorn = born[organism];
        auto& orgDied = died[organism];

        // Shuffle the list of cells that died/were born
        std::random_shuffle(orgBorn.begin(), orgBorn.end());
        std::random_shuffle(orgDied.begin(), orgDied.end());

        auto bornIter = orgBorn.begin();
        auto diedIter = orgDied.begin();

        if (organism == playerOrganism)
        {
            // If we've accumulated enough decay, kill off some cells permanently
            while (toRemove > 1.f && diedIter != orgDied.end())
            {
                cells[*diedIter].alive = false;
                changed.push_back(*diedIter);
                ++diedIter;

                toRemove -= 1.f;
            }

            // If we have cells to add then do so
            while (toAdd > 0 && bornIter != orgBorn.end())
            {
                cells[*bornIter].alive = true;
                changed.push_back(*bornIter);
                ++bornIter;

                toAdd -= 1;
            }
        }
        else
        {
            // Kill cells randomly
            unsigned killRandom = rand() % 8;
            for (unsigned i = 0; i < killRandom && diedIter != orgDied.end(); ++i)
            {
                cells[*diedIter].alive = false;
                changed.push_back(*diedIter);
                ++diedIter;
            }
        }

        // Redistribute dead cells into born cells
        while (bornIter != orgBorn.end() && diedIter != orgDied.end())
        {
            cells[*bornIter].alive = true;
            cells[*diedIter].alive = false;

            changed.push_back(*bornIter);
            changed.push_back(*diedIter);

            ++bornIter;
            ++diedIter;
        }
    }

    std::random_shuffle(changed.begin(), changed.end());

    for (auto& index : changed)
    {
        cells[index].organism = 0;

        for (auto neighbor : getNeighborIndices(index))
        {
            cells[neighbor].organism = 0;
        }
    }

    for (auto it = changed.begin(); it != changed.end(); ++it)
    {
        auto index = *it;
        auto& cell = cells[index];

        // Newly-created; find nearby organisms
        if (cell.alive)
        {
            if (cell.organism == 0) floodFillOrganism(index, true);
        }
        // Newly-destroyed; neighbors may have split into new organisms
        else
        {
            for (auto neighborIndex : getNeighborIndices(index))
            {
                auto& neighbor = cells[neighborIndex];

                if (neighbor.alive && neighbor.organism == 0) floodFillOrganism(neighborIndex, false);
            }
        }
    }

    aliveCount = 0;
    for (auto& cell : cells)
    {
        if (cell.alive && cell.attached) ++aliveCount;
    }
}