views:

136

answers:

4

Given a series of points, how could I calculate the vector for that line 5 pixels away? Ex: Given:

   \
    \
     \

How could I find the vector for

   \  \
    \  \
     \  \

The ones on the right.

I'm trying to figure out how programs like Flash can make thick outlines.

Thanks

+1  A: 

The way to do with a straight line is to find the line perpendicular (N) to the original line, take a 5 pixels step in that direction and then find the perpendicular to the perpendicular in that point

  |     |
--+-----+---N
  |     |
  |     |

The way to do it with a non straight line is to approximate it with many straight lines or if you have the analytic representation of the line, to find some sort of analytic solution in a similar manner to the one of the straight line.

shoosh
+7  A: 

A thick line is a polygon. (Let's forget about antialiasing for now)

picture

start = line start = vector(x1, y1)
end = line end = vector(x2, y2)
dir = line direction = end - start = vector(x2-x1, y2-y1)
ndir = normalized direction = dir*1.0/length(dir)
perp = perpendicular to direction = vector(dir.x, -dir.y)
nperp = normalized perpendicular = perp*1.0/length(perp)

perpoffset = nperp*w*0.5
diroffset = ndir*w*0.5

(You can easily remove one normalization and calculate one of the offsets by taking perpendicular from the other)

p0, p1, p2, p3 = polygon points:
p0 = start + perpoffset - diroffset
p1 = start - perpoffset - diroffset
p2 = end + perpoffset + diroffset
p3 = end - perpoffset + diroffset

P.S. You're the last person I ever going to explain this stuff to. Things like these should be understood on intuitive level.

SigTerm
+1 for the pretty graphics.
Thomas Matthews
+1! Great answer.
Alerty
Thank you very much, I really appreciate this explanation, despite taking Alegebra 1 and 2 and Physics in high school I still have trouble with these things...
Milo
A: 

You will need to have some math background.

Start by understanding the line (linear equations and linear functions) what is a parallel and benefit from looking up geometric transformations.

After that you will understand SigTerm's answer...

Panic
+1  A: 

Try this untested pseudo-code:

# Calculate the "Rise" and "run" (slope) of your input line, then 
# call this function, which returns offsets of x- and y-intercept
# for the parallel line.  Obviously the slope of the parallel line
# is already known: rise/run.

# returns (delta_x, delta_y) to be added to intercepts.  
adjacent_parallel(rise, run, distance, other_side):
    negate = other_side ? -1 : 1
    if rise == 0:
        # horizontal line; parallel is vertically away
        return (0, negate * distance)
    elif run == 0:
        # vertical line; parallel is horizontally away
        return (negate * distance, 0)
    else:
        # a perpendicular radius is - run / rise slope with length
        # run^2 + rize^2 = length  ^ 2
        nrml = sqrt(run*run + rise*rise)
        return (negate * -1 * run / nrml, negate * rise/nrml)

As SigTerm shows in his nice diagram, you will want to get the lines on either side of the intended line: so pass in thickness/2 for distance and call twice, once with other_side=true, and draw a thickness centered on the 'abstract line'.

Heath Hunnicutt