Maths Conundrum, linear curves for RGB bytes.... FIXED

Post here first, or if you can't find a relevant section!
Post Reply
Nutsy
Posts: 237
Joined: Sun Jul 24, 2016 4:26 pm

Maths Conundrum, linear curves for RGB bytes.... FIXED

Post by Nutsy » Fri Mar 17, 2017 12:16 pm

Riiight, I have a maths problem im trying to solve... in my project I have a fade to black function thats called by multiple areas of the program. This is to provide a nice fading trail effect for some of my addressable leds.

But its not perfect and it has issues and im really scratching my head on how to fix it.
Here is an example as its currently written... This doesnt work properly btw...

Code: Select all

long FadeToBlack(uint32_t ledArray, int fadeRate)
//an attempt to centralize the fade effect use in various areas of the program.
{
	long newcol = ledArray;

	uint8_t LEDRdecrease = (newcol >> 16);
	uint8_t LEDGdecrease = (newcol >> 8);
	uint8_t LEDBdecrease = newcol;

	LEDRdecrease = (LEDRdecrease < (LEDRdecrease-(LEDRdecrease/fadeRate))) ? 0 : LEDRdecrease-(LEDRdecrease/fadeRate);
	LEDGdecrease = (LEDGdecrease < (LEDGdecrease-(LEDGdecrease/fadeRate))) ? 0 : LEDGdecrease-(LEDGdecrease/fadeRate);
	LEDBdecrease = (LEDBdecrease < (LEDBdecrease-(LEDBdecrease/fadeRate))) ? 0 : LEDBdecrease-(LEDBdecrease/fadeRate);

	return 65536 * LEDRdecrease + 256 * LEDGdecrease + LEDBdecrease ;
}
So I have three byte variables ranging form 0-255, each representing a colour, R G and B. I need them to reduce with each loop iteration on a linear curve to zero. So they keep the correct colour hue as it fades.

If i simply decrease the number by a fixed rate, the dominant colour quickly shows as the hue alters.

But if i use a devided decrease. While the hue stays the same the number never reaches zero.

I cant hole a global variable because this function is used multiple times by various other functions...

Any ideas?

So to simplfy, i want a fixed straight liner curve down to zero, so the numbers reach zero at the same time and keep the same colour hue as they fade with each loop call...
Last edited by Nutsy on Fri Mar 17, 2017 3:08 pm, edited 1 time in total.

User avatar
Naguissa
Posts: 74
Joined: Sun May 03, 2015 10:38 am
Location: Barcelona, Spain
Contact:

Re: Maths Conundrum, linear curves for RGB bytes....

Post by Naguissa » Fri Mar 17, 2017 1:18 pm

To prevent the neverending effect you could add some constant value to equation.

Also, there's a long variable not needed and return products could be changed to bit displacement (faster):

Code: Select all

long FadeToBlack(uint32_t ledArray, int fadeRate, uint8_t adjust = 10) // Being adjust a (0-100) value
//an attempt to centralize the fade effect use in various areas of the program.
{
   uint8_t LEDRdecrease = (ledArray >> 16);
   uint8_t LEDGdecrease = (ledArray >> 8);
   uint8_t LEDBdecrease = ledArray;
   uint8_t invAdjust =  100 - adjust;
   uint8_t constRate = fadeRate * adjust / 100;

  // Normal operation adjusted to 100% - factor:
   LEDRdecrease = LEDRdecrease/fadeRate *  invAdjust / 100;
   LEDGdecrease = LEDGdecrease/fadeRate *  invAdjust / 100;
   LEDBdecrease = LEDBdecrease/fadeRate *  invAdjust / 100;
   
   // Check linear part.
   LEDRdecrease = LEDRdecrease >= constRate ? LEDRdecrease - constRate : 0;
   LEDGdecrease = LEDGdecrease >= constRate ? LEDGdecrease - constRate : 0;
   LEDBdecrease = LEDBdecrease >= constRate ? LEDBdecrease - constRate : 0;
      
   return LEDRdecrease >> 16 + LEDGdecrease >> 8 + LEDBdecrease ;
}

A little bit tricky, but nice enougth and can solve some issues.

Nutsy
Posts: 237
Joined: Sun Jul 24, 2016 4:26 pm

Re: Maths Conundrum, linear curves for RGB bytes....

Post by Nutsy » Fri Mar 17, 2017 2:11 pm

Thanks for replying, sadly tried inserting your code... Didnt work. But looking at the code im struggling to see what its doing...

I should also mention im feeling pretty exhausted at the moment :p

Nutsy
Posts: 237
Joined: Sun Jul 24, 2016 4:26 pm

Re: Maths Conundrum, linear curves for RGB bytes....

Post by Nutsy » Fri Mar 17, 2017 2:53 pm

With a lot of thanks to another guy from another place.............. he managed to get the right equation...

Code: Select all

long FadeToBlack(uint32_t ledArray, int fadeRate) 
//an attempt to centralise the fade effect used in various areas of the program.
{
	   long newcol = ledArray;

	   uint8_t LEDRdecrease = (newcol >> 16);
	   uint8_t LEDGdecrease = (newcol >> 8);
	   uint8_t LEDBdecrease = newcol;
	   uint8_t LEDaverage = (LEDRdecrease + LEDGdecrease + LEDBdecrease) / 3;

	   LEDRdecrease = (LEDRdecrease < (fadeRate*LEDRdecrease/LEDaverage)) ? 0 : LEDRdecrease-(fadeRate*LEDRdecrease/LEDaverage);
	   LEDGdecrease = (LEDGdecrease < (fadeRate*LEDGdecrease/LEDaverage)) ? 0 : LEDGdecrease-(fadeRate*LEDGdecrease/LEDaverage);
	   LEDBdecrease = (LEDBdecrease < (fadeRate*LEDBdecrease/LEDaverage)) ? 0 : LEDBdecrease-(fadeRate*LEDBdecrease/LEDaverage);

	   return 65536 * LEDRdecrease + 256 * LEDGdecrease + LEDBdecrease ;
}

User avatar
RogerClark
Posts: 6692
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Maths Conundrum, linear curves for RGB bytes.... FIXED

Post by RogerClark » Fri Mar 17, 2017 8:29 pm

I dont known how clever the compiler is...

But looking at your code, it has a product of a division and multiplication that is calculated about 6 times


(fadeRate*LEDRdecrease/LEDaverage);

I would put this in its own variable, in case the compiler doesnt notice this is used all the time

Also AFIK the compiler will do the division first, and cause a possible loss of precision.
I would multiply first, then divide.

Nutsy
Posts: 237
Joined: Sun Jul 24, 2016 4:26 pm

Re: Maths Conundrum, linear curves for RGB bytes.... FIXED

Post by Nutsy » Sat Mar 18, 2017 12:04 pm

the fixed code that the friend gave me did seem to work correctly...

but Im doing some code clean up today... Ill add that to the list of things to try out and change... Maybe it would be a little better... (though as mentioned did seem to work correctly now)

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests