![](public_html/YaBBImages/1pix.gif) |
Author |
Topic: colors & metaballs... (Read 811 times) |
|
ess
![Email](public_html/YaBBImages/email.gif)
|
colors & metaballs...
« on: May 4th, 2004, 6:01pm » |
|
Hi, I've been studying both seb's and toxi's work with 'metaballs' I started by modifying one of seb's examples to make this: http://mywebpages.comcast.net/warptera/p5/metaball1/ and it got me thinking about the possiblility of using different colored metaballs. I've done some messing around and managed to make some cool effects such as this by modifying r,g,b vlaues instead of just brightness: http://mywebpages.comcast.net/warptera/p5/banner/ [click to reinitialize] but now I'm trying to sit down and really work out the principle in order to make whole-color metaballs that combine with each other, and the colors along their borders should mix, but it's a nightmare. the best I can do is this: http://mywebpages.comcast.net/warptera/p5/metaball2/ [click to reinitialize] The principle in this last applet is that the hue of each pixel is inherited from each one of the nodes according to how far away it is. I've done this by interpolation. But I don't think I have it right because the mixing is uneven and some hues don't appear. it seems to be dominated by red and green. Furthermore, what should the initial value of the hue be before the first interpolation, zero, 50%? it is zero right now, but if you make h~150 then blues start to show up. BUt I cna't get the whole spectrum. And should the number of nodes that have already contributed to a pixel decrease the value of the following interpolation? I really think that the issue is with the interpolation. I need a more sophisticated method to take into account how many nodes have been interpolated before hand. like 'progressive interpolation' or something. I think I'm close to making this work but in the spirit of open-sourceness I thought I'd share and ask you guys if I'm totally missing something. AM I over complicating it? should I go back to colorMode(RGB)? here's the code for metaball 2: Code:int rad=600; color c; float b; float t; float h; int num=3; float dx; float dy; int node[][] = new int[num][5]; void setup() { size(400,200); colorMode(HSB,255); initialize(); } void loop() { sim(); render(); } void mousePressed() { initialize(); } float lerp(float a,float b,float f) { f=f*100/255; f*=.005; return a+(b-a)*f; } void initialize() { for(int i=0; i<num; i++) { node[i][0]=int(random(width)); //current X coor node[i][1]=int(random(height)); //current Y coor node[i][2]=int(random(255)); //hue node[i][3]=int(random(width)); //target X coor node[i][4]=int(random(height)); //target Y coor } } void render() { for(int y=0; y<height; y++) { for(int x=0; x<width; x++) { b=0; h=0; for(int i=0; i<num; i++) { t=0; dx=node[i][0]-x; dy=node[i][1]-y; dx=dx*dx; dy=dy*dy; t=rad*500/(dx+dy); b+=t; if(t>255) {t=511-t;} if(t<0) {t=0;} h=lerp(h,node[i][2],t); } if(b>255) {b=511-b;} if(b<0) {b=0;} c=color(h,255,b); set(x,y,c); } } } void sim() { for(int i=0; i<num; i++) { if(abs(node[i][0]-node[i][3])<=2) { node[i][3]=int(random(width)); //new target X coor } else if(node[i][3]>node[i][0]) { node[i][0]+=2; } else if(node[i][3]<node[i][0]){ node[i][0]-=2; } if(abs(node[i][1]-node[i][4])<=2) { node[i][4]=int(random(height)); //new target Y coor } else if(node[i][4]>node[i][1]) { node[i][1]+=2; } else if(node[i][4]<node[i][1]){ node[i][1]-=2; } } } |
|
|
« Last Edit: May 4th, 2004, 6:19pm by ess » |
|
|
|
|
TomC
|
Re: colors & metaballs...
« Reply #1 on: May 4th, 2004, 6:49pm » |
|
on May 4th, 2004, 6:01pm, ess wrote: Code: float lerp(float a,float b,float f) { f=f*100/255; f*=.005; return a+(b-a)*f; } |
| |
| If f is coming in between 0 and 255, which I think it is, then shouldn't that second line be f *= 0.01; Or the first two lines just be f *= 1.0/255.0 Might have misunderstood what you're doing though...
|
|
|
|
ess
![Email](public_html/YaBBImages/email.gif)
|
Re: colors & metaballs...
« Reply #2 on: May 4th, 2004, 8:01pm » |
|
I think you're right TomC, I switched real quick from colorMode(HSB,100) to colorMode(HSB,255) because I thought that might be the problem, and I guess I fudged the math. [edit: wait, no I think I had it right. but I guess what I was doing was not strict interpolation. what I was trying to do was kinda like weighted averaging. for instance fi the hue of the pixel was 100 (out of 100) and I want to add the hue 50 to it at 100% I want it to come out at 75, not as 50 as strict interpolation does. this is because if a pixel is equidistant from a (for example)red node and a blue node, it needs to be purplish.] But it still doesn't fix the Hue problem. I think my method of sequential interpolation is too simplistic and is favoring the last interpolation too much. Right now it effectively interpolates the hue for each node with a value that is the result of previously interpolated nodes. I think this puts too much weight upon the hues that come last in the loop. I think I need to collect the hues and distances for each node, then find a way to average them all together at once rather than sequentially. say I have the following hues and percentage values: 00.0 20% 20.0 30% 40.0 40% 60.0 50% 80.0 60% (note: the percents are individual strengths from 0-100%. they are not meant to total 100% together.) I need a way to combine all 5 hues accroding to the percentages into one hue. successive interpolation favors the later interpolations more. how can I make sure that they are all weighted equally?
|
« Last Edit: May 4th, 2004, 8:33pm by ess » |
|
|
|
|
TomC
|
Re: colors & metaballs...
« Reply #3 on: May 5th, 2004, 12:11am » |
|
I think you want a weighted average. Multiply your columns together and divide by the total percentage. Quote: 00.0 20% 20.0 30% 40.0 40% 60.0 50% 80.0 60% |
| So you want ((00.0 * 20) + (20.0 * 30) + (40.0 * 40) + (60.0 * 50) + (80.0 * 60)) / (20 + 30 + 40 + 50 + 60)
|
|
|
|
narain
|
Re: colors & metaballs...
« Reply #4 on: May 5th, 2004, 1:51pm » |
|
That's right, successive lerps is the problem, and he's got the solution, but it might not be obvious how you'd do it in your code. What you have to do is, instead of replacing h with the lerp, you'll need to keep two values: the numerator and denominator of TomC's expression. In each iteration, add node[i][2]*t to the numerator and t to the denominator. Ater the loop, divide to get the value of h. By the way, (and this is important!) HSB is a bad way to mix colours. If you mix hue 0% (red) and hue 80% (purple), you'll could end up with 40% -- green! Almost everybody runs into this when they try HSB. This is why your sketch is dominated by red and green. The "outside" is hue 0, red, and to get to any other hue it has to get through orange, yellow, green... Can't think of a way around that right now, except going back to RGB, but you may not want to do that.
|
|
|
|
narain
|
Re: colors & metaballs...
« Reply #6 on: May 5th, 2004, 2:19pm » |
|
It's more than that, actually... It's not just about interpolating between two colors, it's about averaging a whole bunch of colours. And you just can't average on a wheel. (What's the average of red, green and blue?) One way I can think of is to convert hue and saturation, which are simply polar coordinates, to rectangular coordinates, average those, and then do the inverse transform. I have to admit, though, I don't really like that one bit.
|
|
|
|
ess
![Email](public_html/YaBBImages/email.gif)
|
Re: colors & metaballs...
« Reply #7 on: May 5th, 2004, 4:26pm » |
|
thanks for your help guys. I think I got it to work. Right now I'm trying to decide the relationship between the hue and distance. I guess the choices are exponential (like the brightness value is) and linear (as I have it now). I guess I'll finish the program and decide how each option looks, or I could allow the user to choose different modes. take a look: http://mywebpages.comcast.net/warptera/p5/hue/ My main question is about the "grain" that you can see between nodes of very different hues. if it worth changing from "HSB,100" to "HSB,255" to increase the resolution or is this caused by something else like the hue problem narain brought up. Speaking of which, I guess I could decide the "direction" of averaging by calculating the difference between the two values(i.e. for HSB,100: hue1-hue2>50) but I might end up going back to RGB if it gets too complicated. I originally wrote it in RGB so it won't be too much to go back. but unless I'm mistaken, isn't the "brightness" value built into to RGB, where it is separate in HSB? this mean I would need a separate method of calculating brightness. how would this be done? I haven't devoted a ton of thought to it but I'm guessing that before the r,g,b values go into color(), that they would need to be leveled accorded to the desired brightness.
|
« Last Edit: May 5th, 2004, 4:50pm by ess » |
|
|
|
|
ess
![Email](public_html/YaBBImages/email.gif)
|
Re: colors & metaballs...
« Reply #8 on: May 6th, 2004, 5:03am » |
|
thanks agian for the help guys. I got it to work. http://mywebpages.comcast.net/warptera/p5/color_meta_help/ (click to refresh, <spacebar> to toggle helpers) I switched back to RGB,255 to cure the averaging and grainyness problems. I did some experimenting in photoshop and found out that a hue is just an RGB color where one value equals 255, another is 0 and the third is random(0,255). so I forced my RGB color generator to produce hues. then I calculated brightness between 0.0-1.0 and multiplied r,g,b by it to form the rings: http://mywebpages.comcast.net/warptera/p5/color_meta_final/ (click to refresh, <spacebar> to toggle helpers) now I just have to make a decent program out of it. thanks again for the help! -ess
|
|
|
|
narain
|
Re: colors & metaballs...
« Reply #9 on: May 6th, 2004, 5:52am » |
|
Cool. Looks good, ess. Congratulations. Say, do the interiors of the balls have to be black, or can you fill them with their own color?
|
|
|
|
ess
![Email](public_html/YaBBImages/email.gif)
|
Re: colors & metaballs...
« Reply #10 on: May 6th, 2004, 2:45pm » |
|
well, you can think of a meta-ball as a gradient related to the radius. to make the halo effect you see above what you do is: if(B>255 {B=511-B;} if(B<0) {B=0;} [where B equals the brightness value] this effectively 'flips' the gradient, giving the outline a nice smooth transition. you can give the center any color your want but it might not look smooth. here's some examples: keys: <spcbr> initialize <0> toggle color-debug mode <1> for 'halo' <2> for 'black' <3> for 'solid' <4> for 'multi' <5> for 'inverse' http://mywebpages.comcast.net/warptera/p5/color_meta_examples/ as you can see, it isn't always a smooth transition. but one of the orginal examples I posted has kinda a neat multicolored effect: http://mywebpages.comcast.net/warptera/p5/banner/
|
« Last Edit: May 7th, 2004, 3:35pm by ess » |
|
|
|
|
narain
|
Re: colors & metaballs...
« Reply #11 on: May 7th, 2004, 6:20am » |
|
Black mode actually looks kinda cool to me. The way you see bridges form between blobs.
|
|
|
|
|