New pen blocks

I think :snap: should have a "set pen mode to [ v]" mode block, and a (pen mode) block. it would have the options "eraser" (which would be affected by the pen size), and a "normal/draw" mode. the last (related) thing is a block that un/redoes the last pen stroke/move.

They're traditionally called penpaint, penerase, penreverse. The latter isn't really an undo; it's an exclusive-or with the existing pentrails.

I am young (in 3rd grade), I don't understand.

So, you know how "or" is generally understood to include "... or both"? Exclusive-or means "A or B but not both." That's just plain natural language meaning. When it comes to computers, if you look at two one-bit values, exclusive or turns out to be the same as ≠. (Work it out.) So, penreverse means to take the RGB colors and exclusive-or them bit for bit.

What this means in practical terms is that if you exclusive-or two arbitrary colors (background and pen) you'll get something hard to interpret, but if you then exclusive-or by the same pen color again, you get back the original background color. It's a way of doing what you wanted without having to maintain a history of drawing, because the picture itself encodes that history.

Does that help?

I don't see how :slightly_frowning_face:

Okay. (This business of reading students' minds, which is the essence of what teachers do, is so much easier face to face!) Actually it's good you're asking, because I just this second realized that I had the algorithm wrong.

Stop me when you don't understand something.

The algorithm: Let's call the background color B. And the pen color P.

  1. Compute B xor P (sorry, "xor" is an abbreviation for exclusive or, in case that's not obvious). Call the result PX. This is just done once, as long as you don't change the foreground or background color.
  2. Now, for each pixel you want to draw on, compute NEW = OLD xor PX. OLD is the old color of that pixel on the screen. NEW will be the new color.

Let's start with the easy case, namely black on white, the usual thing in Snap!. Colors are represented as a string of 24 bits, eight each for red, green, and blue components. (We'll ignore alpha for this discussion.) So, white is the maximum amount of light in all three colors, so all 24 bits are one. (I take it you do know that inside a computer everything is represented in terms of zero and one -- that's the only thing that everyone in the world knows about computers.) So, think B=1, although actually that should be 24 equations B₀=1, B₁=1, B₂=1, and so on. Since we're thinking in black and white, all 24 bits are equal -- all one for white, all zero for black. So you can just pick one of those bits to watch mentally.

The pen is black, so P=0. (Again, this is really 24 bits but we just pick one for this conversation.) If we were doing penpaint (the regular mode that's currently the only mode in Snap! until I talk Jens into this feature), we would just paint P onto the pixel, regardless of what was there before. But we're in penreverse, so we do step 1 of the algorithm above, computing PX = B xor P = 1 xor 0 = 1.

Now, for each pixel we want to draw, we compute NEW = OLD xor PX = 1 xor 1 = 0. So we end up putting down black pixels (since black=0) the same as we would have in penpaint.

But now let's draw over the same pixels again. This time, NEW = OLD xor PX = 0 xor 1 = 1. So we draw in white (all bits 1). If we draw the same pixels a third time, we're back to OLD xor PX = 1 xor 1 = 0. So redrawing alternates between white and black.

Suppose the background were black, and the pen color were white, as in the good old days. In that case, B=0, P=1, PX = B xor P = 0 xor 1 = 1. PX was 1 in the other case too. So once again, each time we draw on a pixel, we flip its color between black and white.

The algorithm is the same for arbitrary colors, but the results are more complicated because the 24 bits aren't all the same. So, for our next example, we'll have a black background (B = 00000.....00) and a spectral (full color) red pen (P = 111111110000000000000000). So PX = 111111110000000000000000 = red, because XORing either bit value with 0 doesn't change it. Now we draw some pixels. Initially they were the background color, so we have NEW = OLD xor PX = red. (Make sure you believe that before continuing.) If we redraw the same pixels, OLD is red and PX is red, so the results are all 0. (That's because 0 xor 0 = 1 xor 1 = 0.) So the pixels turn black.

Things get weirder when we draw colors on a white background in penreverse. So, the background color B is all zeros. We'll stay with a red pen, 111111110000000000000000. So, step 1, PX = B xor P = 000...00 xor 111111110000000000000000 = 000000001111111111111111. This color is green+blue = cyan.

Now for step 2. First time around, OLD xor PX = 111..11 xor 000000001111111111111111 = 111111110000000000000000. We drew in red, as desired. If we redraw the same pixels, OLD xor PX = 111111110000000000000000 xor 000000001111111111111111, which comes out all ones (because each bit's computation is either (0 xor 1 = 1) or (1 xor 0 = 1)). So the resulting color is white, which is the background color.

The algorithm ensures that the first time we draw on a background-color pixel, we get the pen color we asked for; it also ensures that if we draw twice on a pixel with the same color pen, we get the background color. Things look weirder if there are three colors involved; let's say the background is white, but there's a green blob already on the stage, and now we draw across that blob with a red pen. The first step is the same as before, PX = B xor P = white xor red = cyan. Now we want to draw with that pen onto a pixel whose OLD = green = 000000001111111100000000. So, NEW = OLD xor PX = 000000001111111100000000 xor 000000001111111111111111 = 000000000000000011111111 = blue. We think we're drawing in red, but the pixels come out blue. This is necessary so that when we redraw those pixels, we get NEW = OLD xor PX = 000000000000000011111111 xor 000000001111111111111111 = 000000001111111100000000 = green. The second drawing has restored the previous color, green. Repeated drawing with a red pen in penreverse mode will keep flipping between green and blue.

These are simple examples, using primary colors. If you want to paint in orange on a teal blob on a white stage, I have no idea what color you'll actually get. But I do know that repainting the same pixels with the same pen will return them to teal.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.