void CCPointList::addPoints(CCPointList& plist) {
	while(m_count + plist.getCount() >= m_capacity) {
		m_capacity *= 2;
		m_buffer = (CCPoint*)realloc(m_buffer, m_capacity * sizeof(CCPoint));
	}

	memcpy(m_buffer + m_count, plist.getBuffer(), plist.getCount() * sizeof(CCPoint));
	m_count += plist.getCount();
}
void CCCatmullRomSprite::populatePoints(const CCPointList& controlPoints, CCPointList& points) {
    // clear
    points.clear();
    m_segmentPointIndices.clear();
    
    // populate points segment by segment
    int totalSeg = controlPoints.getCount() - 1;
    for(int curSeg = 0; curSeg < totalSeg; curSeg++) {
        // add start index of segment
        m_segmentPointIndices.push_back(points.getCount());
        
        // four control points
        CCPoint cp0 = controlPoints.getPointAt(curSeg - 1);
        CCPoint cp1 = controlPoints.getPointAt(curSeg);
        CCPoint cp2 = controlPoints.getPointAt(curSeg + 1);
        CCPoint cp3 = controlPoints.getPointAt(curSeg + 2);
        
        // segment length, desired points
        float curSegLen = ccpLength(ccpSub(cp2, cp1));
        int curSegPoints = (int)ceilf(curSegLen / m_patternLength) + 1;
        float step = 1.0f / (curSegPoints - 1);
        
        // populate points for this segments
        float lt = 0;
        while(lt < 1) {
            CCPoint pos = ccCardinalSplineAt(cp0, cp1, cp2, cp3, m_tension, lt);
            points.addPoint(pos);
            lt += step;
        }
    }
    
    // last point
    points.addPoint(controlPoints.getPointAt(controlPoints.getCount() - 1));
    
    // last placeholder
    m_segmentPointIndices.push_back(points.getCount());
}