UPDATE: My code here has a bug. Mr. Rafsanjani corrected it in the comments. Please refer to them below. Apologies - this blog is for beginners and for learning, so I've left the original code and the comment as is. CBT 21NOV2014
I had previously done a series of posts on polygon offset intended as a practical guide for accomplishing the task quickly. Some kind folks pointed out that I was making things considerably harder than necessary by using trigonometric functions when vector math would be easier and less error prone.
A coworker lent me his Java code that does polygon offset. I translated it into python (2.5) using the pyeuclid module:
import euclid as eu
OFFSET = 0.15
# PT 1
MONASTERY = [(1.1, 0.75),
# PT 2
. . .
# PT 21
def scaleadd(origin, offset, vectorx):
From a vector representing the origin,
a scalar offset, and a vector, returns
a Vector3 object representing a point
offset from the origin.
(Multiply vectorx by offset and add to origin.)
multx = vectorx * offset
return multx + origin
def getinsetpoint(pt1, pt2, pt3):
Given three points that form a corner (pt1, pt2, pt3),
returns a point offset distance OFFSET to the right
of the path formed by pt1-pt2-pt3.
pt1, pt2, and pt3 are two tuples.
Returns a Vector3 object.
origin = eu.Vector3(pt2, pt2, 0.0)
v1 = eu.Vector3(pt1 - pt2,
pt1 - pt2, 0.0)
v2 = eu.Vector3(pt3 - pt2,
pt3 - pt2, 0.0)
v3 = copy.copy(v1)
v1 = v1.cross(v2)
v3 += v2
if v1.z < 0.0:
retval = scaleadd(origin, -OFFSET, v3)
retval = scaleadd(origin, OFFSET, v3)
polyinset = 
lenpolygon = len(MONASTERY)
i = 0
poly = MONASTERY
while i < lenpolygon - 2:
poly[i + 1], poly[i + 2]))
i += 1