def Offset(self, leftwards_value): save_curve = copy.deepcopy(self) # try offsetting with Geoff's method if self._Offset(leftwards_value): return True if self.IsClosed() == False: return False # use clipper to offset the closed curve inwards_offset = leftwards_value cw = False if self.IsClockwise(): inwards_offset = -inwards_offset cw = True a = geom.Area() a.Append(self) a.Offset(inwards_value) if len(a.curves) == 1: start_span = None if len(self.vertices) > 1: start_span = geom.Span(self.vertices[0].p, self.vertices[1], True) self.vertices = copy.deepcopy(a.curves[0].vertices) if self.IsClockwise() != cw: self.Reverse() if start_span: forward = start_span.GetVector(0.0) left = ~forward offset_start = start_span.p + left * leftwards_value self.ChangeStart(self.NearestPointToPoint(offset_start)) return True return False
def GetUnitizedSectionPoints(self, tip_fraction): # the start point will be geom.Point(0,0) and the last point will be geom.Point(1,0) pts = [] if self.curves[2] and self.curves[3]: perim = self.curves[2].Perim() cur_perim = 0.0 prev_v = None for v in self.curves[2].GetVertices(): if prev_v != None: span = geom.Span(prev_v.p, v, False) cur_perim += span.Length() fraction = cur_perim / perim root_point = GetUnitizedPoint( self.curves[2], fraction, self.root_profile_invtm, self.values['centre_straight'] and (tip_fraction < 0.01)) if root_point == None: return tip_point = GetUnitizedPoint( self.curves[3], fraction, self.tip_profile_invtm, self.values['centre_straight'] and (tip_fraction < 0.01)) if tip_point == None: return vec = tip_point - root_point p = root_point + vec * tip_fraction pts.append(p) prev_v = v return pts
def GetSpans(self): spans = [] prev_p = None for vertex in self.vertices: if prev_p: spans.append(geom.Span(prev_p, vertex)) prev_p = vertex.p return spans
def NearestPointToPoint(self, p): best_point = None prev_p = None first_span = True for vertex in self.vertices: if prev_p: near_point = geom.Span(prev_p, vertex, first_span).NearestPointToPoint(p) first_span = False dist = near_point.Dist(p) if (best_point == None or dist < best_dist): best_dist = dist best_point = near_point prev_p = vertex.p return best_point
def calculate_span_cylinders(self, span, color): sz = span.p.y * toolpath.coords.voxels_per_mm ez = span.v.p.y * toolpath.coords.voxels_per_mm z = sz while z < ez: # make a line at this z intersection_line = area.Span( area.Point(0, z), area.Vertex(0, area.Point(300, z), area.Point(0, 0)), False) intersections = span.Intersect(intersection_line) if len(intersections): radius = intersections[0].x * toolpath.coords.voxels_per_mm self.cylinders.append( VoxelCyl(radius, z * toolpath.coords.voxels_per_mm, color)) z += 1 / toolpath.coords.voxels_per_mm
def _DoesIntersInterfere(pInt, k, leftwards_value): # check that intersections don't interfere with the original kurve sp = geom.Span() kCheckVertex = 0 sp.p0 = k.vertices[kCheckVertex].p kCheckVertex += 1 offset = fabs(leftwards_value) - geom.tolerance while kCheckVertex < len(k.vertices): sp.v = k.vertices[kCheckVertex] kCheckVertex += 1 # check for interference np = sp.NearestPointToPoint(pInt) if np.Dist(pInt) < offset: return True sp.p = sp.v.p return False # intersection is ok
def GetLastSpan(self): if len(self.vertices) < 2: return None return geom.Span(self.vertices[-2].p, self.vertices[-1].p)
def GetFirstSpan(self): if len(self.vertices) < 2: return None return geom.Span(self.vertices[0].p, self.vertices[1].p)
def _EliminateLoops(self, leftwards_value): new_vertices = [] kinVertex = 0 spans = self.GetSpans() sp0 = geom.Span(geom.Point(0, 0), geom.Point(0, 0)) sp1 = geom.Span(geom.Point(0, 0), geom.Point(0, 0)) while (kinVertex < len(self.vertices)): clipped = False sp0.p = self.vertices[kinVertex].p kinVertex += 1 if kinVertex == 1: new_vertices.append( geom.Vertex(sp0.p) ) # start point mustn't dissappear for this simple method if kinVertex < len(self.vertices): ksaveVertex = kinVertex sp0.v = self.vertices[kinVertex] kinVertex += 1 ksaveVertex1 = kinVertex if kinVertex < len(self.vertices): sp1.p = self.vertices[kinVertex].p kinVertex += 1 ksaveVertex2 = kinVertex fwdCount = 0 while (kinVertex < len(self.vertices)): sp1.v = self.vertices[kinVertex] kinVertex += 1 intersections = sp0.Intersect(sp1) if (len(intersections) > 0) and (sp0.p.Dist( intersections[0]) < geom.tolerance): intersections = [] if len(intersections) > 0: if len(intersections) == 2: # choose first intercept on sp0 intersections.pop() ksaveVertex = ksaveVertex1 clipped = True # in a clipped section if self._DoesIntersInterfere( intersection[0], self, leftwards_value): sp0.v.p = intersections[ 0] # ok so truncate this span to the intersection clipped = False # end of clipped section break # no valid intersection found so carry on sp1.p = sp1.v.p # next ksaveVertex1 = ksaveVertex2 ksaveVertex2 = kinVertex fwdCount += 1 if ((kinVertex > len(self.vertices) + 1) or fwdCount > 25) and clipped == False: break if clipped: # still in a clipped section - error return False print('adding ' + str(sp0.v)) new_vertices.append(sp0.v) kinVertex = ksaveVertex # no more spans - seems ok self.vertices = new_vertices return True