   C++ - Need some help drawing bezier curves.
  Hi guys,I've been writing a win32 app in C++ to get the hang of it and to understand and learn how the API works. It's going great in that sense, but I'm having a bit of trouble drawing everything out nicely. In my program, the user can create points, drag these accross the screen, and add these points to a group of points that define a bezier curve. All this works pretty well so far. There are still bugs, but I can take care of those later. My first problem is the flicker I get each time I move a point. I redraw the window everytime I move one of these points, because that would change the curve aswell. Is this something that could be solved with double buffering? If so, can anyone give me a hint or a link to a good tutorial? Second, I'm using linear interpolation to draw the bezier curves (de Casteljau algorithm). Basically, I'm having trouble defining the accuracy of the bezier curves. A low accuracy leads to an angled looking curve. A too small step size is overkill. It doesn't slow the program down to a degree that I'd notice, but it doesn't look very nice either. I need a way to figure out what the best step size is, depending on where the points are.Here is an image of what it looks like with a larger step size:http://img412.imageshack.us/img412/9181/bezierfirstrun.jpgMy idea is to take the absolute value of the differnce between successive point coordinates, add all of this together, and then take the average. Does anyone have an idea of what could be a good way to solve this?Cheers,Brick   
  Yes double buffering solves flickering. There's even a flag you can use on creation of the window that'll do it for you called WS_EX_COMPOSITED (XP and later).As for accuracy vs speed, you can have one or the other when you need it most. When dragging you could use a larger step size, and each time the mouse stops you could use a smaller step size.Note that GDI operations are fast under XP or earlier but are relatively slow under Vista where they are effectively emmulated, and Windows 7 is probably similar. Which OS are you using?   ;  I'm writing it under windows Vista, but also testing on XP...I've already noticed some differences, but it was nothing I couldn't solve. Mainly issues when WM_PAINT is sent. Anyways, I'll try what you suggested. I really like your idea on using the larger step size when dragging the points around. I think I'll use a fixed step size that looks somewhat accurate in that case. Thanks for the info. Just out of curiosity, how would I implement double buffering without the WS_EX_COMPOSITED bit?Cheers,Brick   ;  Add PFD_DOUBLEBUFFER to the pixel format descriptor?And call SwapBuffers(hDC) after drawing the stuff?I may be wrong.   ;Quote:Original post by BrickInTheWallIt doesn't slow the program down to a degree that I'd notice, but it doesn't look very nice either.If it doesn't look very nice, then the step size isn't small enough. And if it doesn't slow the program down to a degree that you'd notice, obviously you can make the step size smaller. I understand your desire to make the program efficient, but are you sure your motivation is based on practicality rather than coolness-factor?Anyways, if you want to know where to subdivide the curve, just recursively subdivide until the ratio of the subdivided and non-subdivided lengths passes below a certain threshold. So, like,ALPHA = 1.01def sample_bezier_aux(curve_func, a, b):  """  Returns internal curve points only.  """  c = (a+b)/2.0  xa = curve_func(a)  xc = curve_func(c)  xb = curve_func(b)  if (dist(xa, xc) + dist(xc, xb)) / dist(xa, xb) > ALPHA:    return sample_bezier(a, c) + [xc] + sample_bezier(c, b)  else:    return []def sample_bezier(curve_func):  return curve_func(0) + sample_bezier_aux(curve_func, 0, 1) + curve_func(1)EDIT: Oh, and quit using de Casteljau. It's a fun little construction, but it's less efficient than the direct matrix-based calculation.[Edited by - Sneftel on May 18, 2010 9:03:31 AM];  I've never heard of the a matrix based calculation regarding bezier curves (is this only for up to cubic curves? If yes, I can't really do much with it). I'll have to check that out. Also, EW_EX_COMPOSITED did nothing for me, still getting flickers.   ;Quote:Original post by BrickInTheWall(is this only for up to cubic curves? If yes, I can't really do much with it).No, it will work with any order curve, though higher-order curves are so limiting and seldom-used compared to bezier splines that I doubt you'll find much information about them.   ;  Ok thanks, I'll do some research. Right now de Casteljau's algorithm is working fine, also for curves of order 20 for example, but it's always good to look at alternative methods.   ;Quote:Original post by BrickInTheWallcurves of order 20[crying]Seriously, look into bezier splines. Faking splines by shoving all your points into a single n-th order curve leads to really badly behaved curves, and they're way more expensive to evaluate and way more difficult to modify locally.   