![]() This example app doesn’t smooth between touch points, doesn’t use variable width or opacity for touch inputs, doesn’t do much of anything that I need, except: it renders lines entirely differently than Core Graphics. It was here that I found the GLPaint example app from Apple. Also, sharp turns - like at the top of a cursive lowercase b or d - had uncomfortably flat tops. This also only let me interpolate between widths at each point, but I wasn’t able to interpolate between opacity. And if I drew on the background thread, then the touch inputs wouldn’t lag but the round trip from main=>background=>main for the view refresh was long enough that the stroke appeard to follow the user’s finger after a delay. If I drew on the main thread, it was slow enough to lag the following touch inputs. This wasn’t the fault of the outline algorithm as much as it was the performance of Core Graphics. Up until this point, I had been using Core Graphics to render my lines, but I found that the computation necessary to calculate this path outline and fill it was simply too slow for what I needed. Then, in the case of Core Graphics, we can fill that path, or we can use a traingle stripe to render it in OpenGL. ![]() Essentially: at each point, find two points perpendicular to the line so that we can define the outline of the path, instead of its centerline. This post by Akeil Khan describes the first strategy that I looked at. So I only need to smooth between widths at each point - shouldn’t be too hard…. At each touch point along the curve, I can use the pressure to determine the width at that point. Now that we have a nice curved Bezier path, it’s time to add some body to it. The smoothing code is integrated in SegmentSmoother::addPoint:andSmoothness. The algorithm is defined here by Maxim Shemanarev, which I found through Sean Christmann’s post. It turns out that doing all of those things is harder than it sounds!Īfter trying probably tens of options for a smoothing algorithm, I finally found a single algorithm that satisfied all of these constraints. Bonus points if its configurable for how hard/soft the smoothing is.The line should always pass through the most recently added point as soon as its added.The line should always curve through the touch points exactly.Building a Drawing View for iOS Smooth Curvesįor smooth curves, I had a few requirements that I wanted to keep: ![]() If you’re curious about how it was built and how I navigated those trade-offs, then read on below. If all you need is the drawing view, head straight to the Github project page for the code and sample project. Save and load asynchronously without lag while drawingĪfter trying innumerable existing options, I decided to build my own drawing engine to solve all these features in 1 framework.Variable width/opacity depending on pressure/velocity.Nice smooth curving lines instead of rigid line segments.There were a fair number of tutorials that would solve the first 80%, but there was always some important pieces left as an exercise for the reader: Smooth curves, removing lag and stutter, or main-thread-blocking save/load.Īll of the code I found could do some, but not all, of the following: ![]() When I started working on Loose Leaf, I quickly realized that the hardest part of the app was finding a fast and efficient drawing UIView that I could add into my app.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |