Пример #1
0
void erase(int i, Plist& L) { L.erase (L.begin()+i); }
Пример #2
0
//===========================================================================
void cCollisionSpheresNode::ConstructChildren(Plist &a_primList)
{
    // ensure that there are at least two primitives so that it makes sense
    // to split them into left and right subtrees
    Plist::iterator primIter;
    assert(a_primList.size() >= 2);

    // declare and initialize local variables for splitting primitives
    Plist leftList, rightList;
    double min[3] = {LARGE, LARGE, LARGE};
    double max[3] = {-LARGE, -LARGE, -LARGE};

    // find minimum and maximum values for each coordinate of primitves' centers
    for (primIter = a_primList.begin(); primIter != a_primList.end(); primIter++)
    {
        cCollisionSpheresGenericShape *cur = *primIter;
        const cVector3d &center = cur->getCenter();
        for (int i = 0; i < 3; i++)
        {
          if (center.get(i) < min[i])
              min[i] = center.get(i);
          if (center.get(i) > max[i])
              max[i] = center.get(i);
        }
    }

    // find the coordinate index with the largest range (max to min)
    int split = 0;
    if ((max[1] - min[1]) > (max[split] - min[split]))
        split = 1;
    if ((max[2] - min[2]) > (max[split] - min[split]))
        split = 2;

    // sort the primitives according to the coordinate with largest range
    cCollisionSpheresGenericShape::m_split = split;
    std::sort(a_primList.begin(), a_primList.end());

    // put first half in left subtree and second half in right subtree
    unsigned int s;
    for (s=0; s<a_primList.size()/2; s++)
        leftList.insert(leftList.end(), a_primList[s]);
    for (s=a_primList.size()/2; s<a_primList.size(); s++)
        rightList.insert(rightList.end(), a_primList[s]);

    // if the left subtree is empty, transfer one from the right list
    if (leftList.size() == 0)
    {
        leftList.insert(leftList.begin(), *rightList.begin());
        rightList.erase(rightList.begin());
    }

    // create new internal nodes as roots for left and right subtree lists, or
    // a leaf node if the subtree list has only one primitive
    if (leftList.size() == 1)
        m_left = new(g_nextLeafNode++) cCollisionSpheresLeaf(*(leftList.begin()), this);
    else
        m_left = new(g_nextInternalNode++) cCollisionSpheresNode(leftList, this);
    if (rightList.size() == 1)
        m_right = new(g_nextLeafNode++) cCollisionSpheresLeaf(*(rightList.begin()), this);
    else
        m_right = new(g_nextInternalNode++) cCollisionSpheresNode(rightList, this);

    // get centers and radii of left and right children
    const cVector3d &lc = m_left->m_center;
    const cVector3d &rc = m_right->m_center;
    double lr = m_left->getRadius();
    double rr = m_right->getRadius();

    // compute new radius as one-half the sum of the distance between the two
    // childrens' centers and the two childrens' radii
    double dist = lc.distance(rc);
    m_radius = (dist + lr + rr) / 2.0;

    // compute new center along line between childrens' centers
    if (dist != 0)
    {
        double lambda = (m_radius - lr) / dist;
        m_center.x = lc.x + lambda*(rc.x - lc.x);
        m_center.y = lc.y + lambda*(rc.y - lc.y);
        m_center.z = lc.z + lambda*(rc.z - lc.z);
    }

    // if the left and right children have the same center, use this as the
    // new center
    else
    {
        m_center = lc;
    }

    // if one sphere is entirely contained within the other, set this sphere's
    // new center and radius equal to those of the larger one
    if (lr > dist + rr)
    {
        m_center = lc;
        m_radius = lr;
    }
    if (rr > dist + lr)
    {
        m_center = rc;
        m_radius = rr;
    }

	m_radius*=1.001;
}