def offsetPolyline(_polylineGUID, _offsetDistance): # works for CONVEX # offset direction is inwards # parameters: # _polylineGUID # _offsetDistance # # version: 2012/07/05A name = "offsetPolyline" debug = False # EVALUATION doc = scriptcontext.doc obj = doc.Objects.Find(_polylineGUID) if obj == None: print(name + ": No Object") crv = obj.CurveGeometry if not crv.IsPolyline(): print(name + ": Curve is not polyline") return None if not crv.IsClosed: print(name + ": Curve is not closed") d = crv.PointAtEnd.DistanceTo(crv.PointAtStart) return None L = [] pts= rs.CurvePoints(_polylineGUID) for i in range((len(pts)-1)): #print("") iP = (i-1) % (len(pts)-1) iC = (i+1) % (len(pts)-1) iN = (i+2) % (len(pts)-1) #print(str(iP) + " " + str(i) + " " + str(iC)+ " " + str(iN)) v1 = rs.VectorCreate(pts[iP], pts[i]) v2 = rs.VectorCreate(pts[iN], pts[iC]) a1 = rs.VectorAngle(v1,v2) a2 = rs.VectorAngle(rs.VectorReverse(v1),v2) if a1 < a2: if debug: print(str(a1) + " < " + str(a2)) # use first else: v1 = rs.VectorReverse(v1) if debug: print(str(a2) + " < " + str(a1)) # use second v = ((v1[0] + v2[0])/2, (v1[1] + v2[1])/2,(v1[2] + v2[2])/2) vY = rs.VectorUnitize(v) vX = rs.VectorCreate(pts[i], pts[iC]) vZ= rs.VectorCrossProduct(vX, vY) ptMid = ((pts[i][0] + pts[iC][0])/2, (pts[i][1] + pts[iC][1])/2, (pts[i][2] + pts[iC][2])/2) p = rs.PlaneFromNormal(ptMid, vZ, vX) #DEBUG if debug: Draw.drawPalneAxeAndArrows(p, _offsetDistance) # make sure green arrawsa are pointing inwards ptA = movePoint(pts[i], rs.VectorScale( rs.VectorUnitize( p[2] ), _offsetDistance)) ptB = movePoint(pts[iC], rs.VectorScale( rs.VectorUnitize( p[2] ), _offsetDistance)) ln = rs.AddLine(ptA, ptB) L.append(ln) P = [] for i in range(len(L)): lineAPts = lineEndPoints(L[i]) lineBPts = lineEndPoints(L[(i+1) % len(L)]) intersection = rs.LineLineIntersection((lineAPts[0], lineAPts[1]), (lineBPts[0],lineBPts[1])) ptI = intersection[0] P.append(ptI) rs.DeleteObjects(L) P.append(P[0]) return rs.AddPolyline(P)