def align( self, target_handle: str, target_rect: VirtualObj = None, ref_rect: VirtualObj = None, ref_handle: str = None, align_opt: Tuple[bool, bool] = (True, True), offset: coord_type = (0, 0) ) -> 'VirtualInst': """ Moves the instance to co-locate target rect handle and reference rect handle """ if target_rect is None: # If an explicit target is not provided, assume that the boundary should be used target_rect = self.loc['bnd'] if (target_handle in VirtualInst.edges) or (ref_handle in VirtualInst.edges): # If you provided an edge handle instead of a corner handle throw an error ValueError('Please use the align_edge method to align edges') if (ref_rect is not None) and (ref_handle in ref_rect.loc): # if a reference rectangle and handle are provided diff = target_rect.loc[target_handle] - ref_rect.loc[ref_handle] diff -= XY(offset) else: # otherwise align only to offset coordinates diff = target_rect.loc[target_handle] - XY(offset) # if the corresponding align opt is true, shift the origin appropriately if align_opt[0]: self.origin.x -= diff.x if align_opt[1]: self.origin.y -= diff.y # Update locations self.export_locations() return self
def get_track(self, num) -> XY: """ Returns [x, y] coordinates of desired track # """ distance = self.spacing * num if self.dim is 'x': return XY([self.origin + distance, 0]) elif self.dim is 'y': return XY([0, self.origin + distance])
def get_midpoint(self, handle: str, coord: coord_type) -> coord_type: """ Gets the midpoint between a location on this rectangle and another coordinate """ my_loc = self.loc[handle] their_loc = XY(coord) mid_x = (my_loc.x + their_loc.x) / 2 mid_y = (my_loc.y + their_loc.y) / 2 return XY([mid_x, mid_y])
def shift_origin(self, origin=None, orient=None) -> 'VirtualInst': """ Moves the instance origin to the provided coordinates and performs transformation""" if origin is not None: new_origin = self.origin + XY(origin) self.move(new_origin, orient) # Move the block else: self.move(origin) return self
def __init__(self, name, layer, xy, res=.001 # type: float ): VirtualObj.__init__(self) # Set the resolution of the grid self._res = res self._xy = XY(xy) self._name = name self._layer = layer
def update_dict(self): """ Updates the location dictionary based on the current ll and ur coordinates """ self.loc = { 'll': self.ll, 'ur': self.ur, 'ul': XY([self.ll.x, self.ur.y]), 'lr': XY([self.ur.x, self.ll.y]), 'l': self.ll.x, 'r': self.ur.x, 't': self.ur.y, 'b': self.ll.y, 'cl': XY([self.ll.x, .5 * (self.ur.y + self.ll.y)]), 'cr': XY([self.ur.x, .5 * (self.ur.y + self.ll.y)]), 'ct': XY([.5 * (self.ll.x + self.ur.x), self.ur.y]), 'cb': XY([.5 * (self.ll.x + self.ur.x), self.ll.y]), 'c': XY([.5 * (self.ll.x + self.ur.x), .5 * (self.ur.y + self.ll.y)]) }
def shift_origin(self, origin=(0, 0), orient='R0'): transform = Mt(orient) # Convert the rotation string to a matrix transformation # Apply the transformation to the coordinate new_xy = np.transpose(np.matmul(transform, np.transpose(np.asarray(self.xy)))) # Convert to XY coordinates and return shifted coordinate return XY(new_xy) + XY(origin)
def ur(self, xy): self._ur = XY(xy)
def ll(self, xy): self._ll = XY(xy)
def origin(self, xy: coord_type) -> None: self._origin = XY(xy) # feed it into XY class to check/condition input