Logo by blob - Contribute your own Logo!

END OF AN ERA, FRACTALFORUMS.COM IS CONTINUED ON FRACTALFORUMS.ORG

it was a great time but no longer maintainable by c.Kleinhuis contact him for any data retrieval,
thanks and see you perhaps in 10 years again

this forum will stay online for reference
News: Did you know ? you can use LaTex inside Postings on fractalforums.com!
 
*
Welcome, Guest. Please login or register. March 29, 2024, 06:26:06 AM


Login with username, password and session length


The All New FractalForums is now in Public Beta Testing! Visit FractalForums.org and check it out!


Pages: [1]   Go Down
  Print  
Share this topic on DiggShare this topic on FacebookShare this topic on GoogleShare this topic on RedditShare this topic on StumbleUponShare this topic on Twitter
Author Topic: Creating a good palette using Bezier interpolation  (Read 12228 times)
0 Members and 1 Guest are viewing this topic.
Matplotlib
Forums Freshman
**
Posts: 13



WWW
« on: May 16, 2017, 11:56:59 AM »

In order to define a palette, one can define some control points, and use linear interpolation to create a gradient. This is what every drawing software does. But when setting up multiple control points, it can resul in some "spikes", and the fractal rendered using this palette can be a bit rough. A way to do so is to preserve differentiability more than continuity. This results in this image :


Fig. 1 : Left, C0 interpolation ; right : C1 interpolation

How to create such a palette ? First, let's take the example of my palette, composed as three lists palette_r, palette_g and palette_b, all of length 2052.
Plot the control points : on the x axis, plot the index of the point in the list, and on the y axis, the RGB value. To make things clear, a linear interpolation would look like this :


Fig. 2 : Linear interpolation for all three RGB values

We'll use a Bezier interpolation (cubic splines) to be able to keep the differientiability at the control points. By setting up control points, one can achieve a cubic spline : given 4 control points P1, P2, P3 and P4, we can define the cubic spline by B(t)=t3P1+3t²(1-t)P2+3t(1-t)²P3+(1-t)3P4 (this uses the Bernstein polynomials ; I won't explain the whole theory here, but it is really interesting, and you should check the Wikipedia articles to give it a start).


Fig. 3 : Cubic splines for the R palette

Given a palette point B, C or D (notations of the Figure 3), if one lines up the previous and the next control points with the palette point, then the differentiability is provided (one the several properties of the Bezier spline is that the vectors P1P3 and P3P4 are tangent to the curve). Ajusting the different control points, and doing so for the three palette lists results in this :


Fig. 4 : The results for the three palettes. It is clear that the linear interpolation gives "spikes" due to roughness around the palette control points. The "steps" for the cubic splines are because colours as defined with three integer values, and not continuous ones

At last, we can compare the results with the palette itself :


Fig. 5 : Comparison of the results
Logged

FractalStefan
Explorer
****
Posts: 45



WWW
« Reply #1 on: May 16, 2017, 01:22:38 PM »

Excellent results - but I wonder how the control points for the Bezier calculation are defined. Are you (or the user) doing this manually, or is this done by an algorithm? Can this be done automatically at all?

I tried something similar recently - but instead of Bezier I used a sinus shape so connect the palette points:


(freehand sketch smiley)

The results were better than linear interpolation, but not really satisfying...
Logged
Matplotlib
Forums Freshman
**
Posts: 13



WWW
« Reply #2 on: May 16, 2017, 01:51:35 PM »

I did this all by hand, but yes, there is a way to do this fully automatically. I already spent a whole afternoon on this, I just didn't want this to become spending the whole week smiley
If I get bored, I'll program an app that will allow the user to define the control points, and that will automatically compute the palette. Well, doesn't this already exist ?
Logged

SamTiba
Safarist
******
Posts: 83


« Reply #3 on: May 16, 2017, 06:35:56 PM »

Didn't thought the implementation of that is new.
I'm using cubic spline interpolation on Matlab for a while now, don't have the time right now but I can compare the results later if it's the same or almost the sa,e.
Logged

Some of my images: Pinterest
FractalStefan
Explorer
****
Posts: 45



WWW
« Reply #4 on: May 16, 2017, 07:21:02 PM »

For comparison, this is a result of sinus-shaped interpolation against linear interpolation as mentioned above:

Linear interpolation:


Sinus-shaped interpolation:


The function I used is:


         function GetColorValue(colorStart, colorEnd, colorIndex)
         {
            if(colorStart != colorEnd)
               colorIndex = (Math.sin(colorIndex * Math.PI - Math.PI / 2) + 1) / 2;

            return ~~(colorStart + (colorEnd - colorStart) * colorIndex);
         }


Where colorStart is the starting value of the color (e.g. 0), colorEnd is the ending value of the color (e.g. 255), and colorIndex is a value from 0 to 1 which points into the color palette which goes from colorStart to colorEnd. (Code is JavaScript.)

The reason why I'm not fully satisfied with this method is that the image sometimes looks like "washed out". So this should be an option which can be switched on or off by the user.

Edit 1:
Instead of

               colorIndex = (Math.sin(colorIndex * Math.PI - Math.PI / 2) + 1) / 2;

this also works:

               colorIndex = (Math.cos(colorIndex * Math.PI + Math.PI) + 1) / 2;

« Last Edit: May 16, 2017, 09:00:03 PM by FractalStefan » Logged
Matplotlib
Forums Freshman
**
Posts: 13



WWW
« Reply #5 on: May 19, 2017, 08:57:50 PM »

I'm using variations on the non-linear color mapping process. Instead of using tanh(n*u/Nmax) (n is adjusted according to the situation), I also tried things like tanh(n*u/Nmax)k where k ranges from 0.5 to 2. At last, I also tried tanh({n*u/Nmax}k) where k ranges from 1 to 2. I used this method to generate new images (some are now in 4K resolution) :
+ http://matplotlib.deviantart.com/art/Julia-set-c-0-763069-0-094691i-681324374
+ http://matplotlib.deviantart.com/art/Julia-set-c-1-769382-0-003138i-4K-render-681421802
+ http://matplotlib.deviantart.com/art/Yet-another-4K-Julia-set-render-681474369
Logged

FractalStefan
Explorer
****
Posts: 45



WWW
« Reply #6 on: May 19, 2017, 09:23:41 PM »

Interesting, but I still wonder why you don't use a divisor like tanh(n) in order to yield a result of exaxtly 1 for u == Nmax.
Logged
Pages: [1]   Go Down
  Print  
 
Jump to:  


Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines

Valid XHTML 1.0! Valid CSS! Dilber MC Theme by HarzeM
Page created in 0.2 seconds with 24 queries. (Pretty URLs adds 0.012s, 2q)