Curve fit examples

Hi all,

does anyone know where I can get the source code examples for a curve fit/smooth algorithm?

I remember they were in the old code exchange repository, but are not longer in the new one.

http://developer.anscamobile.com/code/bezier-curves-corona

http://developer.anscamobile.com/code/curve-fitting-catmull-spline

Probably in the meantime something better was released.

Thanks in advance.

Ale

Found!

Fortunally I had an 2012 backup where was the sources with some curve fitting examples.

I have collect the curve examples in a zip file attached to this post in case someone needs.

Curve fitting code examples:

Bezier-Curve

CurveFitting

PointReduce

PointReductionCurve

smoothPath

Bye,

Ale

Easing transition is perhaps what you are looking for

Thanks Remi,

I need to draw curves with smooth/antialias effect, do Easing transition is used for draw curves?

Have you seen this tutorial:

https://coronalabs.com/blog/2014/09/09/tutorial-working-with-curved-paths/

Rob

Hi Rob,

yes, for sure, is one of the first I’ve looked  :) 

The tutorial is great for moving objects along bezier curve or organic path.

To perform this job the drawn curve can be not so smoothed.

In my case I need to create a curve by finger and to have a rendered curve without aliasing or pixels gap.

Searching on the net I have found a lot of solutions about smoothing curves and using splines.

Many of this suggest to use Catmull-rom algorithm for drawing smooth lines

But for drawing I don’t believe that to be best solution.

This algorithm works nice if you have a final set of control points, in case of drawing app I don’t have that, points will be added after user moves his finger, and I need to draw new lines immediately.

For this reason I’m using this function to recalculate the smoothed points for a quadratic curve.

I found this on code exchage https://code.coronalabs.com/code/drawing-app-corona 
 

local function calculateSmoothLinePoints()         --print("calculateSmoothLinePoints --\> ")         -- 1 We need at least 3 points to use quad curves.                  if(#points \> 2) then             local smoothedPoints = {};             -- 2 Each time we need our current point and 2 previous ones.             for i=3,#points do                 --print(i);                 local prev2 = points[i - 2];                 local prev1 = points[i - 1];                 local cur = points[i];                                    -- print(prev2,prev1,cur,#points)                 -- 3 Calculate our middle points between touch points.                 local midPoint1 = Vector2D:Mult(Vector2D:Add(prev1, prev2), 0.5);                 local midPoint2 = Vector2D:Mult(Vector2D:Add(cur, prev1), 0.5);                 -- 4 Calculate number of segments, for each 2 pixels there will be one extra segment,                 -- minimum of 32 segments and maximum of 128. If 2 mid points would be 100 pixels apart                 -- we would have 50 segments, we need to make sure we have at least 32 segments or the bending will look aliased…                 local segmentDistance = 2;                   local distance = Vector2D:Dist(midPoint1, midPoint2);                   local numberOfSegments = mMin(mMax(min, mFloor(distance/segmentDistance)), max);                   --print(distance,numberOfSegments)                   -- 5 Calculate our interpolation t increase based on the number of segments.                   local t = 0;                 local step = 1 / numberOfSegments;                 for j=1,numberOfSegments do                     -- 6 Calculate our new points by using quad curve equation. Also use same interpolation for line width.                     local newPoint = Vector2D:Add(Vector2D:Add(Vector2D:Mult(midPoint1, mPow(1 - t, 2)), Vector2D:Mult(prev1, 2 \* (1 - t) \* t)), Vector2D:Mult(midPoint2, t \* t));                        newPoint.width = cur.width                     table.insert(smoothedPoints, newPoint);                     t = t + step;                 end                 -- 7 Add final point connecting to our end point                 local finalPoint = {};                 finalPoint = midPoint2;                                  finalPoint.width = (cur.width );                     --finalPoint.width = 2;                 table.insert(smoothedPoints, finalPoint);             end                          -- 8 Since we will be drawing right after this function, we don’t need old points except the last 2. That way each time user moves his finger we can draw next segment.             local new\_points = {points[#points-1],points[#points]}             points= nil;             points ={};             points = new\_points;             return smoothedPoints;         else             return nil;         end     end

I have modified the example cutting the part that are not in line with my project and this solution seem to improve the quality of drawing but is far to be compared with the native approach using CoreGraphic.

Also there are a lot of problems against performances using this solution.

I’m wondering if this is the best solution to use with corona to draw smooth curves and if someone has already solved the problem to draw smooth and antialiased curves with Corona.

Thanks,
Ale

 

Found!

Fortunally I had an 2012 backup where was the sources with some curve fitting examples.

I have collect the curve examples in a zip file attached to this post in case someone needs.

Curve fitting code examples:

Bezier-Curve

CurveFitting

PointReduce

PointReductionCurve

smoothPath

Bye,

Ale

Easing transition is perhaps what you are looking for

Thanks Remi,

I need to draw curves with smooth/antialias effect, do Easing transition is used for draw curves?

Have you seen this tutorial:

https://coronalabs.com/blog/2014/09/09/tutorial-working-with-curved-paths/

Rob

Hi Rob,

yes, for sure, is one of the first I’ve looked  :) 

The tutorial is great for moving objects along bezier curve or organic path.

To perform this job the drawn curve can be not so smoothed.

In my case I need to create a curve by finger and to have a rendered curve without aliasing or pixels gap.

Searching on the net I have found a lot of solutions about smoothing curves and using splines.

Many of this suggest to use Catmull-rom algorithm for drawing smooth lines

But for drawing I don’t believe that to be best solution.

This algorithm works nice if you have a final set of control points, in case of drawing app I don’t have that, points will be added after user moves his finger, and I need to draw new lines immediately.

For this reason I’m using this function to recalculate the smoothed points for a quadratic curve.

I found this on code exchage https://code.coronalabs.com/code/drawing-app-corona 
 

local function calculateSmoothLinePoints()         --print("calculateSmoothLinePoints --\> ")         -- 1 We need at least 3 points to use quad curves.                  if(#points \> 2) then             local smoothedPoints = {};             -- 2 Each time we need our current point and 2 previous ones.             for i=3,#points do                 --print(i);                 local prev2 = points[i - 2];                 local prev1 = points[i - 1];                 local cur = points[i];                                    -- print(prev2,prev1,cur,#points)                 -- 3 Calculate our middle points between touch points.                 local midPoint1 = Vector2D:Mult(Vector2D:Add(prev1, prev2), 0.5);                 local midPoint2 = Vector2D:Mult(Vector2D:Add(cur, prev1), 0.5);                 -- 4 Calculate number of segments, for each 2 pixels there will be one extra segment,                 -- minimum of 32 segments and maximum of 128. If 2 mid points would be 100 pixels apart                 -- we would have 50 segments, we need to make sure we have at least 32 segments or the bending will look aliased…                 local segmentDistance = 2;                   local distance = Vector2D:Dist(midPoint1, midPoint2);                   local numberOfSegments = mMin(mMax(min, mFloor(distance/segmentDistance)), max);                   --print(distance,numberOfSegments)                   -- 5 Calculate our interpolation t increase based on the number of segments.                   local t = 0;                 local step = 1 / numberOfSegments;                 for j=1,numberOfSegments do                     -- 6 Calculate our new points by using quad curve equation. Also use same interpolation for line width.                     local newPoint = Vector2D:Add(Vector2D:Add(Vector2D:Mult(midPoint1, mPow(1 - t, 2)), Vector2D:Mult(prev1, 2 \* (1 - t) \* t)), Vector2D:Mult(midPoint2, t \* t));                        newPoint.width = cur.width                     table.insert(smoothedPoints, newPoint);                     t = t + step;                 end                 -- 7 Add final point connecting to our end point                 local finalPoint = {};                 finalPoint = midPoint2;                                  finalPoint.width = (cur.width );                     --finalPoint.width = 2;                 table.insert(smoothedPoints, finalPoint);             end                          -- 8 Since we will be drawing right after this function, we don’t need old points except the last 2. That way each time user moves his finger we can draw next segment.             local new\_points = {points[#points-1],points[#points]}             points= nil;             points ={};             points = new\_points;             return smoothedPoints;         else             return nil;         end     end

I have modified the example cutting the part that are not in line with my project and this solution seem to improve the quality of drawing but is far to be compared with the native approach using CoreGraphic.

Also there are a lot of problems against performances using this solution.

I’m wondering if this is the best solution to use with corona to draw smooth curves and if someone has already solved the problem to draw smooth and antialiased curves with Corona.

Thanks,
Ale