Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

more vertex points than necessary for curves #1500

Open
kylemcdonald opened this Issue · 1 comment

2 participants

@kylemcdonald

if you generate a curve like this:

vector<ofVec2f> control;
...
ofPath path;
path.curveTo(control.front());
for(int i = 0; i < control.size(); i++) {
  path.curveTo(control[i]);
}
path.curveTo(control.back());
ofPolyline polyline = path.getOutline()[0];
cout << polyline.size() << endl;

the number of points in the polyline are more than necessary. it looks like at each control point, vertices are doubled up -- except for the beginning, where there is only one vertex.

i discovered this while trying to smoothly interpolate along a polyline, and found that the vertices weren't evenly spaced.

@c-mendoza

I ran into this issue as well when trying out a "thick line" geometry shader. As far as I know this is still happening in the latest builds. Something else to note is that this isn't exactly a "doubling up," since the problem points are VERY close to one another but do not have the exact same coordinates (in my tests they differ by something like 0.0001).

A silly fix would be to modify ofPolyline::curveTo to test whether newly generated points are close to the previously generated point, using ofVec3f::match with a tolerance that would not matter when points are output to the screen (something like 0.01):

void ofPolyline::curveTo( const ofPoint & to, int curveResolution ){

    curveVertices.push_back(to);

    if (curveVertices.size() == 4){

        float x0 = curveVertices[0].x;
        float y0 = curveVertices[0].y;
        float z0 = curveVertices[0].z;
        float x1 = curveVertices[1].x;
        float y1 = curveVertices[1].y;
        float z1 = curveVertices[1].z;
        float x2 = curveVertices[2].x;
        float y2 = curveVertices[2].y;
        float z2 = curveVertices[2].z;
        float x3 = curveVertices[3].x;
        float y3 = curveVertices[3].y;
        float z3 = curveVertices[3].z;

        float t,t2,t3;
        float x,y,z;

        for (int i = 0; i < curveResolution; i++){

            t   =  (float)i / (float)(curveResolution-1);
            t2  = t * t;
            t3  = t2 * t;

            x = 0.5f * ( ( 2.0f * x1 ) +
                        ( -x0 + x2 ) * t +
                        ( 2.0f * x0 - 5.0f * x1 + 4 * x2 - x3 ) * t2 +
                        ( -x0 + 3.0f * x1 - 3.0f * x2 + x3 ) * t3 );

            y = 0.5f * ( ( 2.0f * y1 ) +
                        ( -y0 + y2 ) * t +
                        ( 2.0f * y0 - 5.0f * y1 + 4 * y2 - y3 ) * t2 +
                        ( -y0 + 3.0f * y1 - 3.0f * y2 + y3 ) * t3 );

            z = 0.5f * ( ( 2.0f * z1 ) +
                        ( -z0 + z2 ) * t +
                        ( 2.0f * z0 - 5.0f * z1 + 4 * z2 - z3 ) * t2 +
                        ( -z0 + 3.0f * z1 - 3.0f * z2 + z3 ) * t3 );

            //SILLY FIX HERE:

            //Sometimes this algorithm is generating points that are VERY close to one another
            //This check throws out those uneeded points.

            ofPoint thisPoint = ofPoint(x,y,z);

            if (points.size() > 1) {
                //Check the last point, see if it is close to this one:
                ofPoint *lastPoint = &points.back();
                if (!lastPoint->match(thisPoint, 0.01)) {
                    points.push_back(thisPoint);
                }
            } else {
                points.push_back(thisPoint);

            }
        }
        curveVertices.pop_front();
    }
    flagHasChanged();
}

This is obviously inefficient, but it does fix the problem for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.