MouseListeners
to record the mouse points. Then you have a giant polygon. (Or polyline, technically).The problem is: this is ugly. It's acceptable for beginners, or prototypes: but we can do better.
What I want to do is smooth out this data. To replace the series of lines with attractive bezier curves. To the right is an image of what I'm looking for.
I'm not entirely sure what to call this project. (Is there an official word for this? Does anyone know?) It's a mix between "Vectorization" and "Beautification"? For now I created a simple interface called Vectorizer
:
public interface Vectorizer {
public void add(float x,float y,long t);
public void reset();
public GeneralPath getShape();
public void getShape(GeneralPath path);
public boolean isEmpty();
}
Results
I ended up with the following applet.
You can download this applet here (source included).
Implementation
The applet above demos the
BasicVectorizer
. In pseudocode it goes likes this:currentPoint = 0;
while more points remain:
lastPoint = currentPoint + 1;
create cubic arc from currentPoint to lastPoint
while arc is within the allowed error:
lastPoint++;
create cubic arc from currentPoint to lastPoint
write arc
currentPoint = lastPoint;
This seems to work well for far-away points, but it starts to suffer when several points are clustered together. The problem (for me) is it's hard to guess what the user is trying to do when the mouse moves in a small area: is the user drawing a sharp corner? Just drawing slowly? They might not be using a mouse at all -- maybe an assistive device doesn't track the way mice do?
So there's room for improvement, but it's a start.
Other Resources
The only other open-source pencil tool I'm familiar with is Werner's in JHotDraw. (The license is LGPL. I believe the classes involved are
org.jhotdraw.geom.Bezier
and org.jhotdraw.geom.BezierPath
.)Does anyone have other examples handy on the subject?
For now this meets my immediate needs, but maybe in the future I'll touch it up a little.
No comments:
Post a Comment