Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw an outline around any line

enter image description here

So I have a arbitary line (See an example shown in fig 1) made up of n points

I want to draw an outline around this line (see fig 2) so I need to calculate the points of the surrounding polygon.

I started by performing a dilation on the line but this wont work - see figure 3

Any suggestions on how to do this?

I suspect calculating the normal of each line segment for use in translating the new line below and a new line above its current position and then extending each new line to infinity and defining the points as the intersections?

like image 544
iasksillyquestions Avatar asked Apr 12 '11 21:04

iasksillyquestions


2 Answers

First duplicate each line twice, once on each side at a distance of half the width you want from each original line. That gives you the green lines in the image. Then you need to visit them in order (numbered) and deal with the loose ends.

line outlining

When the lines don't meet (2-3, 6-7 and 12-13) you add a line join (in blue). A line join can be a bevel join (2-3) by just connecting the points, or a miter join by extending the lines until they meet (6-7) or a round join by making a curve.

When the lines do meet, just take the intersection point (blue dots).

At the line ends, you need to add an end cap (also in blue). An end cap can be a butt cap (8-9) by connecting the points, a projecting cap (1-16) by extending the lines a little before connecting them, or a round cap (not shown).

The end result is a polygon (or path if it includes round joins) that you can then stroke or fill.

like image 64
xan Avatar answered Oct 08 '22 16:10

xan


I have figured out a way to calculate the outline points of a line. For each point of the original line you will have to compute 2 points for the outline:

  1. for each line segment of the original line (between 2 points) you have to compute its normal vector (red)
  2. for each point, add the normals of the previous and next line segment. This produces a new vector (green)
  3. divide the new vector with the value: kl+1 , where kl is the dot product of the normal vectors. You'll get the blue vector. Then add this vector on the current point and its opposite vector and you'll get the 2 outline points for the current point

The colors above correspond to this image. enter image description here

I have programmed this function in C, but I used Accelerate Framework so it's not very easy to read. You can find the source code here and a video running the demo here.

like image 25
Petrakeas Avatar answered Oct 08 '22 15:10

Petrakeas