2
\$\begingroup\$

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
            line.graphics.lineTo(currentX + addX, currentY + addY);
        }

        // add next dash's length to current cursor position
        currentX += addX;
        currentY += addY;

        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.

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

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)

enter image description here

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.

\$\endgroup\$
6
  • \$\begingroup\$ This is a great solution, but I'm afraid line vectors aren't available to me. \$\endgroup\$
    – Gagege
    Dec 7, 2012 at 18:06
  • \$\begingroup\$ @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 ) \$\endgroup\$
    – Sidar
    Dec 7, 2012 at 18:09
  • \$\begingroup\$ 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. \$\endgroup\$
    – Gagege
    Dec 7, 2012 at 18:12
  • \$\begingroup\$ 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. \$\endgroup\$
    – House
    Dec 7, 2012 at 18:14
  • \$\begingroup\$ But wouldn't line lineVec.scale be scaling the line? \$\endgroup\$
    – Gagege
    Dec 7, 2012 at 18:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .