Source code for pyleecan.Methods.Geometry.Arc.split_line

from numpy import exp, angle, abs as np_abs

from ....Classes.Segment import Segment
from ....definitions import PACKAGE_NAME

DELTA = 1e-7  # To remove computing/DXF noise


[docs]def split_line(self, Z1, Z2, is_join=False, prop_dict_join=None): """Cut the Arc according to a line defined by two complex "Above" is in the coordinate system with Z1 in 0 and Z2 on the X>0 axis Parameters ---------- self : Segment An Segment object Z1 : complex First point of the cutting Line Z2 : complex Second point of the cutting Line is_join : bool True to join the split_list with Segment if there is more that one remaining parts prop_dict_join : dict Property dict to set on the join line Returns ------- top_split_list, bot_split_list : ([Line], [Line]) Both part of the arc """ # Dynamic import of Arc1 to prevent import loop from code generator module = __import__(PACKAGE_NAME + ".Classes.Arc1", fromlist=["Arc1"]) Arc1 = getattr(module, "Arc1") # Get the intersection point Z_int = self.intersect_line(Z1, Z2) # Begin and end point in the line coordonate system Zb = (self.get_begin() - Z1) * exp(-1j * angle(Z2 - Z1)) Ze = (self.get_end() - Z1) * exp(-1j * angle(Z2 - Z1)) # Center of the arc (for later check) Zc = self.get_center() if len(Z_int) == 0: # No intersection copy the line line = self.copy() # Begin and end on top if Zb.imag >= 0 and Ze.imag >= 0: return [line], [] # Begin and end on bot elif Zb.imag <= 0 and Ze.imag <= 0: return [], [line] else: raise Exception("Split Arc error (case 0 int)") if len(Z_int) == 1: # One intersection => Three possible lines # Begin => Intersection line1 = Arc1( begin=self.get_begin(), end=Z_int[0], radius=self.comp_radius(), is_trigo_direction=bool(self.get_angle() > 0), ) # Fix radius if needed if ( np_abs(line1.begin - line1.end) > 1e-6 # Avoid error for center and np_abs(line1.get_center() - Zc) > 1e-6 ): line1.radius = -1 * line1.radius # Intersection => End line2 = Arc1( begin=Z_int[0], end=self.get_end(), radius=self.comp_radius(), is_trigo_direction=bool(self.get_angle() > 0), ) # Fix radius if needed if ( np_abs(line2.begin - line2.end) > 1e-6 and np_abs(line2.get_center() - Zc) > 1e-6 # Avoid error for center ): line2.radius = -1 * line2.radius # Copy of the complete line (begin or end on cutting line, or cutting line is tangent) line3 = self.copy() # If the line is tangent, begin and end are on the same side of the line if (Zb.imag > DELTA and Ze.imag > DELTA) or ( Zb.imag < -DELTA and Ze.imag < -DELTA ): # Begin (and end) on top if Zb.imag > DELTA: return [line3], [] # Begin (and end) on bot elif Zb.imag < -DELTA: return [], [line3] else: raise Exception("Split Arc error (case 1 int-Tangent)") # Return the correct line according to the points position elif Zb.imag > DELTA and abs(Ze.imag) > DELTA: # Begin on top; End!=Int return [line1], [line2] elif Zb.imag > DELTA: # Begin on top; End==Int return [line3], [] elif Zb.imag < -DELTA and abs(Ze.imag) > DELTA: # Begin on bot; End!=Int return [line2], [line1] elif Zb.imag < -DELTA: # Begin on bot; End==Int return [], [line3] # Zb.imag == 0 => begin on cutting line elif Ze.imag > DELTA: # Begin==Int, End on Top return [line3], [] elif Ze.imag < -DELTA: # Begin==Int, End on Bot return [], [line3] else: raise Exception("Split Arc error (case 1 int-Non Tangent)") elif len(Z_int) == 2: # Two intersection => Three possible lines # Begin => Intersection1 (intersection are ordered along the arc) line1 = Arc1( begin=self.get_begin(), end=Z_int[0], radius=self.comp_radius(), is_trigo_direction=bool(self.get_angle() > 0), ) # Fix radius if needed if ( np_abs(line1.begin - line1.end) > 1e-6 # Avoid error for center and np_abs(line1.get_center() - Zc) > 1e-6 ): line1.radius = -1 * line1.radius # Intersection 1 => Intersection 2 line2 = Arc1( begin=Z_int[0], end=Z_int[1], radius=self.comp_radius(), is_trigo_direction=bool(self.get_angle() > 0), ) # Fix radius if needed if ( np_abs(line2.begin - line2.end) > 1e-6 # Avoid error for center and np_abs(line2.get_center() - Zc) > 1e-6 ): line2.radius = -1 * line2.radius # Intersection 2 => End line3 = Arc1( begin=Z_int[1], end=self.get_end(), radius=self.comp_radius(), is_trigo_direction=bool(self.get_angle() > 0), ) # Fix radius if needed if ( np_abs(line3.begin - line3.end) > 1e-6 # Avoid error for center and np_abs(line3.get_center() - Zc) > 1e-6 ): line3.radius = -1 * line3.radius # Line Intersection 1 => Intersection 2 for join seg_join = Segment(begin=Z_int[0], end=Z_int[1], prop_dict=prop_dict_join) # If both intersection are Begin and end line4 = self.copy() if is_join: line_list = [line1, seg_join, line3] else: line_list = [line1, line3] if np_abs(Z_int[0] - self.get_begin()) < DELTA: # Begin==Int1 line_list.pop(0) if np_abs(Z_int[1] - self.get_end()) < DELTA: line_list.pop(-1) # If the intersetion points are begin and end if ( np_abs(Z_int[0] - self.get_begin()) < DELTA and np_abs(Z_int[1] - self.get_end()) < DELTA ): Zm = (self.get_middle() - Z1) * exp(-1j * angle(Z2 - Z1)) # begin and end are on the line => Zm.imag != 0 if Zm.imag > 0: return [line4], [] elif Zm.imag < 0: return [], [line4] else: raise Exception("Split Arc error (case 2 int-Both)") elif Zb.imag > DELTA: # Begin on top return line_list, [line2] elif Zb.imag < -DELTA: # Begin on bot return [line2], line_list elif Ze.imag > DELTA: # Begin== Int1, End on Top return line_list, [line2] elif Ze.imag < -DELTA: # Begin== Int1, End on Bot return [line2], line_list else: Exception("Split Arc error (case 2 int)")