matio2matio
matio2matio

Reputation: 303

Find the vertices of a line between two points with a given stroke width

I am currently trying to create a render of a path in clojure (although I am happy with answers in other languages if they're easy to understand). A simple explanation is that I want to draw a line between two points with a given thickness - however I only want to find vertices of the line so that I can output it to a Wavefront file (a 3d model file with the extension .obj).

So, for example given points A and B which can be joined up like so: A and B

I wish to find points A1 and B1 A1 and B1

This could also be thought of given a border to a shape. For example given A, B, C and D: Shape

I would wish to find A1, B2, C1 and D1: Shape1

The actual shape would be much more complicated however and may have a few hundred points.

My original thought was to do an enlargement from the centre of the shape with a scale factor of less than 1, like so:

(defn shrink-pos [centre-x centre-y x y]
  (let [diff-y (- y centre-y)
        diff-x (- x centre-x)
        dist   (Math/sqrt (+ (* diff-y diff-y) (* diff-x diff-x)))
        n-x    (+ centre-x (* diff-x 0.8))
        n-y    (+ centre-y (* diff-y 0.8))]
    [n-x n-y]))

Unfortunately this does not seem to work. The width of the border/stroke is not uniform and there is no border between the last point and the first which join to close the shape.

Is there a way to do this programmatically?

Upvotes: 0

Views: 481

Answers (1)

MBo
MBo

Reputation: 80187

For 'thick' line: Let's AB is vector from A to B.
ab is normalized (unit length) vector (vector normalization)
ab = normalized(AB)
p is perpendicular vector to ab

p.x = -ab.y, p.y = ab.x

needed points' coordinates:
B' = B + thickness * p
A' = A + thickness * p

For polygon offseting:
Let's two neighbour edges are AB and BC (intersecting in vertice B).
Find normalized (unit) vectors ab and cb.
Calc unit bisector vector
b = normalized(ab + cb)
Calc length of bisector segments as l=d/sin(fi)
where d is offset, and fi is angle between vectors b and ab.
It could be found as:

fi = atan2(crossproduct(b,ab), dotproduct(b,ab))

And find offset polygon vertice (for inner and outer offset polygons):

B' = B + l * b

B'' = B - l * b

P.S. Don't forget about inner polygon vertice vanishing for large offsets and weird loops for non-convex polygons

Upvotes: 2

Related Questions