Sunday, December 31, 2006

Islands of Consciousness

Islands of Consciousness is damn cool. Random composition of random images feeding a random audio composition thingie, creating something pretty strange.

Subdivision made visible

I'm currently working on stroking, and trying to come up with a decent algorithm for that stuff. The big problem here isn't really how to code stuff, but rather what things should look like.

Anyway, in order to visualize some problems for myself, I draw a stroke around a stroke. Then I got the idea that if I modify it a little bit, line segments will become visible, and I kinda liked what the result looked like, as it nicely illustrates the bezier subdivision done.

So in the picture below, there is a cubic bezier, which is subdivided into line segments. Then each of these line segments is made 15 pixels wide, and filled with white. Finally those are stroked with a black outline, which makes each individual segment clearly visible.

Today's daily insight

I think I just cracked a really hard problem: Why does one sometimes get lots of stuff done, while some days it's totally impossible to do anything?

Wednesday, December 27, 2006

Elliptic arcs and some more pron

So far the hardest problem to solve turned out to be how to parametrise arcs. There are three obvious parameters, namely a control triangle of the rational quadratic bezier that is the arc. But how to get a weight for the middle point?

After playing with different parametrisation, I currently have one which gives the middle point the weight of cos(angle/2) where angle is an extra parameter to the function. It happens that when the legs of the control triangle are of equal length, and the angle between them is supplied as angle, one gets an arc of a circle. When the legs aren't of equal length, or the parameter isn't the angle between the legs, one gets an ellipse instead. For zero angle one gets normal non-rational bezier, and for angle pi one gets a straight line. Larger angles give the other side of the ellipse or circle.

Bonus benefit is that when the curve is subdivided in the middle, one doesn't need to track weights for the control points. Just using half the angle will give the proper midpoint weight.

For the typical uses of arcs, there's an extra function which simply makes the guess that the angle between the legs will probably be fine. For stuff like corners of polyline strokes or rectangles this seems to be a reasonable value.

And naturally we have a sample picture:



In the picture you see 3 elliptic arcs, one line and one cubic bezier.

Sunday, December 24, 2006

Beziergons

Did I miss the deadline?

Saturday, December 23, 2006

Two dimensions for a change

Haven't got much of anything interesting added to the synthesizer thingie during the last few days. Instead, I've actually played around a bit in two dimensions. For a long time I've wanted a simple vector graphics library. A few days ago I started playing with the math. The result is rather boring system based on a couple of simple principles:

  1. There is canvas, masks, and paint; paint is applied to canvas through a mask.
  2. Geometric primitives (= line paths) work with masks.
  3. Colors, gradients, bitmaps, whatever, work with paint.
  4. To draw a white triangle, cut a triangle shaped hole in a mask, apply white paint.
The result looks like this (smaller one is screencap, bigger is the same thing magnified):


Now, at this point there isn't even a datatype for a path, so the individual lines in the mask must be drawn separately, but fixing that isn't a huge amount of work (actually probably less than writing this blog post). And I'd expect stuff like beziergons to work before christmas.

Now, what is nice about the design, is that as you see it antializes rather beautifully. It actually draws what you'd get by doing 16x16 naive supersampling and averaging down. Ofcourse all the supersampling is internal to the line drawing function. I'll probably make it 256x256 when I have the extra minute to tweak the algorithm a bit more.

The whole thing is a very basic scanline rasterizer, so the trick really is in the scanlines. Now a scanline rasterizer works by incrementing a counter every time it crosses a line going up, and decrements a counter every time it crosses a line going down. Then you typically fill when you've got either non-zero or odd number in your counter, depending a bit on what you want.

The antialising then is actually quite easy, just a question of putting fractional values in the scanline buffer, and drawing an anti-aliased line. The only important thing then is that the line drawing function makes sure that when one starts from left side of the line, and sums all the pixel values until one has crossed the whole line, the result is exactly one. In a sense, what is being drawn is the finite difference of the edge of an antialised half-plane. And I actually got the idea originally from anti-aliasing audio with BLEPs. Don't ask.

And the best thing? Since integration (and differentiation) are linear operations, one can draw each line independently, and just integrate the scanlines at the end. There aren't really any special cases whatsoever.

Ps. I'm not sure if the above makes any sense. I might consider a better explanation some other day, but I now have to add those beziergons. :)

Monday, December 18, 2006

Sample of what I'm working on

Ok, here's a really quick sample clip of stuff my synthesizer project currently does.


[no-flash: mp3 here]
One sound, live playing, a touch of delay but no other effects.

Oh and the player (which hopefully works) is XSPF Web Music Player button version.