def test_toolbox_metal_cross(self): """ Test functionality of cross in toolbox_metal.py. """ math_and_overrides.set_decimal_precision(3) my_array_1 = np.array([3, 4]) my_array_2 = np.array([12, 14]) self.assertEqual(math_and_overrides.cross(my_array_1, my_array_2), -6)
def issideways(self, point, seg_point_a, seg_point_b): return mao.cross(point - seg_point_a, seg_point_b - seg_point_a) < 0
def adjust_length(self, delta_length, pts, start_pt: QRoutePoint, end_pt: QRoutePoint) -> np.ndarray: """ Edits meander points to redistribute the length slacks accrued with the various local adjustments It should be run after self.pts_intermediate is completely defined Inputs are however specific to the one meander segment Assumption is that pts is always a sequence of paired points, each corresponds to one meander 180deg curve The pts is typically an odd count since the last point is typically used to anchor the left-over length, therefore this code supports both odd and even cases, separately. For even it assumes all points are in paired. Args: delta_length (delta_length): slack/excess length to distribute on the pts pts (np.array): intermediate points of meander. pairs, except last point (2,2,...,2,1) start_pt (QRoutePoint): QRoutePoint of the start end_pt (QRoutePoint): QRoutePoint of the end Returns: np.ndarray: Array of points """ # the adjustment length has to be computed in the main or in other method # considering entire route (Could include the corner fillet) if len(pts) <= 3: # not a meander return pts # is it an even or odd count of points? term_point = len(pts) % 2 # recompute direction snap = is_true(self.p.snap) # snap to xy grid forward, sideways = self.get_unit_vectors(start_pt, end_pt, snap) # recompute meander_sideways if mao.cross(pts[1] - pts[0], pts[2] - pts[1]) < 0: first_meander_sideways = True else: first_meander_sideways = False if mao.cross(pts[-2 - term_point] - pts[-1 - term_point], pts[-3 - term_point] - pts[-2 - term_point]) < 0: last_meander_sideways = False else: last_meander_sideways = True # which points need to receive the shift? # 1. initialize the shift vector to 1 (1 = will receive shift) adjustment_vector = np.ones(len(pts)) # 2. switch shift direction depending on sideways or not if first_meander_sideways: adjustment_vector[2::4] *= -1 adjustment_vector[3::4] *= -1 else: adjustment_vector[::4] *= -1 adjustment_vector[1::4] *= -1 # 3. suppress shift for points that can cause short edges # calculate thresholds for suppression of short edges (short edge = not long enough for set fillet) fillet_shift = sideways * self.p.fillet start_pt_adjusted_up = start_pt.position + fillet_shift start_pt_adjusted_down = start_pt.position - fillet_shift end_pt_adjusted_up = end_pt.position + fillet_shift end_pt_adjusted_down = end_pt.position - fillet_shift # if start_pt.position is below axes + shift - 2xfillet & first_meander_sideways if first_meander_sideways and not self.issideways( start_pt_adjusted_up, pts[0], pts[1]): pass # if start_pt.position is above axes - shift + 2xfillet & not first_meander_sideways elif not first_meander_sideways and self.issideways( start_pt_adjusted_down, pts[0], pts[1]): pass else: # else block first mender adjustment_vector[:2] = [0, 0] # if end_pt.position is below axes + shift - 2xfillet & last_meander_sideways if last_meander_sideways and not self.issideways( end_pt_adjusted_up, pts[-2 - term_point], pts[-1 - term_point]): pass # if end_pt.position is above axes - shift + 2xfillet & not last_meander_sideways elif not last_meander_sideways and self.issideways( end_pt_adjusted_down, pts[-2 - term_point], pts[-1 - term_point]): pass else: # else block last mender adjustment_vector[-2 - term_point:-term_point] = [0, 0] not_a_meander = 0 if term_point: # means that pts count is a odd number # thus needs to disable shift on the termination point... adjustment_vector[-1] = 0 # ...unless the last point is anchored to the last meander curve if start_pt.direction is not None and end_pt.direction is not None: if ((mao.dot(start_pt.direction, end_pt.direction) < 0) and (mao.dot(forward, start_pt.direction) <= 0)): # pins are pointing opposite directions and diverging, thus keep consistency adjustment_vector[-1] = adjustment_vector[-2] if adjustment_vector[-1]: # the point in between needs to be shifted, but it will not contribute to length change # therefore the total length distribution (next step) should ignore it. not_a_meander = 1 # Finally, divide the slack amongst all points... sideways_adjustment = sideways * ( delta_length / (np.count_nonzero(adjustment_vector) - not_a_meander)) pts = pts + sideways_adjustment[ np.newaxis, :] * adjustment_vector[:, np.newaxis] return pts