def move(self, cur: Point2) -> None: lx, ly = project_point(self.vs.revMatrix, self.last) nx, ny = project_point(self.vs.revMatrix, cur) self.vs.translate(Vec2(nx - lx, ny - ly)) self.last = cur
def __init__(self, view, model, cmodel): self._model = model self._cmodel = cmodel self.p1_point = EditablePoint(Point2(0, 0)) rmat = rotate(self._cmodel.theta) dy = -(model.pin_count / 2 - 1) * model.pin_space v_aligned = Vec2(0, dy) v_delta = project_point(rmat, v_aligned) # the pin on the end of the same row as P1 self.p_bottom_corner = OffsetDefaultPoint(self.p1_point, v_delta) # Opposite corner point self.p_opposite = WidthProjectedPoint(self) points = [self.p1_point, self.p_bottom_corner, self.p_opposite] super(DIPEditFlow, self).__init__(view, points, True) self.update_matrix()
def other_corner_offset(): x = self._model.pin_spacing * ((self._model.side1_pins - 1) / 2 + (self._model.side3_pins - 1) / 2) y = self._model.dim_2_pincenter r = rotate(self._cmodel.theta) return project_point(r, Point2(x, y))
def event_add_keypoint(self, event: ToolActionEvent) -> None: # If we're in world view mode, we need to figure # out where this keypoint would be in image space as well if self.model.view_mode.is_aligned(): # World coords of event world = event.world_pos # Normalized image coords of event im_norm = project_point(self.model.kp.image_matrix_inv, world) # Pixel coords of event im_px = self._parent.il.n2p(im_norm) else: raise NotImplementedError("Cannot add keypoint in unaligned") # Do all ops as a single macro self._parent.undoStack.beginMacro("Add/Set Keypoint") cmd = cmd_add_keypoint(self.model.kp) self._parent.undoStack.push(cmd) # Since we added it manually, we want to use it as part of the alignment cmd2 = cmd_set_keypoint_used(self.model.kp, cmd.index, True) self._parent.undoStack.push(cmd2) # If adding a keypoint in world space, setup the im-space version as well if self.model.view_mode.is_aligned(): cmd3 = cmd_set_keypoint_px(self.model.kp, cmd.index, im_px) self._parent.undoStack.push(cmd3) # select the keypoint self.model.kp.selected_idx = cmd.index # and move it to where the click was self.do_set_cmd(event.cursor_pos, True) self._parent.undoStack.endMacro()
def p2_corner_offset(): x = self._model.pin_spacing * ((self._model.side1_pins - 1) / 2) + self._model.dim_1_pincenter / 2 y = self._model.dim_2_pincenter / 2 - ( self._model.side2_pins - 1) / 2 * self._model.pin_spacing r = rotate(self._cmodel.theta) return project_point(r, Point2(x, y))
def im2V(self, pt: Vec2) -> Vec2: """Translate Image coordinates to viewport coordinates""" if self.model_overall.view_mode.is_aligned(): ph = project_point(self.model.image_matrix, pt) return self.viewPort.tfW2V(ph) else: return self.viewPort.tfW2V(pt)
def dip_border_va(va_xy: 'VA_xy', dip: 'DIPComponent') -> None: by = dip.body_length() / 2 r = units.MM va_xy.add_box(dip.center.x, dip.center.y, dip.body_width(), dip.body_length(), dip.theta) pt_center = project_point(dip.matrix, Point2(0, by)) va_xy.add_arc(pt_center.x, pt_center.y, r, dip.theta + math.pi, dip.theta, 28)
def fit_point_cloud(self, points: List[Vec2]): new_points = [project_point(self.__rotate_flip, p) for p in points] if not new_points: return r = Rect.from_center_size(new_points.pop()) for p in new_points: r.point_merge(p) self.__fit_postrotate_rect(r)
def V2im(self, pt: Vec2) -> Vec2: """ Translate viewport coordinates to image coordinates :param pt: :return: """ world = self.viewPort.tfV2W(pt) if self.model_overall.view_mode.is_aligned(): inv = numpy.linalg.inv(self.model.image_matrix) return project_point(inv, world) else: return world
def update_matrix(self): rot = rotate(self._cmodel.theta) center_to_corner = Vec2( 0, self._model.pin_space * (self._model.pin_count - 1) / 2) center_to_corner_w = project_point(rot, center_to_corner) self._cmodel.center = self.p1_point.get() - center_to_corner_w self.matrix = translate(self._cmodel.center.x, self._cmodel.center.y).dot( rotate(self._cmodel.theta))
def smd_border_va(va_xy: 'VA_xy', smd: 'SMD4Component') -> None: va_xy.add_box(smd.center.x, smd.center.y, smd.dim_2_body, smd.dim_1_body, smd.theta) # Calculate size / position of marker scale = min(smd.dim_1_body, smd.dim_2_body) / 5 if scale > units.MM: scale = units.MM if scale < units.MM/5: scale = units.MM/5 size = scale/2 offs = scale posx = -smd.dim_2_body/2 + offs posy = smd.dim_1_body/2 - offs pt = project_point(smd.matrix, Point2(posx, posy)) va_xy.add_circle(pt.x, pt.y, size, 40)
def update_matrix(self): rot = rotate(self._cmodel.theta) sign = self.get_cur_sign() center_to_corner = Vec2( sign * self._model.pin_width / 2, self._model.pin_space * (self._model.pin_count / 2 - 1) / 2) center_to_corner_w = project_point(rot, center_to_corner) self._cmodel.center = self.p1_point.get() - center_to_corner_w self.matrix = translate(self._cmodel.center.x, self._cmodel.center.y).dot( rotate(self._cmodel.theta))
def __init__(self, parent: 'Component', pad_no: str, rel_center: Vec2, theta: float, width: float, length: float, th_diam: float = 0, side: Optional[SIDE] = None): super(Pad, self).__init__() if side is None: side = SIDE.Top assert side is not None self.parent: 'Component' = parent self.__rel_center: Vec2 = rel_center # Cached translation-only location matrix self.__translate_mat = translate(self.__rel_center.x, self.__rel_center.y) self.__theta: float = theta self.width: float = width self.length: float = length self.side: SIDE = side # Throughhole diameter, 0 if not T/H self.th_diam: float = th_diam self.pad_no: str = pad_no if self.parent is not None: pmat: 'npt.NDArray[numpy.float64]' = self.parent.matrix else: pmat = numpy.identity(3, dtype=numpy.float32) self.__pmat: 'npt.NDArray[numpy.float64]' = pmat self.center = project_point(pmat, self.__rel_center) self.layer: 'Layer' = self.parent._side_layer_oracle.stackup.layer_for_side( self.side)
def get_corner_points(self) -> List[Vec2]: # Normalized_dims max_dim = float(max(self.__cached_decode.shape)) x = self.__cached_decode.shape[1]/max_dim y = self.__cached_decode.shape[0]/max_dim corners = ( (-1, -1), (-1, 1), (1, 1), (1, -1)) # Rectangle in pixel space corners_pixspace = [ Vec2(mx * x, my * y) for mx, my in corners ] # Possibly non-rectangular corner points corners_norm = [ project_point(self.transform_matrix, p) for p in corners_pixspace ] return corners_norm
def __fit_postrotate_rect(self, rect: Rect): self.__center_point = project_point(numpy.linalg.inv(self.__rotate_flip), rect.center) self.__scale = min(self.__normal_width / rect.width, self.__normal_height / rect.height) self.__update()
def tfW2V(self, pt: Vec2) -> Vec2: return project_point(self.fwdMatrix, pt)
def tfV2W(self, pt: Vec2) -> Vec2: return project_point(self.revMatrix, pt)
def get(self): r = rotate(self.parent._cmodel.theta) cv = Vec2(-self.parent._model.dim_1_body / 2, -self.parent._model.dim_2_body / 2) return self.parent._cmodel.center + project_point(r, cv)
def set(self, val): r = rotate(-self.parent._cmodel.theta) p = project_point(r, val - self.parent._cmodel.center) self.parent._model.dim_1_body = abs(p.x) * 2 self.parent._model.dim_2_body = abs(p.y) * 2
def point_inside(self, pt: Vec2) -> int: v = pt - self.center v_in_cmp = project_point(rotate(-self.theta), v) return self.theta_bbox.point_test(v_in_cmp)
def n2p(self, pt: Vec2) -> Vec2: return project_point(self.normalized_to_pixel, pt)
def p2n(self, pt: Vec2) -> Vec2: return project_point(self.pixel_to_normalized, pt)