Mac Quartic ease in/out in Applescript?

Puonti

macrumors 6502a
Original poster
Mar 14, 2011
825
345
I'm trying to write an Applescript that would dim Philips Hue bulbs based on a quartic ease in/out (speed up until halfway point, then slow down towards the end). The script would run every 10 minutes and calculate what the brightness should be at that time, based on the quartic ease in/out.

I've found the quartic ease in/out formula in other programming languages but unfortunately my attempts to convert it into Applescript have resulted in values that don't make sense. Since programming and Applescript aren't my strong suites I was hoping someone could help me sort this out.

Here's what I have for the calculation:

Code:
set b to 0 as integer -- starting brightness
set c to 255 as integer -- target brightness
set t to 10 as integer -- elapsed time in minutes
set d to 60 as integer -- fade duration in minutes

t ≠ d / 2

if t < 1 then
	set hueBrightness to c / 2 * t * t * t * t + b as real
else
	set t to t - 2
	set hueBrightness to -c / 2 * (t * t * t * t - 2) + b as real
end if
In the sample script above 10 minutes would have passed since the fade began (t = 10).
 

chown33

Moderator
Staff member
Aug 9, 2009
8,497
4,458
Pale blue comma
... I've found the quartic ease in/out formula in other programming languages ...
Where did you find it?

Post the URL where you found the formula you're using.

If there's more than one language on the web page, also tell us exactly which language you used as your example.
 

chown33

Moderator
Staff member
Aug 9, 2009
8,497
4,458
Pale blue comma
The quartic ease-in/out in ActionScript is this:
Code:
// quartic easing in/out - acceleration until halfway, then deceleration
Math.easeInOutQuart = function (t, b, c, d) {
[COLOR="Red"]	t /= d/2;
[/COLOR]	if (t < 1) return c/2*t*t*t*t + b;
	t -= 2;
	return -c/2 * (t*t*t*t - 2) + b;
};
I've hilited in red the line that doesn't correpond to AppleScript.

The correct AppleScript calculation for that line would be:
Code:
set t to t / (d/2)
The /= operator is a divide-and-assign operator, which is completely different from , an inequality comparison.

If this still doesn't produce the desired results, change all your as integer clauses to as real. The calculation may need intermediate floating-point values, not integers.


I should also point out that dividing a 60-minute duration into 10-minute intervals is only going to yield 7 points, counting both end-points. The dimming or brightening at each 10-minute point is probably going to be noticeable.
 

Puonti

macrumors 6502a
Original poster
Mar 14, 2011
825
345
I've hilited in red the line that doesn't correpond to AppleScript.

The correct AppleScript calculation for that line would be:
Code:
set t to t / (d/2)
The /= operator is a divide-and-assign operator, which is completely different from , an inequality comparison.
Thank you so much! I suspected that particular line might have been the cause, but lack of understanding combined with a Google search lead me astray. Your correction gives me the kind of values I was expecting; problem solved! (and more importantly, I hope, lesson learned)

I should also point out that dividing a 60-minute duration into 10-minute intervals is only going to yield 7 points, counting both end-points. The dimming or brightening at each 10-minute point is probably going to be noticeable.
Setting bulb brightness to the resulting value would indeed be visible. My plan is to make use of Hue's transitiontime function which makes the bulbs change brightness (and other values, too) over a given time – in this case 10 minutes.

Thanks again, I appreciate your help.
 

hhas

macrumors regular
Oct 15, 2007
127
0
I should also point out that dividing a 60-minute duration into 10-minute intervals is only going to yield 7 points, counting both end-points. The dimming or brightening at each 10-minute point is probably going to be noticeable.
Yep. A much better approach would be to step down the brightness by a fixed amount each time, and just use a precalculated list of times to sleep between each step. To illustrate:

Code:
-- save as a stay-open applet

global gDelays, gBrightness

on run
   set gDelays to {1, 2, 4, 8, 16, 32, 64, ..., 8, 4, 2, 1} -- whatever
   set gBrightness to 100 -- percentage
end

on idle
   set gBrightness to gBrightness - 5
   if gDelays is {} -- done
      -- tell applet to terminate as soon as idle handler returns
      quit
      return 0
   else
      set nextDelay to first item of gDelays
      set gDelays to rest of gDelays
      return nextDelay
   end
end