void DrawNode::drawCardinalSpline(PointArray *config, float tension, unsigned int segments, const Color4F &color) { Vec2* vertices = new (std::nothrow) Vec2[segments + 1]; if( ! vertices ) return; ssize_t p; float lt; float deltaT = 1.0f / config->count(); for( unsigned int i=0; i < segments+1;i++) { float dt = (float)i / segments; // border if( dt == 1 ) { p = config->count() - 1; lt = 1; } else { p = dt / deltaT; lt = (dt - deltaT * (float)p) / deltaT; } // Interpolate Vec2 pp0 = config->getControlPointAtIndex(p-1); Vec2 pp1 = config->getControlPointAtIndex(p+0); Vec2 pp2 = config->getControlPointAtIndex(p+1); Vec2 pp3 = config->getControlPointAtIndex(p+2); Vec2 newPos = ccCardinalSplineAt( pp0, pp1, pp2, pp3, tension, lt); vertices[i].x = newPos.x; vertices[i].y = newPos.y; } drawPoly(vertices, segments+1, false, color); CC_SAFE_DELETE_ARRAY(vertices); }
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()); }