fit-curve
fit-curve copied to clipboard
There is no smooth transition for some cases between very sharp and too smooth solutions
@Sphinxxxx Can you check this one. I am not sure, but maybe this is related to major changes you've made. This assumption based on a fact that I had to add additional point in one of my expected results after your changes.
Here is list of points I've drawn on demo page:
var points = [[492,108],[492,111],[494,113],[496,117],[499,119],[503,122],[506,125],[508,126],[510,126],[512,126],[513,127],[515,127],[518,128],[520,128],[523,128],[525,128],[527,128],[529,128],[530,128],[532,128],[533,128],[533,128],[533,129],[534,129],[535,129],[537,129],[538,129],[539,129],[540,129],[541,130],[541,131],[541,134],[541,137],[542,141],[542,143],[542,145],[542,146],[542,147],[542,148],[543,148],[543,149],[543,150],[544,151],[544,152],[545,153],[546,154],[546,155],[547,155],[547,155],[548,155],[549,155],[550,155],[550,154],[551,154],[552,154],[552,154],[553,154],[554,154],[555,154],[556,154],[557,154],[559,154],[559,155],[560,155],[560,156],[561,156],[562,157],[563,158],[564,158],[564,159],[565,160],[566,160],[567,161],[567,161],[568,161],[568,162],[569,162],[570,163],[571,163],[571,164],[572,164],[573,165]];
Here is photos of this line:
What worries me, is that I can't made it up of just 3 points. It goes from 4 right to 2. I can see how there should be a solution with 3 points, that would lay somewhere in between 4 points and 2 point solutions.
Thoughts?
Hello! I'll take a look at this, maybe tomorrow. Do you have the exact coordinates for the expected 3-point solution (and the error tolerance)?
No, I don't have for this specific case. In this case I am just talking about "feeling" that there should be some solution in between. You can open demo paste this:
rawLinesData = [[[492,108],[492,111],[494,113],[496,117],[499,119],[503,122],[506,125],[508,126],[510,126],[512,126],[513,127],[515,127],[518,128],[520,128],[523,128],[525,128],[527,128],[529,128],[530,128],[532,128],[533,128],[533,128],[533,129],[534,129],[535,129],[537,129],[538,129],[539,129],[540,129],[541,130],[541,131],[541,134],[541,137],[542,141],[542,143],[542,145],[542,146],[542,147],[542,148],[543,148],[543,149],[543,150],[544,151],[544,152],[545,153],[546,154],[546,155],[547,155],[547,155],[548,155],[549,155],[550,155],[550,154],[551,154],[552,154],[552,154],[553,154],[554,154],[555,154],[556,154],[557,154],[559,154],[559,155],[560,155],[560,156],[561,156],[562,157],[563,158],[564,158],[564,159],[565,160],[566,160],[567,161],[567,161],[568,161],[568,162],[569,162],[570,163],[571,163],[571,164],[572,164],[573,165]]];
into console and then slide the error slider.
The other case I've mentioned you can find here https://github.com/soswow/fit-curve/commit/172a646986528cc814aa4dea339e907eeadc8523 Expected result was two points, but I had to update it to three points. Not sure if this is related.
I have made this codepen to compare the old version (0.1.1) with the new one (0.1.4): http://codepen.io/Sphinxxxx/pen/jALxvQ
From what I have tested, the new version overall creates just as smooth curves, using fewer segments than the old version. The main difference in the code is the find_t()
method, which helps us estimate the distance from a source point to a curve segment more accurately than before (read the comment in that method).
Now, if you try the codepen with your test data [[0, 0], [10, 10], [10, 0], [20, 0]]
, the new version actually gives the same 2-segment result as the old version if you set the error slider to 3
. But for lower error values, it decides that the first segment isn't close enough to the second point.
Nice. Let's remove my assumption that it were you changes that introduce this. Is there a way to make what I imagined with what we have? Maybe change some internal hyperparameters? Do we have any? Like how many times we want to sample a distance to measure an error? or anything else.
Yeah, that's a really good question. Sure, in some cases it would help if computeMaxError()
sampled the error distance with a set of t
values that are slightly lower and higher than what it gets from find_t()
to find the best match.
However, I don't think that would give us much more "intelligent" fitting, i.e. the curve candidates coming from generateBezier()/newtonRaphsonRootFind()
. I don't understand the math that goes on in there, but FWIW I made another codepen which shows all the different curve candidates that are tested along the way:
http://codepen.io/Sphinxxxx/pen/YWYOJK?editors=0010
Flip through the dropdown list of segments to see the progress. The green curve is the current segment candidate. The black arrow marks the source point that is furthest away from that curve, and the green circle marks the corresponding point on the curve (as estimated by computeMaxError()
)