def generate_offset_track(self, mid_track, thickness): poly_line = LinearRing(mid_track) poly_line_offset_left = poly_line.parallel_offset(thickness, side="left", resolution=16, join_style=2, mitre_limit=2) poly_line_offset_right = poly_line.parallel_offset(thickness, side="right", resolution=16, join_style=2, mitre_limit=2) offset_left_track = [] for coord in poly_line_offset_left.coords: p = [coord[0], coord[1]] offset_left_track.append(p) offset_left_track.append(offset_left_track[0]) offset_right_track = [] for coord in poly_line_offset_right.coords: p = [coord[0], coord[1]] offset_right_track.append(p) offset_right_track.append(offset_right_track[0]) return offset_left_track, offset_right_track
def offset_perimeter(geometry, offset, side='left', plot_offset=False): """Offsets the perimeter of a geometry of a :class:`~sectionproperties.pre.sections.Geometry` object by a certain distance. Note that the perimeter facet list must be entered in a consecutive order. :param geometry: Cross-section geometry object :type geometry: :class:`~sectionproperties.pre.sections.Geometry` :param float offset: Offset distance for the perimeter :param string side: Side of the perimeter offset, either 'left' or 'right'. E.g. 'left' for a counter-clockwise offsets the perimeter inwards. :param bool plot_offset: If set to True, generates a plot comparing the old and new geometry The following example 'corrodes' a 200UB25 I-section by 1.5 mm and compares a few of the section properties:: import sectionproperties.pre.sections as sections from sectionproperties.pre.offset import offset_perimeter from sectionproperties.analysis.cross_section import CrossSection # calculate original section properties original_geometry = sections.ISection(d=203, b=133, t_f=7.8, t_w=5.8, r=8.9, n_r=16) original_mesh = original_geometry.create_mesh(mesh_sizes=[3.0]) original_section = CrossSection(original_geometry, original_mesh) original_section.calculate_geometric_properties() original_area = original_section.get_area() (original_ixx, _, _) = original_section.get_ic() # calculate corroded section properties corroded_geometry = offset_perimeter(original_geometry, 1.5, plot_offset=True) corroded_mesh = corroded_geometry.create_mesh(mesh_sizes=[3.0]) corroded_section = CrossSection(corroded_geometry, corroded_mesh) corroded_section.calculate_geometric_properties() corroded_area = corroded_section.get_area() (corroded_ixx, _, _) = corroded_section.get_ic() # compare section properties print("Area reduction = {0:.2f}%".format( 100 * (original_area - corroded_area) / original_area)) print("Ixx reduction = {0:.2f}%".format( 100 *(original_ixx - corroded_ixx) / original_ixx)) The following plot is generated by the above example: .. figure:: ../images/offset_example.png :align: center :scale: 75 % 200UB25 with 1.5 mm corrosion. The following is printed to the terminal: .. code-block:: text Area reduction = 41.97% Ixx reduction = 39.20% """ # initialise perimeter points list perimeter_points = [] # add perimeter points to the list for facet_idx in geometry.perimeter: # get the facet facet = geometry.facets[facet_idx] # get the first point on the facet point = geometry.points[facet[0]] # add the (x,y) tuple to the list perimeter_points.append((point[0], point[1])) # create LinearRing object perimeter = LinearRing(perimeter_points) # offset perimeter new_perimeter = perimeter.parallel_offset(distance=offset, side=side, resolution=0, join_style=2) (new_xcoords, new_ycoords) = new_perimeter.xy # create deep copy of original geometry object new_geometry = copy.deepcopy(geometry) # replace offset points in new geometry for (i, facet_idx) in enumerate(new_geometry.perimeter): # get the facet facet = new_geometry.facets[facet_idx] # get the first point on the facet point = new_geometry.points[facet[0]] # replace the point location with the offset location point[0] = new_xcoords[i] point[1] = new_ycoords[i] if plot_offset: (_, ax) = plt.subplots() # plot new geometry for (i, f) in enumerate(new_geometry.facets): if i == 0: ax.plot([ new_geometry.points[f[0]][0], new_geometry.points[f[1]][0] ], [ new_geometry.points[f[0]][1], new_geometry.points[f[1]][1] ], 'ko-', markersize=2, label='Offset Geometry') else: ax.plot([ new_geometry.points[f[0]][0], new_geometry.points[f[1]][0] ], [ new_geometry.points[f[0]][1], new_geometry.points[f[1]][1] ], 'ko-', markersize=2) # plot the original perimeter for (i, facet_idx) in enumerate(geometry.perimeter): f = geometry.facets[facet_idx] if i == 0: ax.plot([geometry.points[f[0]][0], geometry.points[f[1]][0]], [geometry.points[f[0]][1], geometry.points[f[1]][1]], 'r--', markersize=2, label='Original Perimeter') else: ax.plot([geometry.points[f[0]][0], geometry.points[f[1]][0]], [geometry.points[f[0]][1], geometry.points[f[1]][1]], 'r--', markersize=2) ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) ax.set_title('Offset Geometry') ax.set_aspect('equal', anchor='C') plt.tight_layout() plt.show() return new_geometry