Reputation:
I would like to generate a table of values for an input/output curve from 0 to 255 based on specific points, and have that curve smooth.
It is basically the same thing we use when editing the brightness of a picture with RGB curves.
e.g. I would define the points 0,0 ; 128,104 ; 255,255 and I would get all values from 0 to 255 with something smooth (non-linear) around 128,104. I would eventually be able to configure how smooth that curve is.
I could program it but it seems like a little bit of pain and I'm quite sure something like this exists as a module or script already.
Thank you!
EDIT:
The answer from Benjamin W. produces the following result with the following code:
require Math::Spline;
my @x = (0, 64, 128, 204, 255);
my @y = (0, 12, 64, 224, 255);
$spline = Math::Spline->new(\@x,\@y);
for( my $a = 0 ; $a < 256 ; $a++ ){
print("$a\t".$spline->evaluate($a)."\n");
}
Upvotes: 1
Views: 285
Reputation: 52152
Smoothly connecting points can be done by means of spline interpolation, where you calculate a piecewise polynomial. For Perl, there is the module Math::Spline.
For your example (slightly modified to make the "bend" better visible), it would roughly look like this:
use strict;
use warnings;
use feature 'say';
use Math::Spline;
my @x = (0, 210, 255);
my @y = (0, 124, 255);
my $spline = Math::Spline->new(\@x, \@y);
my @x_interp = (0 .. 255);
my @y_interp;
for my $x_i (@x_interp) {
push @y_interp, $spline->evaluate($x_i);
}
say "$x_interp[$_]\t$y_interp[$_]" for (0 .. 255);
The output can be piped to a file and plotted, for example with gnuplot:
Upvotes: 2