# How do I draw a dotted or dashed line?

I'm trying to draw a dashed or dotted line by placing individual segments(dashes) along a path and then separating them. The only algorithm I could come up with for this gave me a dash length that was variable based on the angle of the line. Like this:

private function createDashedLine(fromX:Float, fromY:Float, toX:Float, toY:Float):Sprite
{
var line = new Sprite();
var currentX = fromX;
var currentY = fromY;
var addX = (toX - fromX) * 0.0075;
var addY = (toY - fromY) * 0.0075;
line.graphics.lineStyle(1, 0xFFFFFF);

var count = 0;

// while line is not complete
while (!lineAtDestination(fromX, fromY, toX, toY, currentX, currentY))
{
/// move line draw cursor to beginning of next dash
line.graphics.moveTo(currentX, currentY);

// if dash is even
if (count % 2 == 0)
{
// draw the dash
}

// add next dash's length to current cursor position

count++;
}
return line;
}


This just happens to be written in Haxe, but the solution should be language neutral. What I would like is for the dash length to be the same no matter what angle the line is. As is, it's just adding 75 thousandths of the line length to the x and y, so if the line is and a 45 degree angle you get pretty much a solid line. If the line is at something shallow like 85 degrees then you get a nice looking dashed line. So, the dash length is variable, and I don't want that. How would I make a function that I can pass a "dash length" into and get that length of dash, no matter what the angle is?

If you need to completely disregard my code, be my guest. I'm sure there's a better solution.

EDIT: To clarify, I can't use vectors (unless they're easy to implement, I'm not even sure how vec2 works) also I'd like the dash length to be based on neither line rotation NOR line length. So, no scaling the line to get the dash length.

I would generate such a dashed line with two vectors.

First create a normalized vector that indicates the direction of your line.

vec2 lineVec = vec2(toX-fromX, toY-fromY)


Then split that into two scaled vectors to represent the visible part of the line and the gaps.

vec2 dashVec = lineVec.scale(lineSize)
vec2 gapVec = lineVec.scale(gapSize)


Then simply alternate between the two as you step out creating vertices along the way.

length = 0
position = lineStartPosition

while(length < maxLength)
addVertex(position) //start of dash and end of gap
position += dashVec //space out the dash
addVertex(position) //end of dash and begining of gap
position += gapVec //space out the gap
length += dashVec.length + gapVec.length
addVertex(position) //to cap off the line


You may want to check the end position more accurately, since this can easily go over the maximum length. In theory (if I'm not missing something) this would give you equal length lines no matter the rotation.

• This is a great solution, but I'm afraid line vectors aren't available to me. – Gagege Dec 7 '12 at 18:06
• @Gagege, It's just a 2D vector. You could write your own or just download a vector2D class ( you could also use the vector3D with the z component always 0, assuming you're using AS3 ) – Sidar Dec 7 '12 at 18:09
• Thanks! I just found Vector3D in Haxe's API documentation. That will work. Now I'm trying to figure out how to not have the dash length be based on the line length. I'd like the dashes to be consistent even with different line lengths. I can probably figure that part out though. – Gagege Dec 7 '12 at 18:12
• With this solution the dash length is not based on the length of the line. See lineSize and gapSize, those are just floats the represent the size of each. – MichaelHouse Dec 7 '12 at 18:14
• But wouldn't line lineVec.scale be scaling the line? – Gagege Dec 7 '12 at 18:14