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.
IndexProgramming Questions & HelpSyntax Questions › dotted or dashed lines
Page Index Toggle Pages: 1
dotted or dashed lines? (Read 2231 times)
dotted or dashed lines?
Feb 8th, 2008, 4:59pm
 
It appears that there is no built-in way to draw dotted or dashed lines.  I've searched and not come up with anything.

It's easy enough to write something to do it, but if it was built-in it would potentially be more efficient (and my code would probably be cleaner).

I was hoping to find something similar to strokeWeight (strokeType?).

Is this the case?  Dotted and dashed lines must be created manually?
Re: dotted or dashed lines?
Reply #1 - Feb 9th, 2008, 9:28pm
 
Yes, it's a DIY job. Whether it would be more efficient is something only the seniors can answer.

You'll find the following functions useful:

http://processing.org/reference/curvePoint_.html

http://processing.org/reference/bezierPoint_.html

http://processing.org/reference/strokeCap_.html

http://processing.org/reference/lerp_.html

Curved dashed lines may be a bugger to do.
Re: dotted or dashed lines?
Reply #2 - Feb 9th, 2008, 10:13pm
 
In the OPENGL mode you can use the glLineStipple methode:

Code:

PGraphicsOpenGL pgl = (PGraphicsOpenGL) p.g;
GL gl = pgl.gl;
pgl.beginGL();
gl.glLineStipple(10, (short) 0xFA0FA);
gl.glEnable(GL.GL_LINE_STIPPLE);
pgl.endGL();
Re: dotted or dashed lines?
Reply #3 - Feb 10th, 2008, 7:36pm
 
Here's the function I ended up writing in case anyone wants something similar.  I originally wrote a couple quick functions to do horizontal and vertical lines (which are all that I need).  This function will work with diagonal lines as well.  I make no claims about its efficiency.

The xStart, yStart and xEnd, yEnd arguments should be self-explanatory.

The linePattern argument determines the type of dashing or dotting that should be used.  The function uses the binary pattern of the argument to do this.  The least significant bit is used first.

Note that the pattern will not necessarily start a xStart, yStart.  The end points may be changed around by the implentation of the Bresenham algorithm.

Some examples:
 linePattern = 0x5555 will be a dotted line, alternating one drawn and one skipped pixel.
 linePattern = 0x0F0F will be medium sized dashes.
 linePattern = 0xFF00 will be large dashes.

The lineScale argument controls the size of the pattern.  If you create a dotted line with linePattern = 0x5555 and a lineScale of 1, you will get a dotted line.  If you use a lineScale of 2, you will get a dashed line with two pixels on, two off (the same as linePattern = 0x3333, lineScale = 1).  lineScale is primarily there to allow much larger dashes and patterns that can't be defined with the 16 bits in linePattern.  A lineScale of 0 is the same as 1.

The color is based on the current stroke() color.

Code:

//based on Bresenham's algorithm from wikipedia
//http://en.wikipedia.org/wiki/Bresenham's_line_algorithm

void patternLine(int xStart, int yStart, int xEnd, int yEnd, int linePattern, int lineScale) {
int temp, yStep, x, y;
int pattern = linePattern;
int carry;
int count = lineScale;

boolean steep = (abs(yEnd - yStart) > abs(xEnd - xStart));
if (steep == true) {
temp = xStart;
xStart = yStart;
yStart = temp;
temp = xEnd;
xEnd = yEnd;
yEnd = temp;
}
if (xStart > xEnd) {
temp = xStart;
xStart = xEnd;
xEnd = temp;
temp = yStart;
yStart = yEnd;
yEnd = temp;
}
int deltaX = xEnd - xStart;
int deltaY = abs(yEnd - yStart);
int error = - (deltaX + 1) / 2;

y = yStart;
if (yStart < yEnd) {
yStep = 1;
} else {
yStep = -1;
}
for (x = xStart; x <= xEnd; x++) {
if ((pattern & 1) == 1) {
if (steep == true) {
point(y, x);
} else {
point(x, y);
}
carry = 0x8000;
} else {
carry = 0;
}
count--;
if (count <= 0) {
pattern = (pattern >> 1) + carry;
count = lineScale;
}

error += deltaY;
if (error >= 0) {
y += yStep;
error -= deltaX;
}
}
}


I'm not sure why some of the indenting above is a little funny.

Here's a very quick piece of code that draws dashed lines:

Code:

void setup() {
size (500,500);

stroke(0);
for (int i = 0; i <= 20; i++) {
int x = 10 + i * 10;
patternLine(x, 10, x, 400, 0x5555, i);
}
}

void draw() {
}
Re: dotted or dashed lines?
Reply #4 - Jan 19th, 2010, 9:25pm
 
I've written a generic dashed line routine, patterned after the way SVG does stroke-dasharray. Examples in my code posted at openprocessing.org (user jdeisenberg)

Code:
/* 
* Draw a dashed line with given set of dashes and gap lengths.
* x0 starting x-coordinate of line.
* y0 starting y-coordinate of line.
* x1 ending x-coordinate of line.
* y1 ending y-coordinate of line.
* spacing array giving lengths of dashes and gaps in pixels;
*  an array with values {5, 3, 9, 4} will draw a line with a
*  5-pixel dash, 3-pixel gap, 9-pixel dash, and 4-pixel gap.
*  if the array has an odd number of entries, the values are
*  recycled, so an array of {5, 3, 2} will draw a line with a
*  5-pixel dash, 3-pixel gap, 2-pixel dash, 5-pixel gap,
*  3-pixel dash, and 2-pixel gap, then repeat.
*/
void dashline(float x0, float y0, float x1, float y1, float[ ] spacing)
{
 float distance = dist(x0, y0, x1, y1);
 float [ ] xSpacing = new float[spacing.length];
 float [ ] ySpacing = new float[spacing.length];
 float drawn = 0.0;  // amount of distance drawn

 if (distance > 0)
 {
   int i;
   boolean drawLine = true; // alternate between dashes and gaps

   /*
     Figure out x and y distances for each of the spacing values
     I decided to trade memory for time; I'd rather allocate
     a few dozen bytes than have to do a calculation every time
     I draw.
   */
   for (i = 0; i < spacing.length; i++)
   {
     xSpacing[i] = lerp(0, (x1 - x0), spacing[i] / distance);
     ySpacing[i] = lerp(0, (y1 - y0), spacing[i] / distance);
   }

   i = 0;
   while (drawn < distance)
   {
     if (drawLine)
     {
       line(x0, y0, x0 + xSpacing[i], y0 + ySpacing[i]);
     }
     x0 += xSpacing[i];
     y0 += ySpacing[i];
     /* Add distance "drawn" by this line or gap */
     drawn = drawn + mag(xSpacing[i], ySpacing[i]);
     i = (i + 1) % spacing.length;  // cycle through array
     drawLine = !drawLine;  // switch between dash and gap
   }
 }
}
Re: dotted or dashed lines?
Reply #5 - Jan 20th, 2010, 7:07am
 
nice. :)
note that IFF you're using the JAVA2D renderer you can also use variations on this approach:

Quote:
size(400,400,JAVA2D);
smooth();
Graphics2D g2 = ((PGraphicsJava2D)g).g2;
background(255);
stroke(0);
for (int i=0; i<19; i++) {
  int y = 20+i*20;
  // define a random dash pattern:
  int ndashsegs = (int)random(1,6);
  float [] dashsegs = new float[ndashsegs];
  for (int j=0; j<ndashsegs; j++)
    dashsegs[j] = random(2,10);
  BasicStroke bs = new BasicStroke(2.0, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, dashsegs, 0);
  // now use that dash pattern
  g2.setStroke(bs);
  line(20,y,width-20,y);
}
Page Index Toggle Pages: 1