Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix derive for degree == 1 and update unit test #164

Merged
merged 3 commits into from
May 15, 2020

Conversation

justinthomas
Copy link
Contributor

The logic in derive was incorrectly avoiding scaling control points for degree == 1. This removes the unnecessary logic and updates the derive_single_line_with_custom_knots unit test to demonstrate successful computation of the correct derivatives.

This is not yet ready to merge as the derive_discontinuous_lines_ignoring_epsilon unit test is currently failing.

The derive_discontinuous_lines_ignoring_epsilon unit test is currently
failing.
@justinthomas justinthomas changed the title Fix derive for degree == 1 and update derive_single_line test Fix derive for degree == 1 and update unit test May 15, 2020
@msteinbeck
Copy link
Owner

Hi @justinthomas,

thank you again for your efforts.

This is not yet ready to merge as the derive_discontinuous_lines_ignoring_epsilon unit test is currently failing.

Will you fix it?

slope[0] = (ctrlp[2] - ctrlp[0]) / span;
slope[1] = (ctrlp[3] - ctrlp[1]) / span;
tsReal step = span / (nsamples - 1);
for(size_t i = 0; i < nsamples; ++i) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you know that TinySpline offers a function to sample splines: ts_bspline_sample. It might be easier to use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point - I completely forgot about that functionality even though I use it frequently

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though, I'm leveraging the independent variable to confirm the slope, so I think I'll stick with ts_bspline_eval for now.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point.

@justinthomas
Copy link
Contributor Author

Happy to help, but I'm not sure what the expected behavior is for the failing unit test. The failure message is

There was 1 failure:
1) derive_discontinuous_lines_ignoring_epsilon: /home/.../tinyspline/test/c/derive.c:475: expected <1.000000> but was <1.428571>

Here's a quick link to the test:

void derive_discontinuous_lines_ignoring_epsilon(CuTest *tc)

@justinthomas
Copy link
Contributor Author

Ah, I think I understand - the multiplicity is what was throwing me off. I think the commit above is an appropriate fix.

@msteinbeck
Copy link
Owner

In this case, discontinuity must be ignored by ts_bspline_derive (epsilon is negative) by "removing" the control point at index 4 (x) and 5 (y). The points used to calculate the derivative are: [2, 2], [3, 3], [1, 1]. This yields a sequence of two points: [1, 1], [-2, -2] because the slope of [2, 2] and [3, 3] is [1, 1] and the slope of [3, 3] and [1, 1] is [-2, -2].

@msteinbeck
Copy link
Owner

msteinbeck commented May 15, 2020

Ah, I think I understand - the multiplicity is what was throwing me off. I think the commit above is an appropriate fix.

This looks very good. It shows that the expected slopes still correspond to the intuitive results. I wonder why scaling (0.7 and 0.3) is necessary.

Edit: Ok, now I understand.

@msteinbeck
Copy link
Owner

msteinbeck commented May 15, 2020

I really like that there are no longer any special cases for degree > 0.

test/c/derive.c Outdated
@@ -173,8 +194,8 @@ void derive_single_line_with_custom_knots(CuTest *tc)
(int) ts_bspline_num_control_points(&spline));
TS_CALL(try, status.code, ts_bspline_control_points(
&spline, &ctrlp, &status))
CuAssertDblEquals(tc, 2.f, ctrlp[0], EPSILON);
CuAssertDblEquals(tc, 8.f, ctrlp[1], EPSILON);
CuAssertDblEquals(tc, 1.f, ctrlp[0], EPSILON);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be easier to understand if you assert 2.f/2.f and 8.f/2.f (similar to derive_discontinuous_lines_ignoring_epsilon). Dividing by 2.f is necessary because span is 2.

@msteinbeck msteinbeck merged commit 31f9d0d into msteinbeck:master May 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants