 Thank you all so much for coming. This is Rainbows. My name is Lido. I work at CareZone. My Twitter handle is LidoNico. You can find me on there. This talk uses a lot of visualizations. It uses specifically the Ruby Graphics gem. It's a gem written by Ryan Davis. And he kind of gave it out to everyone in Seattle and Seattle Ruby community and said, show us what you can do with it. And this talk just came out of everything I did with that. It's available. It's still in beta, so when you gem install, you're going to have to do a dash dash pre. And also, this entire talk is hand drawn, aside from the computer-y bits and the code. I actually tried to draw the QR code, like piece by piece, but that didn't work too well. So from here on out, we're going with the drawings. This is a simulation of fluid. It's based on the particles themselves, each having pressure. I actually learned about the simulation from the work of an amazing Rubyist by the name of Yusuke Endo, who wrote a crazy simulation, all in C, all in the terminal that won the obfuscated C contest. And I'm using the same model. It's called Smooth Particle Hydrodynamics. It's a simple model meant for astronomers to simulate stars crashing into each other, too many objects to worry about real physical correctness and more, just like, let's watch some things slosh around. And that's what we've got going here. I like this a lot. I think there's so much more information here that we're not seeing. If we wanted to see what happens in terms of turbulence, we might want to show how fast each of these particles is moving. My favorite aspect for this is the pressure of each particle that tells us exactly what the model is doing. It calculates pressure around each particle and pushes them away based on higher low pressure areas. So we can kind of map that. We have maybe 100 kilopascals, or whatever, an atmosphere-ish, of pressure. And map that to, like, let's make that a gray. We can do this all across the board. Like 90 kilopascals, we'll say that's the lowest the pressure's ever going to get. There are enough particles sloshing around that that's lowest. That'll be blacked all the way up, number by number, to 120-ish. And that'll be the brightest. So we can implement that. This is now in the Ruby Graphics Gem code. This is, you know, the code I'm going to be showing you is exactly what makes this thing work, and it's built into the gem. So we're just going to take the brightness, and that'll be what's displayed. We'll give that a triple of how much brightness and send that over to the drawing layer, the SDL simple direct layer to send to the GPU. When we do this, it works. So now we can see the pressure of the simulation. It's, you know, the brighter spots where you can see where the water comes crashing down. It's a lot brighter because the area is more pressurized and the opposite for low pressure areas. That's great and all, but I want cool colors. Like, this is the entire point of what I'm doing is I just want pretty pictures. So let's make that happen. How do we even go from a number, like a simple brightness number all the way up to a full color in the spectrum? And computers only really know red, green, and blue anyway. Like that is a pixel on a CRT computer screen. Different computers have different pixels. Like this laptop right here has the little bars of blue, red, green, LCD lights. The projector that's projecting this has a spinning wheel of red, green, and blue that it flashes lights through at the correct interval and it is reflected by mirrors to make each pixel. But only three colors. So how do we map a full spectrum of light to only three colors? And also, how is it even possible to make all of the colors from only three? Answer is biology. Of course, the messiest science of all, and let's get into the real squishy bits, the cells in our eyes. Now, when we receive light into our eyes, there are two different types of cells that receive it. One just receives brightness information, the intensity of light, and that's the rods in our eyes. But the cones can give us information about the wavelength which we perceive as color. And those are those little squid-shaped guys there. Basically, little swizz, I don't know. We have three different kinds. We have a red-sensing cone, a green-sensing cone, and a blue-sensing cone, though some XY people have only two, we call that different kinds of color blindness, and some XX chromosome people have more for scientists have predicted either between 2% and 50% of 2X people have, which seems like kind of a big range, right? Like, who knows? Maybe like 25% of this audience has super color vision. You can distinguish colors better than the rest of us. It's super cool. And so we have these little squid in our eyes, basically. And each kind senses a different kind of light. It's a signal like all red, green, or blue. We can display these on different axes. And we usually, in the computer world, not the biology world, talk about these from zero to 255. Maybe you're more familiar with zero to FF in hexadecimal. When we display a full color, we'll talk about red, green, and blue. And you'll see that in CSS. It'll be a six-digit hex number. So how does our eye do it? How does our brain process how these colors mix? Like, when I see a color, what does our eye expect the analog on the visible spectrum of light to be? Like, when we see yellow, our eyes will say, all right, I'm seeing a little bit of red wavelength and a little bit of green wavelength. It must be in between those two. It must be yellow. So our eye just kind of makes up, you know, when I'm looking at this computer screen, I'm not seeing yellow. I'm seeing red and green light, but on the other hand, when you look at like a lemon, you're seeing real yellow wavelength light. Likewise, for blue and green, combining to make cyan, your eye just kind of interpolates between, I see some green, I see some blue, must be in the middle. But how about magenta? Like blue and red, we're seeing something in between, but there's no green, which is where we expect them to collide. So our brain invents a color to present to us, and magenta is just not real, right? Like, I mean, how could magenta be real if our brains aren't real? So our brain has invented this color, and if we see all the three different wavelengths of light that we can perceive, our brain imagines, all right, that's full spectrum light. That's all the colors I know about. So we're gonna call it full spectrum. It's not white, it's just three colors, but it's, our brain tells us it's full spectrum light. And if we do that all the way around, we get the color cube. Every single color our eyes can perceive out of red, green, and blue light. And we can walk around the edge from most intense color to most intense color to get this smooth transition between the fully saturated colors. Like that is what maps a single number on the spectrum to a triple of red, green, and blue, and vice versa. Here's a Wikipedia-based visualization of like, okay, we start out with all red and blend in more and more green and more green and more green until it's all the way yellow and then blend out red until we get green and then blend in blue and so on and so on. So we can code this up really quickly, imagining that we're walking around the edges of this color cube from like, all the way zero to 360 degrees around. We can say, all right, we're gonna start with red is the strongest color and green is the second strongest. We're gonna push more and more and more green in. And again, this is the code that exists in Ruby Graphics today. And in fact, it's not just around the outsides. You can make any gradient by blending between two colors. You can blend linearly along the outside. If we wanna get from reddish to light salmon, we can just move along the outside of the color cube or through it. If we wanna go from two colors that are on opposite sides, we can go straight through and just linearly interpolate right through the middle of that color cube. And we get a smooth gradient. So we can implement that in Ruby Graphics. Cool. All sorts of cool ads, that's worse, right? But why is that worse? It doesn't give us more information because different colors, even though they're fully saturated, even though I'm showing you the same amount of light for each, they appear to have different brightness. This is first of all, super weird. Second of all, not entirely explained. There's a name for the thing itself. It's called the Helmholtz-Kohlrausch effect. And there are various theories for why this happens, but the best we know is that these colors are all the same, intensity all the same, luminance and theory, and they look really different. In fact, they're even supposed to be the same intensity as that gray background, which just doesn't look like that to me at all. I don't know about you all. Maybe you have better color vision, who knows. So one idea that scientists have come up to explain this is called the opponent process theory of color, and it's a theory about maybe we just don't combine signals, maybe we combine them in a more complicated way. So like when we see red and green light, maybe those just we perceive red and green, great. But maybe we combine those two signals only to get an idea of what lightness is, and you know, you should be thinking like, all right, maybe that explains why yellow appears so bright to us. And when we mix in blue, we might get, okay, we are very bright, we have no blue, that must be yellow, or we have very dark, but all blue, okay, we're seeing blue light. And we can use this to create a better idea of how to desaturate colors. We can graph a lightness plot of like wavelength to how bright it is. So we could do this, we can desaturate the color cube and we can find lines of constant brightness through, but that's gonna take some calculus, blah. Like it's neat, but hard. And actually this paper I'm using the image from has transformed into a different color space because doing it in the color cube was too difficult. Let's not do that, absolutely not. An astronomer named Dave Green came up with a much better way to get a nice smooth transition he wanted for his astronomy, a color scheme that ran from dark to light, but went through colors so he could have his scientific papers printed out really pretty. I mean, basically all of the motivation of this is I wish it looked better. He came up with this idea that, well, television knows a very simple formula for how bright each color is. The NTSC guidelines say that like, here is about how bright each color is. Like red, 30, green is much brighter, blue is much darker. We're just gonna use that. Like we're not gonna build any more complex models of color. We're just going to use that information and I'll show you a demo in color space. Got it? Great. So this is the color cube hollowed out with a lightness vector if we're not, if we're pretending that red, green and blue all have the same brightness to us as humans. Now what this formula I just showed you is saying that maybe it's not like that. Maybe brightness goes along a different direction, this kind of greenish vector. Now this doesn't take into the opponent process theory of color, but it gives us a better idea of we can say, how about if we have a plane of constant brightness, just perpendicular to that lightness vector. That's all we need and you can tell that maybe the muddy yellows are a little bit darker than the cyan's, but it's a pretty good job. In fact, it's much better than just going around the outside of the color cube. And Dave Green thought like, all right, I got this. I have this plane, gonna make this circle, gonna chop one end off and kind of drag it towards black and drag the other end towards white. And in fact, that's exactly what he did. And the code describing it is only a few lines. Afterward, if any of you wants to come up and talk to me about how I got all of here, we can, but suffice to say that this is creating a circle and then stretching it out between dark and light. And forget the WebGL stuff I was showing you earlier. This is a Ruby conference. I'm gonna do this in Ruby graphics and it works. It works beautifully, we get this nice spiral. In fact, the name of this color scheme is called the cube helix. This is a spiral around the middle of the color cube. And it works. We have this color palette, but we're also displaying meaningful information and it's just great. We've done it. This is what I wanted to see out of my simulations. Cool color, meaningful information. That's fantastic, but some of you might be thinking, okay, this color information seems completely wrong. Like my printer prints with cyan, magenta, and yellow. And like when I was taught to paint as a little kid, definitely didn't use those colors. I used red, blue, and yellow, I think, or the paint primaries. So this is because we're painting on a bright surface and shining light added or printer ink in this case. On a reflective background, we put down cyan and that's absorbing the red primary. If we layer magenta over that, we're absorbing green light, so the leftover is just blue bouncing back at us. Kind of the inverse of shining light directly at us. Likewise, if we paint a yellow circle of printer ink over, the red area will be the intersection of yellow and magenta and reflect back to us red light. So that's how those work. And in painting, we kind of just make do because we need colors that mix very well. We make do with phthalocyanine, with cadmium, with alizarin, with these chemicals that are like pretty red, pretty blue. There is no magenta in oil paint that mixes well with another color. It just kind of gets muddier and muddier the more you mix it. And that has to do with the chemical properties of the paints that you're using rather than the color properties themselves. So that's why maybe you were taught to paint with red, blue, and yellow, and you just can't make magenta. It'll never happen. So thank you so much. That's all I got.