We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexDiscussionExhibition › Drawing a line of points at even distances, fast
Page Index Toggle Pages: 1
Drawing a line of points at even distances, fast (Read 783 times)
Drawing a line of points at even distances, fast
Aug 1st, 2009, 2:43pm
 
I came up with this method at work, and it seems pretty useful to me so I thought I'd share it.

It's basically a way of drawing a free hand line, but keeping all the points in that line at even distances apart.

Code:

int frame_count, mouse_count;
boolean mouse_pressed;
Paint paint;

void setup(){
size(400, 400);
paint = new Paint(10, 20);
smooth();
}

void draw(){
background(255);
paint.main();
frame_count++;
}

void mousePressed(){
mouse_count = frame_count;
mouse_pressed = true;
}
void mouseReleased(){
mouse_pressed = false;
}
class Line{
PVector a, b;
float vx, vy, dx, dy, length;
Line(PVector a, PVector b){
this.a = a;
this.b = b;
updateLine();
}
void updateLine(){
vx = b.x - a.x;
vy = b.y - a.y;
length = sqrt(vx * vx + vy * vy);
if(length > 0){
dx = vx/length;
dy = vy/length;
}
else {
dx = 0.0f;
dy = 0.0f;
}
}
void draw(){
line(a.x, a.y, b.x, b.y);
}
}

public class Paint {
ArrayList lines, dots;
PVector last;
int length;
float spacing;
Paint(int spacing, int length){
lines = new ArrayList();
dots = new ArrayList();
last = null;
this.spacing = spacing;
this.length = length;
}
// Adds dots inbetween dots that are too far apart
void interpolate(PVector a, PVector b) {
Line line = new Line(a, b);
// the number of segments we will divide the gap into
int denominator = (int)(line.length / spacing);
// the distance between each new dot (note that it will be a little above spacing
// this means it'll look slightly uneven - but no bunching and we get fast results)
float step = line.length / denominator;
for(float n = step; n < line.length; n += step) {
// hack to deal with flash's bullshit floating point math
// not sure if java does this too, but I'm playing safe
if(line.length - n < step * 0.5) break;
dots.add(new PVector(a.x + line.dx * n, a.y + line.dy * n));
}
}
// Returns true if (x0,y0) is less than length from (x1,y1)
boolean proximity(float x0, float y0, float x1, float y1, float length){
return (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) <= length * length;
}
void main() {
int i, j;
// saves me putting this function in mousePressed()
if(mouse_count == frame_count) {
clear();
}
// painting routine
if(mouse_pressed){
float x = mouseX;
float y = mouseY;
PVector next = null;
if(last == null){
// draw the first dot
last = new PVector(x, y);
dots.add(last);
} else {
// add new dots, but only if they're further than 'spacing' apart
if(!proximity(x, y, last.x, last.y, spacing)){
next = new PVector(x, y);
}
}
if(next != null) {
// dots that are too far apart we break up
if(!proximity(last.x, last.y, next.x, next.y, spacing * 2)) {
interpolate(last, next);
}
dots.add(next);
// turn those dots into lines
while(dots.size() > 1) {
last = (PVector)dots.get(1);
lines.add(new Line((PVector)dots.remove(0), last));
}
// limit the length of the whole chain
while(lines.size() >= length) lines.remove(0);
}
}
draw();
}
// clears the paint from the screen and memory
void clear() {
lines = new ArrayList();
dots = new ArrayList();
last = null;
}
void draw(){
for(int i = 0; i < lines.size(); i++){
Line temp = (Line)lines.get(i);
temp.draw();
ellipse(temp.a.x, temp.a.y, 5, 5);
}
}
}
Re: Drawing a line of points at even distances, fast
Reply #1 - Aug 3rd, 2009, 10:22pm
 
You might find this interesting

http://www.algorithmist.net/arclengthparam.html

Scroll down to 'Arc Length Parametrization'
Page Index Toggle Pages: 1