Jagged lines in ofBezier

I’ve recreated an animated Processing work I did a while ago using OF and my iPod Touch. I find that the curved lines of ofBezier are considerably less smooth than those of Processing. ofEnableSmoothing doesn’t seem to make a difference (the documentation says it only works for ‘lines’). Is there a way to improve this?

thanks

rh

for use on iOS trying using the below code in the main.mm file

  
ofAppiPhoneWindow * window = new ofAppiPhoneWindow();  
window->enableAntiAliasing( 4 );  
ofSetupOpenGL(window, 1024,768, OF_FULLSCREEN);  
ofRunApp(new testApp);  

Thanks, Nick. I tried your code but don’t see any improvement, unfortunately. (btw, I had to change ‘window’ to ‘iOSWindow’)

Hey Ron - can you post the full code from your main.mm ?

The code nick posted should work.
Theo

This is my code, Theo:

  
#include "ofMain.h"  
#include "testApp.h"  
  
  
int main(){  
	ofAppiPhoneWindow * iOSWindow = new ofAppiPhoneWindow();  
    iOSWindow->enableRetina();  
    iOSWindow->enableAntiAliasing(4);  
    ofSetupOpenGL(iOSWindow, 1024, 768, OF_FULLSCREEN);  
    ofRunApp(new testApp);  
  
}  
  

ahh - I wonder if its retina + enableAntiAliasing - just curious but could you try it without retina enabled?

I tried without retina enabled, theo, but the results are the same. I don’t think it’s an aliasing issue - it’s just that the sharp curves are drawn by creating a series of straight segments. Processing doesn’t use OpenGL and must have a different algorithm for drawing curves. Still, if there is some way to get smoother curves, I’d like to know what it is.

oh - try ofSetCurveResolution

Unfortunately ofSetCurveResolution does not work in this case - I’ve found that this has been covered before:

http://forum.openframeworks.cc/t/ofsetcurveresolution-±ofscale…-is-working-ok/9596/0

The method recommended there, using ofPath, would be fine, but I need alpha blending, and I can’t see how to do that with ofPath.

you can do alpha blending with ofPath like this:

myPath.setColor( ofColor200, 0, 255, 100) );

the 100 is the alpha.

however ofBezier is using an ofShape internally - so it should work - could you post full sample code to reproduce the issue and we can then find the error and patch it.

thanks!
Theo

the problem in that thread you link, (i didn’t noticed when answering it at that time) is that he is scaling, probably drawing a small curve then scaling it which makes the curve have little resolution.

but yes if you post some code and a screenshot of what you get it’ll help telling you what’s the problem or fixing any possible bug

@RonH I had some nice results with ->http://artgrammer.blogspot.de/2011-06-01-archive.html , but you have to wrap it for of yourself.

greetings ascorbin

OK, I’ve got some code and screenshots now. Using ofBezier:

  
void testApp::draw(){  
      
   //create the black frame and the two black vertical lines  
    ofDisableAlphaBlending();  
    ofRect(320, 0, 4, 320);  
    ofRect(160, 0, 4, 320);  
    ofRect(0, 0, 480, 60);  
    ofRect(0, 260, 480, 60);  
      
   //make filled lines semi-transparent  
    ofEnableAlphaBlending();  
    ofSetColor(0, 0, 0, 70);  
     
    ofBezier(50, 300, 50, 0, 420, 0, 420, 300);  
    ofBezier(100, 300, 50, 0, 420, 0, 470, 300);  

And using ofPath:

  
void testApp::draw(){  
      
   //create the black frame and the two black vertical lines  
    ofDisableAlphaBlending();  
    ofSetColor(0, 0, 0, 100);  
    ofRect(640, 0, 8, 640);  
    ofRect(320, 0, 8, 640);  
    ofRect(0, 0, 960, 120);  
    ofRect(0, 520, 960, 120);  
      
   //make filled lines semi-transparent  
    ofEnableAlphaBlending(); //in this example I assume this has no impact  
      
    ofPath curve;  
    curve.setColor( ofColor (0, 0, 0, 70) );  
    curve.setCurveResolution(60);  
    curve.moveTo(50, 300);  
    curve.bezierTo( 50, 0, 420, 0, 420, 300);  
    curve.draw();  
  
	curve.setColor( ofColor (0, 0, 0, 70) );  
    curve.setCurveResolution(60);  
    curve.moveTo(100, 300);  
    curve.bezierTo( 100, 0, 420, 0, 470, 300);  
    curve.draw();  

Obviously the ofPath example is much smoother (presumably because it has a separate control for resolution). On the other hand, the ofPath example is not blending - one curve is just laying on top of the other. Also, I’m actually drawing nine curves in an animation, so the ofPath version bogs down and gets pretty slow.

Hi thanks, yes there was a bug in one of the versions of ofBezier, it’s fixed now, here are the changes:

https://github.com/arturoc/openFrameworks/commit/19b5a6015375669b8f26bbed1792affe13533f08

also the way you are using ofPath, you are actually drawing 3 paths, 1 the first time and then 2 the second time you call draw. ofPath stores all the paths you draw in it and draws them everytime you call draw. Also you don’t need to recreate the path everytime you draw, only when it changes, if you do it like that ofPath should actually be faster than using ofBezier or ofBezierVertex:

  
  
void testApp::setup(){  
	curve1.setMode(ofPath::POLYLINES);  
	curve1.setColor( ofColor (0, 0, 0, 70) );  
	curve1.setCurveResolution(60);  
	curve1.moveTo(50, 300);  
	curve1.bezierTo( 50, 0, 420, 0, 420, 300);  
	curve2.setMode(ofPath::POLYLINES);  
	curve2.setColor( ofColor (0, 0, 0, 70) );  
	curve2.setCurveResolution(60);  
	curve2.moveTo(100, 300);  
	curve2.bezierTo( 100, 0, 420, 0, 470, 300);  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
	//create the black frame and the two black vertical lines  
	ofDisableAlphaBlending();  
	ofSetColor(0, 0, 0, 100);  
	ofRect(640, 0, 8, 640);  
	ofRect(320, 0, 8, 640);  
	ofRect(0, 0, 960, 120);  
	ofRect(0, 520, 960, 120);  
  
	//make filled lines semi-transparent  
	ofEnableAlphaBlending();  
	curve1.draw();  
	curve2.draw();  
}  
  

where curve1 and curve2 are ofPaths declared in testApp.h. the call setMode(ofPath::POLYLINES) will also make it slightly faster by not using a vectorial representation but decomposing the paths in polylines as soon as you add them

whenever you want to change each curve call .clear() on them and add the new curves

Thanks, arturo. I still have a number of questions:

  1. You mention a bug in ofBezier, but the link you included is for bezierTo. Also, the corrected version that includes resolution as an argument doesn’t work in Xcode (i.e. providing 7 args instead of 6).

  2. POLYLINES may be faster, but setCurveResolution seems to have no impact in that case, and I’m back to having the series of lines rather than genuine curves.

  3. I don’t understand the part about drawing 3 paths. If it was drawing all the paths stored, wouldn’t an animated image end up being just a solid block of color? (btw my paths are changing every frame)

  4. Where would I put curve1.clear - immediately after curve1.draw?

  5. When I try to declare curve1 and curve2 in the header file, I get a linking error - is there a different format I should use there?

1/2. yes ofBezier internally uses an ofPath the problem is there, if you add those fixes in your OF folder it’ll fix ofBezier and POLYLINES mode. this will be fixed in 074 which is about to be released

3/4. if you don’t clear the paths you are accumulating new curves so you are drawing all of them everytime you call draw, that’s also why the alpha wasn’t working for you. If you want to change the paths every frame clear them and add the new curves in update then draw all of them in draw. if they for example change interactively using the mouse you should be clearing and recreating them in mouseMoved or mouseDragged

  
  
//--------------------------------------------------------------  
void testApp::setup(){  
	curve1.setMode(ofPath::POLYLINES);  
	curve1.setColor( ofColor (100, 0, 0, 70) );  
	curve1.setCurveResolution(60);  
	curve2.setMode(ofPath::POLYLINES);  
	curve2.setColor( ofColor (0, 0, 0, 70) );  
	curve2.setCurveResolution(60);  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
	curve1.clear();  
	curve1.moveTo(50, 300);  
	curve1.bezierTo( 50, 0, 420, 0, 420, 300);  
	curve2.clear();  
	curve2.moveTo(100, 300);  
	curve2.bezierTo( 100, 0, 420, 0, 470, 300);  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
	//create the black frame and the two black vertical lines  
	ofDisableAlphaBlending();  
	ofSetColor(0, 0, 0, 100);  
	ofRect(640, 0, 8, 640);  
	ofRect(320, 0, 8, 640);  
	ofRect(0, 0, 960, 120);  
	ofRect(0, 520, 960, 120);  
  
	//make filled lines semi-transparent  
	ofEnableAlphaBlending();  
	curve1.draw();  
	curve2.draw();  
}  
  

  1. inside testApp:
  
  
class testApp{  
...  
ofPath curve1, curve2;  
}  
  

Thanks, arturo. That’s all very helpful.

I made the changes to the ofPath.cpp file, yet Xcode still complains if I attempt to add that last extra argument to either ofBezier or bezierTo. Is there something I need to do to ge Xcode to update the files for the project?

you don’t need to add that parameter to ofBezier or bezierTo, if you are using ofBezier use:

ofSetCurveResolution(60)

if you are using ofPAth

curve1.setResolution(60)

got it - thanks