def roundedRectangle(length, width, corner_radius, bit_diameter, path_ref='outside'): """ Assumes it's in INCREMENTAL MODE. Since length and width arguments are not related to any position. With path_ref='outside', the length and width define the outer boundary of the cut. With path_ref='center', the length and width define the cut path (centerline of cut) boundary. With path_ref='inside', the length and width define the inner boundary of the cut. Assumes that the bit is already in a starting position, at least X of least Y edge; path_ref is not a consideration. """ bit_radius = bit_diameter / 2.0 corner_diameter = 2 * corner_radius if corner_radius <= 0: raise ValueError('corner_radius %d must be greater than 0.' % corner_radius) if path_ref is 'outside': # TODO: check that corner_radius > bit_radius if corner_radius <= bit_radius: raise ValueError( 'corner_radius %d must be greater than bit radius %d.' % (corner_radius, bit_radius)) center_offset = corner_radius - bit_radius file_text = G.G1_X(length - corner_diameter) file_text += G.G3XY_to_INCR_FULL((center_offset, center_offset), (0, center_offset)) file_text += G.G1_Y(width - corner_diameter) file_text += G.G3XY_to_INCR_FULL((-center_offset, center_offset), (-center_offset, 0)) file_text += G.G1_X(-length + corner_diameter) file_text += G.G3XY_to_INCR_FULL((-center_offset, -center_offset), (0, -center_offset)) file_text += G.G1_Y(-width + corner_diameter) file_text += G.G3XY_to_INCR_FULL((center_offset, -center_offset), (center_offset, 0)) elif path_ref is 'center': file_text = G.G1_X(length - corner_diameter) file_text += G.G3XY_to_INCR_FULL((corner_radius, corner_radius), (0, corner_radius)) file_text += G.G1_Y(width - corner_diameter) file_text += G.G3XY_to_INCR_FULL((-corner_radius, corner_radius), (-corner_radius, 0)) file_text += G.G1_X(-length + corner_diameter) file_text += G.G3XY_to_INCR_FULL((-corner_radius, -corner_radius), (0, -corner_radius)) file_text += G.G1_Y(-width + corner_diameter) file_text += G.G3XY_to_INCR_FULL((corner_radius, -corner_radius), (corner_radius, 0)) elif path_ref is 'inside': center_offset = corner_radius + bit_radius file_text = G.G1_X(length - corner_diameter) file_text += G.G3XY_to_INCR_FULL((center_offset, center_offset), (0, center_offset)) file_text += G.G1_Y(width - corner_diameter) file_text += G.G3XY_to_INCR_FULL((-center_offset, center_offset), (-center_offset, 0)) file_text += G.G1_X(-length + corner_diameter) file_text += G.G3XY_to_INCR_FULL((-center_offset, -center_offset), (0, -center_offset)) file_text += G.G1_Y(-width + corner_diameter) file_text += G.G3XY_to_INCR_FULL((center_offset, -center_offset), (center_offset, 0)) else: raise ValueError('Invalid path reference specified: %s.' % path_ref) return file_text