I need to draw curves and use them as path for moving elements all along them.
This is why I chose ofPolyline (I don’t need all ofPath features, I think)
At the beginning, I generate n ofPoints and I put them in my ofPolyline using curveTo() (which is probably NOT the right way).
I draw that.
nice (except for the first and last points because I put them using addVertex() and from 0 to 1 and from n-2 to n-1 there are lines and not curves)
Then I want to move some points from a position on the screen to another.
I do that and as soon as I did that, the draw mode from and to the point I changed are lines and no more curves.
ofPolyline is a collection of points and even if you add “curves” to it, those are just turned into points before they are added to the polyline so in the end, it will always be a set of points.
To keep things smooth, sometimes I use the resampling and smoothing of the polyline object to “curve” it, ie:
but this just doing smoothing, which curves the line…
another option is to look at ofPath, which is more of a higher level representation of a shape, where you can have higher level commands like a curve and they are stored internally as curves. You can then get the outline of the shape as a set of polylines (points) when you want to draw it, etc.
i am not an expert and i don’t know if this is the right way to achieve it, but this is how i update shapes while dragging points with the mouse using bezier command points :
void Shape::updatePath() {
ofPath newPath;
newPath = path; // save shape properties before editing path
newPath.clear(); // clears path but keeps properties like color, stroke...
// build new path according to actual path's control points properties
for (int i = 0; i < controls.size(); i++) {
switch (controls[i].type) {
case ofPath::Command::moveTo:
newPath.moveTo(controls[i].to);
break;
case ofPath::Command::lineTo:
newPath.lineTo(controls[i].to);
break;
case ofPath::Command::curveTo:
newPath.curveTo(controls[i].to);
break;
case ofPath::Command::bezierTo:
newPath.bezierTo(controls[i].cp1, controls[i].cp2, controls[i].to);
break;
case ofPath::Command::quadBezierTo:
newPath.quadBezierTo(controls[i].cp1, controls[i].cp2, controls[i].to);
break;
case ofPath::Command::arc:
newPath.arc(controls[i].to, controls[i].radiusX, controls[i].radiusY, controls[i].angleBegin, controls[i].angleEnd, controls[i].arc);
break;
case ofPath::Command::arcNegative:
newPath.arc(controls[i].to, controls[i].radiusX, controls[i].radiusY, controls[i].angleBegin, controls[i].angleEnd, controls[i].arcNegative);
break;
case ofPath::Command::close:
newPath.close();
break;
default:
break;
}
path.clear();
path = newPath;
path.flagShapeChanged();
}
}
Hi @julienbayle,
as zach said there’s the ofPath option. you can call the getCommands() from it which will give you a vector of ofPath::commands which are actually the commands and parameters stored whenever you called moveTo(…) or bezierTo(…). you can access those and modify them. I’ve been using this method a lot lately. Whenever you modify the ofPath through the commands, its polylines will get recalculated that you can access through the getOutline() method, which returns a vector object,then use the getPointForPercent() method on these.
take a look at the following.
ofApp.h
#pragma once
#include "ofMain.h"
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void mouseDragged(int x, int y, int button);
ofPath path;
float pct;
};
It absolutely helps.
I don’t know the best practice in that case: using ofPolyline or ofPath.
Actually, in my case, I’d need to change all points of my path, sometimes (using the animated/smoothed way… the other thread where you answered me )
Now, another “issue” for me: when strokeweight is greater than even 2 or 3, joints are not cute. I saw some posts about that… checking now.
I see. in this case I think that ofPolyline is a good choice. Where are the new points comming from? are you adding these new points to the polyline through lineTo, bezierTo,…, or these points are sumply line vertices.
In case of the latter, Maybe a better solution is to use a ofMesh or ofVboMesh.
The stroke “issue” is because openGL. There are several methods to work it around. I made an addon some years ago that addressed this issue called ofxFatLines. It kinda works nicely but I it fails when you have sharp angles. It is based on the very basic idea of VASE renderer, which now a days seems to be much more mature than my addon. also, yo might want to try ofxShivaVG. it renders 2D stuff really nicely.
Hi @julienbayle
in this case, where you are just drawing lines, you can think of ofPath as a kind of buffer of commands to create polylines, which will actually create the points of the polyline only when needed. So you actually dont need to port the code for morphing, simply update the morphed polylines when its according ofPath changes.