fit-curve icon indicating copy to clipboard operation
fit-curve copied to clipboard

There is no smooth transition for some cases between very sharp and too smooth solutions

Open soswow opened this issue 8 years ago • 5 comments

@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: screen shot 2016-12-03 at 4 38 07 pm

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?

soswow avatar Dec 03 '16 05:12 soswow

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)?

Sphinxxxx avatar Dec 04 '16 23:12 Sphinxxxx

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.

soswow avatar Dec 05 '16 01:12 soswow

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.

Sphinxxxx avatar Dec 06 '16 02:12 Sphinxxxx

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.

soswow avatar Dec 06 '16 04:12 soswow

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())

Sphinxxxx avatar Dec 06 '16 16:12 Sphinxxxx