Notifications
Clear all

[Closed] Gradient bitmap

from the autodesk forum on exposing gradient ramp to mxs, a slightly different approach

here what I came up with…

(
	fn GetGradient file_name =
	(
		dotNet.loadAssembly "system.xml"
		xmlDoc = dotNetObject "system.xml.xmlDocument";
		try
			xmlDoc.load file_name;
		catch
			return false;
		
		flags = #()
		root_e = xmlDoc.DocumentElement;
		if root_e != undefined and root_e.name == "gradient" then
		(
			flags_e = root_e.item["flags"];
			if 	flags_e != undefined then
			(
				nflags = flags_e.getAttribute "count" as Integer; 
				flags.count = nflags;
				for f = 1 to nflags do
				(
					flag_e = flags_e.ChildNodes.item (f-1);
					col = execute flag_e.item["color"].InnerText;
					pos = flag_e.item["pos"].InnerText as Float;
					flags[f] = #(pos,col);
				)	
			)	
		)
		flags;
	)

	fn lower_bounds arr left right val =
	(
		while left < right do
		(
			middle = left + (right - left)/2;
			if val <= arr[middle][1] then right = middle else left = middle + 1;
		)		
		left;
	)	
	
	fn get_sub_range arr tval =
	(	
		lb = lower_bounds arr 1 arr.count tval;
		res = [0,0,0];
		if tval == 0.0 then 
			res = [lb, lb + 1,0.0];
		else if tval == 1.0 then 
			res = [lb - 1, lb, 1.0];
		else
		(
			start = arr[lb - 1][1];
			end = arr[lb][1]; 
			res	= [lb - 1, lb, (tval - start)/(end - start)];
		)	
		res;
	)	

	fn lerp  a b s = (a + s * (b - a))	
		
	fn GradientBitmap grad width interp =
	(
		bmap = bitmap width 1 color:white;
		pixels = getPixels bmap [0,0] width;

		for p = 1 to width do
		(	
			t = (p - 1)/(width as float);
			ival = get_sub_range grad t;
			
			pixels[p] = lerp grad[ival[1]][2] grad[ival[2]][2] ival[3];
		)
		setPixels bmap [0,0] pixels;
		bmap
	)	

	grad = GetGradient "gradient.xml"
	bm = GradientBitmap grad 256  1;
	display bm;
)	

where the xml looks like…

<?xml version="1.0"?>
<gradient name = "default" interp = "linear">
	<flags count = "5">
		<flag>
			<color>(color 0 0 0)</color>
			<pos>0.0</pos>	
		</flag>	
		<flag>
			<color>(color 0 0 255)</color>
			<pos>0.25</pos>	
		</flag>	
		<flag>
			<color>(color 128 128 128)</color>
			<pos>0.5</pos>	
		</flag>	
		<flag>
			<color>(color 255 0 0)</color>
			<pos>0.75</pos>	
		</flag>	
		<flag>
			<color>(color 255 255 255)</color>
			<pos>1.0</pos>	
		</flag>	
	</flags>	
</gradient>
2 Replies

the ease in function is

fn ease_in t = pow t 1.5

some strange math for the ease_out

fn ease_out t = if t == 0 then 0 else (pow t 1.61)/t

no exactly right but pretty close

yet to find ease_in_out solutions

this is the ease in out curve (for gradient ramp) as a 3 point bezier (couldn’t find a solution for 2 ) if anyone knows a simpler function that fits this curve . most ease in’s and outs are split across 2 regions (smoothstep withstanding )I guess a bezier solution is as good as any. Though it does have the wiff of smoothstep (which is popular with max devs) though I can’t get it to reproduce this curve. Not quite as “easy as” that one might think eh Denis