Recent

Author Topic: TAChart with spline series  (Read 24560 times)

WDB463

  • New Member
  • *
  • Posts: 11
TAChart with spline series
« on: June 10, 2011, 06:48:56 pm »
According to the English wiki (http://wiki.lazarus.freepascal.org/TAChart) the TAChart shall have a spline series but I cannot find any property or code inside to use it.

Is there any actual version supports this? Is this spline planed (like e.g. TLineSeries with LineType = ltSpline)?
« Last Edit: June 10, 2011, 07:06:54 pm by WDB463 »

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: TAChart with spline series
« Reply #1 on: June 11, 2011, 12:16:39 am »
You are probably referring to the "Roadmap" part of the page,
which contains a rough todo-list of TAChart improvements.
It was slightly outdated -- some of the mentioned changes are already implemented,
but, unfortunately, splines are not one of them. I updated the wiki page.

I shall increase the priority of spline implementation,
since now there is a user who wants them.
Meanwhile, you are welcome to create a feature request and/or patch ;-)

Quote
Is this spline planed (like e.g. TLineSeries with LineType = ltSpline)?
I am inclined to say that splines should be a different series, not subtype of line series.

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: TAChart with spline series
« Reply #2 on: June 12, 2011, 01:25:47 am »
I shall increase the priority of spline implementation

Done. See "Spline" page in the func demo since r31173.

WDB463

  • New Member
  • *
  • Posts: 11
Re: TAChart with spline series
« Reply #3 on: June 15, 2011, 04:33:46 pm »
Fast work. Thanks. But the unfortunately the result is not a Spline, it is a Bézier curve. In a spline the curve is going through the defining values. I had wondered before why no Pointer / ShowPoints exists. Also the BeginUpdate / EndUpdate I have missed. May be this is the reason on the different basis classes.

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: TAChart with spline series
« Reply #4 on: June 16, 2011, 06:28:40 am »
Quote
unfortunately the result is not a Spline, it is a Bézier curve.
More accurately, it is a B-spline. Bezier is a special case of B-spline.
What you want is known (to me, at least) as non-approximating (for example, cubic) spline.
I am sorry I misunderstood you, but please be more specific in the future requests ;-)
I will probably implement this too, but not soon.

Quote
BeginUpdate / EndUpdate I have missed.
Just call ListSource.BeginUpdate / EndUpdate directly.
Wrappers in LineSeries are only for compatibility.

ironphil

  • Jr. Member
  • **
  • Posts: 58
Re: TAChart with spline series
« Reply #5 on: June 21, 2011, 03:19:50 pm »
I needed a way to modelize the background of some signal and I thought a cubic spline would do it. After countless hours I have managed to create a cubic spline in TAChart. It is a natural cubic spline, it goes right through the source points and the curve becomes a straight line at both ends. It would be easy to modify it in order to specify a slope at both ends instead. I use a line series (with the line invisible) as the source and a another line series (with the points invisible) as the spline curve. I based my code on this documentation:
http://people.math.sfu.ca/~stockie/teaching/macm316/notes/splines.pdf

To solve the equation system I use 4 files from the dmath (tpmath) project (http://www.unilim.fr/pages_perso/jean.debord/tpmath/tpmath.htm) which allow me to call a function which does a Gauss-Jordan elimination on the array I created with the values of the source points.
The solution of the equation system allows me to calculate the coefficients for all the spline segments which I can then draw using an appropriate increment.

So far it seems to work perfectly but I am not a very skilled programmer, I do this for fun, so my code might not be that optimized or elegant. If you want to take a look at it anyway I can extract the cubic spline code from my project when I'll get home and attach it.

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: TAChart with spline series
« Reply #6 on: June 22, 2011, 02:00:06 pm »
Quote
After countless hours
Did you encounter any specific problems?

Quote
If you want to take a look at it anyway
Sure, it would not harm.

ironphil

  • Jr. Member
  • **
  • Posts: 58
Re: TAChart with spline series
« Reply #7 on: June 25, 2011, 01:50:50 am »
Quote
Did you encounter any specific problems?
The problems I had were mostly related to the mathematics behind the cubic spline and the numerous counters in my code going out of bounds. The TAChart part was ok as I only had to read the source points and draw the curve.

But it would be cool to be able to use the drag point tool and have the spline be recalculated as a point is dragged. I did not manage to do it with the drag point tool as I don't know how to call some code as the point is being dragged. But if I use the mousedown, mousemove and mouseup events to drag a point (with the movepoint procedure and the coordinates of the mouse) it works, the spline is constantly recalculated and redrawn as long as I am dragging the point (well sometimes the point gets dropped, I don't know why...). That is what I would like to achieve to modelize some background. The problem is that if I am doing it that way, I cannot use the chart tools anymore because I am using the mouse events of the chart.

I have attached a small project showing the cubic spline and what I would like to do with the point dragging. The additional files (ugausjor.pas, uminmax.pas, utypes.pas and types.inc) are from the TPMath project and are needed to solve the equation system for the spline calculation.

As I said, I am doing this mostly for fun, so there is no hurry to implement any of this (at least for me but it seems there is another user who wants the cubic spline).

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: TAChart with spline series
« Reply #8 on: June 25, 2011, 04:28:03 am »
Quote
The additional files (ugausjor.pas, uminmax.pas, utypes.pas and types.inc) are from the TPMath project

Do you know what license they are under?

ironphil

  • Jr. Member
  • **
  • Posts: 58
Re: TAChart with spline series
« Reply #9 on: June 25, 2011, 01:54:10 pm »
Good point, I should have verified before but it seems the library is under the LGPL license.

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: TAChart with spline series
« Reply #10 on: June 26, 2011, 07:31:43 pm »
Your implementation is generally ok.
The main problem IMO is that you draw spline as a polyline instead of function,
so zooming in on it may show sharp angles.

I added initial implementation of TCubicSplineSeries, see "Spline" page in the func demo since r31408.
Instead of adding yet another third-party numeric library,
I decided to try fixing one already supplied with FPC.
We shall see how this plays out.

WDB463

  • New Member
  • *
  • Posts: 11
Re: TAChart with spline series
« Reply #11 on: June 28, 2011, 05:34:54 pm »
I have tested this basic implementation and it works exactly in that way as I thought. Also the zoom works absolutely perfect.

In some cases e.g. during the direct input of data it seems that the calculation takes to much time so that the program reaction stops for a while. Then it could be make sense to put the calculation and the drawing into an individual threat.

Actually I have found some failures:
  • The line is shown only if there are more than 5 points in the line.
  • The maximum point in x direction in the line has a wrong y value.
  • If one x value above index 2 is zero then it gets a div zero exception.
  • If the line exceeds the maximum or minimum of the points y values it will be cut.
Additional question: Are pointer planned to add at this line type?

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: TAChart with spline series
« Reply #12 on: June 28, 2011, 06:48:30 pm »
Quote
The maximum point in x direction in the line has a wrong y value.
If the line exceeds the maximum or minimum of the points y values it will be cut.
Fixed in r31430

Quote
Are pointer planned to add at this line type?
Added in r31432-r31434.

Quote
In some cases e.g. during the direct input of data it seems that the calculation takes to much time so that the program reaction stops for a while. Then it could be make sense to put the calculation and the drawing into an individual threat.

I can understand that the calculation may be somewhat slow, but I tested with 1000 points,
and it is still below 0.1 sec. How many points do you have?
What do you mean by "direct input"?

Quote
The line is shown only if there are more than 5 points in the line.
If I understand the theory correctly, you need at least 4 points to define
a cubic spline. (It was 5 due to the same error that caused last point to be missed).

Quote
If one x value above index 2 is zero then it gets a div zero exception.
Can not reproduce. Please post a project demonstrating the error.

WDB463

  • New Member
  • *
  • Posts: 11
Re: TAChart with spline series
« Reply #13 on: June 30, 2011, 09:51:32 am »
Div-Zero-Exceptions occur in e.g. this cases:
Code: [Select]
 
Chart1CubicSplineSeries1.AddXY(0,0);
Chart1CubicSplineSeries1.AddXY(0,1);
Chart1CubicSplineSeries1.AddXY(2,4);
Chart1CubicSplineSeries1.AddXY(3,9);
and
Code: [Select]
Chart1CubicSplineSeries1.AddXY(0,0);
Chart1CubicSplineSeries1.AddXY(1,1);
Chart1CubicSplineSeries1.AddXY(0,4);
Chart1CubicSplineSeries1.AddXY(0,9);
and also sometimes if two x values are the same
Code: [Select]
Chart1CubicSplineSeries1.AddXY(0,0);
Chart1CubicSplineSeries1.AddXY(1,1);
Chart1CubicSplineSeries1.AddXY(1,4);
Chart1CubicSplineSeries1.AddXY(3,9);
Interestingly it does not occur in this case although there are a multiple zero and equal identical x values in:
Code: [Select]
Chart1CubicSplineSeries1.AddXY(0,0);
Chart1CubicSplineSeries1.AddXY(1,1);
Chart1CubicSplineSeries1.AddXY(0,4);
Chart1CubicSplineSeries1.AddXY(3,9);


A drawing outside the chart area happens in e.g. this case
Code: [Select]
Chart1CubicSplineSeries1.AddXY(-1,0);
Chart1CubicSplineSeries1.AddXY(1,0);
Chart1CubicSplineSeries1.AddXY(2,3);
Chart1CubicSplineSeries1.AddXY(3,8);


Idea for drawing the series if the number of points are below 4:
  • 1 point: drawing of this point
  • 2 points: drawing of a line between the points
  • 3 points: drawing of in the same way as the end points of the cubic spline or by a quadratic solution
Then the series can be drawn always also when less points exists.


The drawing speed is is still ok. May be it came by the debugger at the catching of the div zero exception.

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: TAChart with spline series
« Reply #14 on: June 30, 2011, 05:24:39 pm »
Quote
Div-Zero-Exceptions occur in e.g. this cases

I see now -- it occurs when the sequential X values are equal.
Fixed in r31479 -- such a spline will not be drawn.

Quote
Idea for drawing the series if the number of points are below 4

Of course, but then the resulting curve will not be a cubic spline,
which may confuse some users.

Maybe I'll add "DrawIfIncorrect" property, which, if set to true,
will let the series draw under-defined and ill-defined splines
(for example, in case of duplicate X value it can ignore the second point and still draw something).

 

TinyPortal © 2005-2018