2

Possible Duplicate:
iPhone smooth sketch drawing algorithm

I'm looking for an actual demonstrable example of code or an algorithm responsible for super smooth beautiful paint strokes like those found in the Penultimate app?

Heck, any code that demonstrates any smooth paint stroke based upon a user's finger stroke would be great. The elusive nugget I'm seeking is "smooth". Other answers on SO attempt to address smooth stroke drawing, however none target Penultimate as the elusive goal, and none of the solutions achieve anything as smooth and refined as Penultimate, which is what this question is after specifically, not just general smoothing algorithms.

Community
  • 1
  • 1
Todd Hopkinson
  • 6,803
  • 5
  • 32
  • 34
  • What you're looking for, in a nutshell, is taking a massive list of points and estimating them with bezier curves. Its not a direct link or example, but it may help your googling. – Yann Ramin Apr 12 '11 at 00:42
  • I was aware of other similar questions and relevant answers elsewhere on the stack, but in this particular question I specifically mention Penultimate in the hopes that someone familiar with that specific technique in getting that kind of result could provide some added insight. – Todd Hopkinson Apr 12 '11 at 02:21
  • That is a good link and pretty close to what I'm looking for, though I have not seen anything anywhere that comes close to demonstrating how to get the fluid smoothness that gives Penultimate it's characteristic feel. – Todd Hopkinson Apr 12 '11 at 02:30
  • If there was a simple algorithm for beauty, art would be a lot easier. – tc. Apr 12 '11 at 04:39
  • Penultimate appears to vary line thickness *slightly*, which might not be so easy to do well, but line smoothing itself is not that difficult (that said, I spent a day tweaking my algorithm to get something vaguely sane; the usual methods assume roughly equally-spaced control points which just isn't true). You might consider looking at the GIMP's "ink" tool, which IIRC looks reasonable. – tc. Apr 12 '11 at 04:46
  • 2
    I'm also looking for this. I've been trying many ways, using Cubic bezier, quadratic bezier, curve fitting, even tried implementing a hard-to-read research paper, but to no avail. All the implementations I tried still not that smooth. Although the better one is using quadratic bezier, but that's still not as smooth as penultimate or paper. So, I don't think this should be marked as answered/duplicate, because all the "answers" in stackoverflow aren't still as smooth as those good apps. – Coolant Feb 08 '13 at 10:35
  • 1
    I know this question is years ago, but since I commented a few days ago about not being able to achieve a really smooth line, I thought I have to clear this by saying what I found, that I finally found a near perfect smooth by using B-Spline. Not a bezier curve. Here I thought B-Spline means Bezier curve, so I skipped it, lol. It's really smooth. You can check for the code here (it's in other language, but you can port it to obj-c) : http://www.c-sharpcorner.com/UploadFile/apundit/DrawingCurves11182005012515AM/DrawingCurves.aspx – Coolant Feb 14 '13 at 05:47

1 Answers1

1

This has been discussed a few times. You need to use bezair curves and OpenGL. I don't want to rewrite it all, so here is a link to an answer I posted a while ago on the same topic. It is a rather robust answer and should help you get in the right direction.

Community
  • 1
  • 1
Beaker
  • 1,633
  • 13
  • 22
  • where are the comments that were here before?! – Todd Hopkinson Apr 13 '11 at 20:43
  • @icnivad: How were the comments? Were they uncivil? Were they lengthy and/or noisy? There's a good chance that a moderator decided they were unsalvageable and just nuked them. – Robert Harvey Apr 13 '11 at 21:38
  • They were actually pretty good and provided some useful information in regards to the initial question. – Todd Hopkinson Apr 13 '11 at 22:42
  • @icnivad They were trite and useless. It was a pissing contest that I bought into. Anyway. Useful links that were posted: http://stackoverflow.com/questions/1813035/opengl-es-iphone-drawing-anti-aliased-lines and http://answers.oreilly.com/topic/1669-how-to-render-anti-aliased-lines-with-textures-in-ios-4/ Those were all the links I recall were posted. – Beaker Apr 14 '11 at 02:04
  • @Ginamin, your initial answer is right on the money. However, I need a hint on implementation. I am not clear on where I need to place the code from the second example you posted (the code block that is calling drawBezier). If I am using GLPaint, would I replace the renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end with my own [self draw] method? Also, I it seems that the code is supposed to be in a for loop, is that loop supposed to be iterating all the CGPoints in currentStroke array? Lastly, what exactly is the pointCount in that section (there is no declaration for pointCount)? – Todd Hopkinson Apr 14 '11 at 05:36
  • @icnivad Yes, you draw into an OpenGLES2DView. No renderLineToPoint. You don't actually need a loop... I just like to redraw over my lines. You can just use 3 points (a begin (index 0), control (index 1), and end(index 2)). Ah, I forgot about pointCount. That is a modifier to dynamically adjust the number of points based on line thickness. The thinner the line, the more points are required. I usually have it set to 1, unless my line thickness is really large, then I use a larger number. – Beaker Apr 15 '11 at 04:58
  • @Ginamin, thanks. What determines the value of the control? That seems to be the crux of it all. I have bezier curves now, but just can't get the control value right. Using your example, the curve is always toward the center of the screen. The lines look good when I click one spot, then another (though the curve is always toward the center), but when I move my finger to get a realtime stroke, I get a series of small frequent loops. It is all about my control or midpoint. What should the control value be? Any ideas? – Todd Hopkinson Apr 15 '11 at 08:04
  • @icnivad ah no. The code won't draw half the segment, which would be the last half. So, the rendering is 'delayed' because we need to know where the user is drawing to. The control is simply part of the line the user has drawn. I'm not sure why your control is going to the center of the screen... that is really weird. – Beaker Apr 15 '11 at 08:08
  • @icnivad Oh, to be more clear. The control is simply one if the points touchesMoved recorded. However, after curving your line, you need to adjust where the midpoint actually is, or your next line will be off. That is where newMidPoint comes in. That is the new location if your control point (which will become your firstPoint). So after drawing, it recalculates the control, then you need to remove the first point, which will set the old control to your new mid-point, then the touchesMoves will tack on another point, which will be the endPoint. – Beaker Apr 15 '11 at 08:22
  • @Ginamin, ok, so the control gets recalculated, but where is that recalculation - how is the control recaltulated? Is it basically the final x,y in the drawBezier algorithm section? – Todd Hopkinson Apr 15 '11 at 14:20
  • Yes, it is what is returned from the drawBezierCurve function. – Beaker Apr 16 '11 at 06:24