views:

155

answers:

4

I am currently developing a little sketching application based on HTML5 Canvas element. There is one particular problem I haven't yet managed to find a proper solution for.

The idea is that the user will be able to manipulate existing stroke data (points) quite freely. This includes pushing point data around (ie. magnet tool) and manipulating it at whim otherwise (ie. altering color).

Note that the current brush engine is able to shade by taking existing stroke data in count. It's a quick and dirty solution as it just iterates the points in the current stroke and checks them against a distance rule.

Now the problem is how to do this in a nice manner. It is extremely important to be able to perform efficient queries that return all points within given canvas coordinate and radius. Other features, such as space usage, should be secondary to this. I don't mind doing some extra processing between strokes while the user is not painting.

Any pointers are welcome. :)

A: 

I would go with simple matrix int pixels[][] where for given pixel at x,y the value of the matrix is its color.

I do not see any clear advantage of using more sophisticated data structures, matrix is very fast and easy to use. As for operations, for instance getting points for given coordinate and radius you just perform the math on matrix indices and only retrieve only matchings pixels etc. Bleeding fast.

pajton
Okay. That makes sense. Is there some standard way for calculating a round kernel for the adjacency query case?
bebraw
I don't think that this is adequate if you have more concrete objects represented on your canvas. (Equivalently, if you have many fewer objects than pixels, as would be typical.)
Rob Lachlan
A: 

I'd basically just wrap an array in an object with some special functions for moving the pixels' data around - or sampling them. I did something fairly similar in a weather-erosion project...just used a Gaussian function to both sample and push data down based on some sort of circumference / weighting principle.

You'd have to have a list of pixels mapping to each 'brushstroke' if you wanted to have undo / brushstroke interactions, but that seems like a different object - you'd just have all your brushstrokes pointing at that central matrix (for the actual contents of the points they influenced - they'd maybe have 'weights' concerning how much color they contributed to the point, or something).

phyllis diller
Yeah. The idea is that undo is handled separately (bounding boxes with old pixel data per stroke). In this case all I'm concerned about is fast access. Note that in this case I don't get to deal with actual pixel data, just points based on which it is rendered.
bebraw
+2  A: 

the standard solution for working with arbitrary points lists in 2d is a quadtree space partitioning: http://en.wikipedia.org/wiki/Quadtree

Johan Henriksson
+1 Yup, that's a good idea.
Rob Lachlan
+1  A: 

You want to have a look at spatial indexing in general. Johan has a good suggestion with the quadtree. Other data structures that might work:

Rob Lachlan
Thanks. I think I will give a grid index ago. It should be easy enough to perform a culling query against it that gives me less points to check. If that doesn't work out well, I will have a look at the other alternatives. :)
bebraw