Algorithm to generate parallel path inside polygon

algorithms

A path is defined as a list of 2D points (x,y) (and may be open or closed).

Given a path p, what is an algorithm which generates a path p' which is "inside" p and at constant offset to p i.e. each line segment of p' is parallel to the corresponding line segment of p.

Best Answer

Well, this turns out to be non-trivial extension of Veldaeven's solution.

For each sequence of 3 points, calculate the 2 vectors between them, as suggested by Veldaeven.

Find the angle between the two vectors by adding the angles from the x axis - (nb do not use dot product which always returns an angle less than pi and hence is too symmetrical for our problem).

Halve this angle. This is the perpendicular bisector along which the resulting vector will lie.

Now to calculate which quadrant to draw the point in (the "which side" problem). Find the difference between the 2 vectors. If the gradient of this (i.e. the "double derivative") is positive then the path is going back on itself through a maximum: add pi/2. If the gradient is negative, the path is going through a minimum: subtract pi / 2

innerWallClockwise :: Float -> V2 Float -> [Point V2 Float] -> [V2 Float]

innerWallClockwise w acc (p : p' : p'' : ps) = 

 let v = p' .-. p
  v' = p'' .-. p'
  d2v = v' .-. v
  phi = atan2 (v ^. _y) (v ^. _x)
  rho = atan2 (v' ^. _y) (v' ^. _x)
  theta = phi + rho
  d2vtheta = atan2 (d2v ^. _y) (d2v ^. _x)

  theta' = theta / 2 + if d2vtheta > 0 then pi / 2 else (-1) * pi / 2
  v''' = w *^ angle theta'
  v'''' = acc .+^ v'''
in
  if ps == [] then [v''''] else v'''' : (innerWallClockwise w (acc .+^ v') (p' : p'' : (head ps) : (tail ps)))

Let's give it a simple rectangular path

let path=[P (V2 0 0), P(V2 0 5), P(V2 5 5), P (V2 5 (-5)), P (V2 0 (-5))]

Try out our function:

innerWallClockwise 1 (V2 0 5) path

=> [V2 0.70710677 4.2928934,V2 4.2928934 4.2928934,V2 4.2928934 (-4.2928934)]

Yes, the points are all inside the input path at a distance of sqrt(2) from the vertex.

NB all methods using e.g. the cross product of the two vectors are too symmetrical.

Hopefully this will help someone in the future.

Related Topic