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

BUG: The tension parameter does not have the expected effect on the curve #4120

Open
raindropsfromsky opened this issue Jan 17, 2018 · 13 comments
Labels

Comments

@raindropsfromsky
Copy link

I thought that a higher "Tension" in automation curve should make it look more like linear progression, while a lower tension should allow a smoother transition between control points. Secondly, I expected this change to occur throughout the length of the curve.

But this is not so, as can be seen from the following samples:
This is the graph with the lowest tension:
image

This is the same graph, with the highest tension:
image

But in reality, the following unexpected things happen:

  1. Only the left side of the graph is affected more. The right side is hardly affected.
    This is as if we have put multiple nails on a board (where the control points are),
    and then threaded a string around them.
    As we pull the string from left, only its portion on the left experiences the pull.
  2. Increasing the tension actually relaxes the curve, which becomes more rounded (instead of sharper).
  3. With the highest tension, the graph does not resemble linear progression.
@tresf
Copy link
Member

tresf commented Jan 17, 2018

In a quick unit test, it seems to ignore the last two points. Is that what you're observing? The last point I believe is intentional, so I'd guess this is a simple off-by-one coding mistake.

@raindropsfromsky
Copy link
Author

raindropsfromsky commented Jan 17, 2018

No on the whole, when I adjust the tension from 0 to 1, I see a little movement only in the left (starting of the timeline). The rest of the curve remains more or less unchanged.

Secondly, the curve behaves exactly opposite compared to what I expect: More tension actually relaxes the curve.

Can I attach a video here?

@tresf
Copy link
Member

tresf commented Jan 17, 2018

Can I attach a video here?

You'd have to link it to a video service however GIFs will work.

Ok, I took a closer look at the tension behavior and I think "tension" is the wrong description here (or the values are reversed). Inkscape uses node handles and the length of them determines the width of the curve.

It's been asked before and I think we could benefit from allowing a true zero length curve to obtain a straight line, but we should also extend to the behavior to be able to control both with option to link (default) and unlink.

image

@raindropsfromsky
Copy link
Author

I created a random shape, and then varied the tension.
The yellow dotted line shows the original curve at tension=0.
Note that there is no difference in 2-3, 3-4, 4-5, 5-6 and 8-9 segments at all. (WHY??)
image
There is a dramatic difference in segment 1-2 (at left).
In this case there is some change at right too (6-7 and 7-8).

The general observation is that sag is removed when tension is increased.
But then I don't think the algorithm draws the curve based on gravity! :)

@raindropsfromsky
Copy link
Author

Ok, I took a closer look at the tension behavior and I think "tension" is the wrong description here (or the values are reversed). Inkscape uses node handles and the length of them determines the width of the curve.

Bingo! I was thinking of InkScape when I made the observations.

In InkScape, the handles are not only made longer to simulate the increased tension, but the handles are turned toward the next/previous control point also. Thus as the tension is increased, the curve more and more resembles the linear progression curve.

@tresf
Copy link
Member

tresf commented Jan 17, 2018

Probably a good to-do for @codythecoder, related #2466. Thanks for reporting @raindropsfromsky.

@raindropsfromsky
Copy link
Author

image

I tried to add tangents (handles) with their lengths proportionate to the tension.

  • The pale yellow arrows show handles for tension=0.
  • The red arrows show handles for tension=1.

They do not seem to follow either of the two rules:

  1. When tension increases, the force increases
  2. When tension increases, the handles turn toward the adjacent control point.

@musikBear
Copy link

just a comment
Changing these curves influence old projects

@tresf
Copy link
Member

tresf commented Jan 17, 2018

Changing these curves influence old projects

Yes, any bug fixes need to carefully consider backwards compatibility, but we're not in the business of preserving bugs, so please save the comments for the PRs and the actual testing.

@Anonymouqs Anonymouqs added the bug label Feb 28, 2018
@PhysSong
Copy link
Member

PhysSong commented Mar 6, 2018

I've also looked into the logic and found that the tension parameter affects slopes of tangent lines. If tension is 0, every tangent line should be a horizontal line. If it's 1, a tangent line from a point will be parallel to the line which connects two adjacent points. For implementation details, see AutomationPattern::generateTangents and the logic below.

int numValues = ((v+1).key() - v.key());
float t = (float) offset / (float) numValues;
float m1 = (m_tangents[v.key()]) * numValues * m_tension;
float m2 = (m_tangents[(v+1).key()]) * numValues * m_tension;
return ( 2*pow(t,3) - 3*pow(t,2) + 1 ) * v.value()
+ ( pow(t,3) - 2*pow(t,2) + t) * m1
+ ( -2*pow(t,3) + 3*pow(t,2) ) * (v+1).value()
+ ( pow(t,3) - pow(t,2) ) * m2;

Here m1 and m2 stands for starting tangent and ending tangent.

FYI, the Cubic Hermite spline progression is introduced in 6249b23.

@raindropsfromsky
Copy link
Author

If tension is 0, every tangent line should be a horizontal line.

Isn't that one of the problems? If you see my actual graph, the tangents are NOT supposed to be horizontal at any time. This will only work if the peaks and troughs are symmetrical around X-axis (such as point#4 in the graph). That is rarely the case.

@PhysSong
Copy link
Member

PhysSong commented Mar 6, 2018

tangents are NOT supposed to be horizontal at any time.

Yes, it may be bad in some(maybe almost every?) situation. Current implementation for tension=0 doesn't look good for me.

I thought that a higher "Tension" in automation curve should make it look more like linear progression, while a lower tension should allow a smoother transition between control points.

As long as we keep using cubic Hermite spline, the only way to change the curve is changing tangents at automation points. Unless LMMS allows discontinuous slope at points for cubic Hermite progression(which is supposed to be have smooth curve IMO), that's almost impossible.

@PhysSong
Copy link
Member

I think we can use control points for cubic Hermite spline, as well as the Bezier curve in #2466.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants