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)
示例#2
0
 def issideways(self, point, seg_point_a, seg_point_b):
     return mao.cross(point - seg_point_a, seg_point_b - seg_point_a) < 0
示例#3
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