I think you have two problems: Non-symmetric control points ==== Initially you start with equal distances between p0 to p1 and p1 to p2. If the tolerance angle between the line segments is not met, you move p1 and p2 forward, but keep p0 where it was. This increases the distance between p0 to p1 while keeping the distance between p1 to p2 the same. When you create a curve using p1 as the control points, it can be heavily biased towards p2 depending on how many iterations have passed since the last curve. If you would move p2 twice the amount than p1, you would get even distances between the points. Quadratic curves ==== As mentioned in other answers as well, quadratic curve is not very good for this case. Adjacent curves you create should share a **control point and a tangent**. When your input data is just points, [Catmull-Rom Spline][1] is a good choice for that purpose. It's a cubic Hermite curve, where the tangents for the control points are calculated from previous and next points. The Path API in Android supports Bézier curves, which are a little different than Hermite curves regarding parameters. Fortunately Hermite curves can be converted to Bézier curves. [Here][2] is the first example code I found when Googling. [This Stackoverflow answer][3] also seems to give the formula. You also mentioned the problem of sharp edges. With the input data you have, it's impossible to detect if there is an actual sharp corner or just a very steep curve. If this becomes a problem, you can make the iteration more adaptive by increasing / decreasing the step on-the-fly as needed. **Edit:** After further thinking quadratic curves could be used after all. Instead of drawing a quadratic curve from p0 to p2 using p1 as the control point, draw it from p0 to p1 using a new point p0_1 as the control points. See the picture below. ![New control points][4] If p0_1 is in the intersection of the tangents in p0 and p1, the result should be smooth. Even better, since `PathMeasure.getPosTan()` returns also tangent as the third parameter, you can use actual accurate tangents instead of approximations from adjacent points. With this approach you need less changes to your existing solution. Based on [this answer][5], the intersection point can be calculated with the following formula: getPosTan(pxPlace0, p0, t0); // Also get the tangent getPosTan(pxPlace1, p1, t1); t1 = -t1; // Reverse direction of second tangent vec2 d = p1 - p0; float det = t1.x * t0.y - t1.y * t0.x; float u = (d.y * t1.x - d.x * t1.y) / det; float v = (d.y * t0.x - d.x * t0.y) / det; // Not needed ... yet p0_1 = p0 + u * t0; This solution however works only if both u and v are non-negative. See the second picture: ![Rays don't intersect][6] Here the rays don't intersect although the lines would, since u is negative. In this case it's not possible to draw a quadratic curve that would smoothly connect to the previous one. Here you need the bézier curves. You can calculate the control points for it either with the method given earlier in this answer or derive them directly from the tangents. Projecting p0 to the tangent ray p0+u*t0 and vise versa for the other ray gives both of the control points c0 and c1. You can also adjust the curve by using any point between p0 and c0 instead of c0 as long as it lies on the tangent ray. **Edit2:** If your drawing position is in p1, you can calculate the bezier control points to p2 with the following pseudo code: vec2 p0, p1, p2, p3; // These are calculated with PathMeasure vec2 cp1 = p1 + (p2 - p0) / 6; vec2 cp2 = p2 - (p3 - p1) / 6; With these you can append a path from p1 to p2: path.cubicTo(cp1.x, cp1.y, cp2.x, cp2.y, p2.x, p2.y); Replace the vector operations with per component operations on float[[2]] arrays to match your code. You start by initializing `p1 = start;` and p2 and p3 are the next points. p0 is initially undefined. For the first segment where you don't have p0 yet, you can use a quadratic curve from p1 to p2 with cp2 as the control point. The same for the end of the path where you don't have p3, you can draw a quadratic curve from p1 to p2 with cp1 as the control point. Alternatively you can initialize p0=p1 for the first segment and p3=p2 for the last segment. After every segment you shift the values `p0 = p1; p1 = p2; and p2 = p3;` when moving forward. When you are saving the path, you just save all points p0 ... pN. No need to save the control points cp1 and cp2, as they can be calculated as needed. **Edit3:** As it seems to be hard to get good input values for the curve generation, I propose another approach: Use serialization. Android Path doesn't seem to support it, but fortunately Region class does. See [this answer][7] for the code. This should give you the exact result. It might take some space in the serialized form if it's not optimized, but in that case it should compress very well. Compression is easy in Android Java using [GZIPOutputStream][8]. [1]: http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline [2]: http://processingjs.nihongoresources.com/code%20repository/?get=Catmull-Rom-to-Bezier [3]: https://stackoverflow.com/a/3559116/160539 [4]: https://i.sstatic.net/frOe9.png [5]: https://stackoverflow.com/a/2932601/160539 [6]: https://i.sstatic.net/g4KsZ.png [7]: https://stackoverflow.com/a/13393533/160539 [8]: http://developer.android.com/reference/java/util/zip/GZIPOutputStream.html