def getFacets(p1,p2, curve): if p2.x == p1.x: leveling_angle = math.radians(90) else: leveling_angle = -math.atan((p2.y-p1.y)/(p2.x-p1.x)) p1p = p1#rotate(p1, leveling_angle, origin=p1, use_radians=True) p2p = affinity.rotate(p2, leveling_angle, origin=p1, use_radians=True) # rotate p2 around p1, so they lie on a horizontal line. Finding the center is easier this way. l = (p2p.x-p1p.x)/2 # half the distance between the points. h = l/math.tan(-curve/2) # compute the distance to the center of the circle # from the line connecting the two points. cp = shapes.Point(p1p.x + l, p1p.y-h) # the center of the (rotated) circle. c = affinity.rotate(cp, -leveling_angle, origin=p1, use_radians=True) # unrotate the circle to get the center of the original circle. # how man line segments to use to approximate the curve. Bound the angle between consecutive segments to 5 degrees. ALways have at least 10 segments. facets = max(10, int(math.ceil(abs(curve)/5))) points = [] t = p1 for i in range(1,facets + 2): # Generate the segments by rotating p1 # around the center a little bit at a time. points.append(t) t = affinity.rotate(t, curve/facets, origin=c, use_radians=True) return points
def saveR(rectangles, A, cc, n): zona = takeZona(n) polis =[] for r in rectangles: polis.append(r[0]) union = affinity.rotate(cascaded_union(polis), -A, origin=cc) dx = union.centroid.x-cc.x dy = union.centroid.y-cc.y print 'translate : ',dx, dy data2save=() for r in rectangles: rotated=affinity.rotate(r[0], -A, origin=cc) translated = affinity.translate(rotated, -dx, -dy) #verificar si interseca print zona.intersects(translated) if zona.intersects(translated): data = (n, A, r[1], r[2], "SRID=25831;"+str(translated)) data2save += (data,) #print data conn = db.connect(rootData) c = conn.cursor() c.executemany('''insert into elementsdiv ( name, ang, x, y, geometry ) values ( ?, ?, ?,?, GeomFromEWKT( ? ) )''', data2save ) conn.commit() conn.close() return
def min_bounding_box(p): ''' return the minimum-area bounding box (any orientation) of a convex polygon p.''' def rotate_points(pts, theta): R = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]]) return np.dot(R, pts.T).T def bbox_area(pts): min_pts = pts.min(axis=0) max_pts = pts.max(axis=0) return np.product(max_pts - min_pts) edges = np.diff(np.array(p.boundary), axis=0) angles = np.arctan2(edges[:,1], edges[:,0]) # polar angles of each edge in p zero_pt = (0,0) pts = np.array(p.boundary) '''Minimum-area bounding box of cvx poly must be aligned with an edge. So rotate polygon by negative polar angle, fit axis-aligned bbox, repeat and choose box with minimum area''' min_area = np.inf for angle in angles: pts_rot = rotate_points(pts, -angle) area = bbox_area(pts_rot) if area < min_area: min_area = bbox_area(pts_rot) min_angle = angle p_rot = affinity.rotate(p, -min_angle, origin=zero_pt, use_radians=True) return affinity.rotate(p_rot.envelope, min_angle, origin=zero_pt, use_radians=True), min_angle
def perpendicular_at(line, point, length): """ line: a linestring point: a point within the line at which to search for a perpendicular line length: length of the line """ point = asPoint(point) E = 1e-8 if line.intersects(point): refpoint = point else: r = 16 while True: refpoint = point.buffer(line.distance(point)+E, resolution=r).exterior.intersection(line) if not refpoint.is_empty: break else: r = r * 2 assert not refpoint.is_empty a = line_angle_at(line, refpoint) a2 = a + pi/2 p2 = Point(point.x, point.y + length*0.5) p3 = rotate(p2, -math.degrees(a2), origin=point) p4 = rotate(p2, (180 - math.degrees(a2)), origin=point) l = linestr(p3, p4) return l
def generate_patterns(depths): cuts_n = list(generate_cuts(depths)) cuts_e = [rotate(x, 90) for x in cuts_n] cuts_s = [rotate(x, 180) for x in cuts_n] cuts_w = [rotate(x, 270) for x in cuts_n] for cut_n, cut_e, cut_s, cut_w in product(cuts_n, cuts_e, cuts_s, cuts_w): poly = cut_n.union(cut_e).union(cut_s).union(cut_w) yield poly
def plot_arrow(color, center_line, dist, normalized=False): ARROW_LENGTH = 3.0 origin_p = center_line.interpolate(dist, normalized=normalized) normal_line = get_normal_to_line(center_line, dist, normalized=normalized) half_arrow = extend_line(normal_line, ARROW_LENGTH - normal_line.length, direction="forward") half_arrow = affinity.rotate(half_arrow, -55.0, origin=origin_p) plot_line(color, half_arrow) half_arrow = affinity.rotate(half_arrow, -70.0, origin=origin_p) plot_line(color, half_arrow)
def generate_panels(wafer_size): panels0 = SectorGenerator(wafer_size*sqrt3o2)(Point(0,wafer_size*sqrt3o2*2)) panels = [] panels.append(panels0) panels.append([rotate(panel, 60, origin=(0,0)) for panel in panels0]) panels.append([rotate(panel, 120, origin=(0,0)) for panel in panels0]) panels.append([rotate(panel, 180, origin=(0,0)) for panel in panels0]) panels.append([rotate(panel, 240, origin=(0,0)) for panel in panels0]) panels.append([rotate(panel, 300, origin=(0,0)) for panel in panels0]) return panels
def generate_panels_test(wafer_size, panel_list): panels0 = SectorGeneratorTest(wafer_size*sqrt3o2, panel_list)(Point(0,0)) panels = [] panels.append(panels0) panels.append([rotate(panel, 60, origin=(0,0)) for panel in panels0]) panels.append([rotate(panel, 120, origin=(0,0)) for panel in panels0]) panels.append([rotate(panel, 180, origin=(0,0)) for panel in panels0]) panels.append([rotate(panel, 240, origin=(0,0)) for panel in panels0]) panels.append([rotate(panel, 300, origin=(0,0)) for panel in panels0]) return panels
def _crop_after_rotation(im, angle, xres, yres, surroundings): """Crop image to the bounding box of bite's surroundings. Arguments: im: PIL.Image, rotated map part angle: by which the map has been rotated, in degrees (counterclockwise) xres: width of one tile in pixels yres: height of one tile in pixels surroundings: shapely.geometry.polygon.Polygon """ #before rotation x1, y1, x2, y2 = surroundings.bounds old_bb_upper_left = Point(x1, y1) old_bb_upper_right = Point(x2, y1) old_bb_bottom_left = Point(x1, y2) old_bb_center = ((x1+x2)/2, (y1+y2)/2) #shapely y-axis goes upwards shapely_angle = -angle #after rotation x1, y1, x2, y2 = affinity.rotate(surroundings, shapely_angle, origin=old_bb_center).bounds crop_upper_left = Point(x1, y1) crop_width = x2 - x1 crop_height = y2 - y1 #points where old bounding box of surroundings (i.e. the old image) touches #its bounding box after rotation tl = None #touch at the left side of the new bounding box tt = None #touch at the top side of the new bounding box if angle > 0: tl = affinity.rotate(old_bb_upper_left, shapely_angle, origin=old_bb_center) tt = affinity.rotate(old_bb_upper_right, shapely_angle, origin=old_bb_center) else: tl = affinity.rotate(old_bb_bottom_left, shapely_angle, origin=old_bb_center) tt = affinity.rotate(old_bb_upper_left, shapely_angle, origin=old_bb_center) #upper left corner of ther new bounding box new_bb_upper_left = Point(tl.x, tt.y) #from these we get b: upper left corner of the crop area relative to new_bb_upper_left b = (crop_upper_left.x - new_bb_upper_left.x, crop_upper_left.y - new_bb_upper_left.y) #crop rectangle in pixels relative to new_bb_upper_left crop_box = [int(x) for x in [ b[0] * xres, b[1] * yres, (b[0] + crop_width) * xres, (b[1] + crop_height) * yres ]] cropped = im.crop(box=crop_box) cropped.load() return cropped
def generate_sectors(full_layer, wafer_size): sector = Polygon([(0,0)]+list(full_layer.exterior.coords)[:2]) sector = shift_point(sector, 0, (0,wafer_size*sqrt3o2)) sector = shift_point(sector, 1, (0,wafer_size*sqrt3o2)) sectors = [sector] sectors.append(rotate(sector, 60, origin=(0,0))) sectors.append(rotate(sector, 120, origin=(0,0))) sectors.append(rotate(sector, 180, origin=(0,0))) sectors.append(rotate(sector, 240, origin=(0,0))) sectors.append(rotate(sector, 300, origin=(0,0))) return sectors
def __init__(self, hexagon_size, length=3, width=2): v0 = Point((0,0)) v1 = Point((0,hexagon_size*(length-1))) v2 = Point((0,hexagon_size*(length+width-2))) v2 = rotate(v2, 120, origin=v1) v3 = Point((0,hexagon_size*(width-1))) v3 = rotate(v3, 120, origin=v0) self._vertices = [(v0.x,v0.y),(v1.x,v1.y),(v2.x,v2.y),(v3.x,v3.y)] # create mirrored panel v2_mirror = rotate(v2, -240, origin=v1) v3_mirror = rotate(v3, -240, origin=v0) self._vertices_mirror = [(v2_mirror.x,v2_mirror.y),(v3_mirror.x,v3_mirror.y),(v0.x,v0.y),(v1.x,v1.y)]
def findMinCv(name, polygon): bb = polygon.bounds ang = 0 refarea = Bounds(polygon).area cc=polygon.centroid for p in range(len(polygon.exterior.coords[:])-1): angle = getAngle(polygon.exterior.coords[p], polygon.exterior.coords[p+1]) rPolygon= affinity.rotate(polygon, angle, origin=cc) if Bounds(rPolygon).area < refarea: ang = angle bbx = affinity.rotate(Bounds(rPolygon), (360-angle), origin = cc) #bbx = affinity.rotate(Bounds(rPolygon), (angle), origin = cc) return (bbx, ang)
def cov_trans_and_rotate(p, obst_cov): ''' do cov transform as above, fit minimum bounding box, then rotate so bbox is axis-aligned ''' p_w, W = cov_transform(p, obst_cov) bbox, bbox_angle = min_bounding_box(p_w) p_rw = affinity.rotate(p_w, -bbox_angle, origin=(0,0), use_radians=True) bbox_r = affinity.rotate(bbox, -bbox_angle, origin=(0,0), use_radians=True) theta = -bbox_angle R = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]]) return p_rw, bbox_r, np.dot(R,W)
def rotate(self, polygon, angle, refpoint=Point()): """ rotate polygon around ref point :param polygon: :param angle: in degree :param point: :return: """ if refpoint.is_empty: refpoint = polygon.centroid return affinity.rotate(polygon, angle, refpoint) else: return affinity.rotate(polygon, angle, refpoint)
def valid_edge(self, state, primitive, plot = True): bounding_poly = affinity.rotate(primitive.bounding_poly, state[2], origin = (0.0, 0.0), use_radians = True) bounding_poly = affinity.translate(bounding_poly, state[0], state[1]) #Drawing Primitive-TAKE OUT TODO if plot: if bounding_poly.intersects(self.world_polys): color = 'r' else: color = 'b' fig = plt.figure(2) fig.clear() plt.ion() ax = fig.add_subplot(111, aspect = 'equal') for poly in self.world_polys: P = PolygonPatch(poly, fc = 'k', zorder = 2) ax.add_patch(P) P = PolygonPatch(bounding_poly, fc = color, ec = '#999999', alpha = 1, zorder = 1) polyPatch = ax.add_patch(P) ax.set_xlim(0,50) ax.set_ylim(0,50) fig.show() plt.pause(0.1) #pdb.set_trace() if bounding_poly.intersects(self.world_polys): return False return True
def line_extrapolate_point(l, p, length): """ Return a Point p2 which would extend the line `l` so that it would have a length of `length` l: a line p: a point within that line length: the length that a line from p to p2 would have """ p = Point(*_normalize_point(p)) a = line_angle_at(l, p) if a > pi: a = a % pi p2 = Point(p.x, p.y + length) c = l.centroid if p.x < c.x: if p.y < c.y: angle = pi-a else: angle = a elif p.x > c.x: if p.y < c.y: angle = -a else: angle = -a else: if p.y < c.y: angle = a + pi elif p.y > c.y: angle = a % pi else: angle = 100 p3 = rotate(p2, math.degrees(angle), origin=p) return p3
def _best_angle(surroundings, maxwidth, maxheight): """Find the angle by which surroundings should be rotated. Try to minimalize surroundings' height while keeping its width under maxwidth. Also prefer smaller rotations over bigger ones. Arguments: surroundings: shapely.geometry.polygon.Polygon maxwidth: maximum allowed width of the surroundings bounding box maxheight: maximum allowed height of the surroundings bounding box Returns: angle in degrees (counterclockwise) """ minheight = maxheight best = 0 lowest_penalty = 1000 for angle in range(-90, 90, 5): x1, y1, x2, y2 = affinity.rotate(surroundings, angle).bounds height = y2 - y1 width = x2 - x1 if width < maxwidth: penalty = height + abs(angle) / 100 if penalty < lowest_penalty: lowest_penalty = penalty minheight = height best = angle #maps and shapely differ in the directions of their y-axes return -best
def _do_inverse_transform(shape, rotation, mirrored, rotation_origin=(0,0), scale_origin=(0,0)): if shape is None or shape.is_empty: return shape r = shape r = affinity.scale(r, xfact=(-1 if mirrored else 1), origin=scale_origin) r = affinity.rotate(r, -rotation, origin=rotation_origin) return r;
def map_to_polygon(shape,origin,position,rotation,size): geom_obj=Polygon(shape) geom_obj=affinity.translate(geom_obj, -origin[0],-origin[1],0) geom_obj=affinity.scale(geom_obj,size[0],size[1],origin=(0,0)) geom_obj=affinity.rotate(geom_obj,int(rotation*360),origin=(0,0)) geom_obj=affinity.translate(geom_obj, position[0],position[1],0) return geom_obj
def to_shapely(self): """Create a shapely half circle rotated by the fan's angle. Notes ===== `Motivated by: <https://stackoverflow.com/a/30762727/680232>`_ """ # Define the arc (presumably ezdxf uses a similar convention) centerx, centery = self.semi_circle_center # make a semi-circle first that points to the x-axis, rotate later. start_angle = 270 # In degrees # number of elements for the semi-circle numsegments = 100 # The coordinates of the arc theta = np.radians(np.linspace(start_angle, start_angle+180, numsegments)) x = centerx + self.radius * np.cos(theta) y = centery + self.radius * np.sin(theta) arc = geom.LineString(np.column_stack([x, y])) rotated = affinity.rotate(arc, self.data.angle, origin=tuple(self.semi_circle_center)) df = pd.DataFrame(np.vstack([self.coords[::-1][:2], np.array(rotated)])) return geom.Polygon(df.round(2).drop_duplicates().values)
def __init__(self, x=0, y=0, z=0, N_slits=10, width=.0005, spacing=.002, length=.025, angle=0, angle_units='degrees', **kwargs): positions = spacing * np.array(range(N_slits)) positions = positions - np.mean(positions) geometry = MultiPolygon( [Polygon([(-length/2.0 + y, -width/2.0 + i + z), (-length/2.0 + y, +width/2.0 + i + z), (+length/2.0 + y, +width/2.0 + i + z), (+length/2.0 + y, -width/2.0 + i + z)]) for i in positions] ) if angle_units=='degrees': angle = angle elif angle_units=='radians': angle = angle * 180/np.pi else: raise IOError('unrecognized angle units') if angle != 0: geometry = rotate(geometry, angle, origin=Point((y, z))) super(PolygonGratingCollimator, self).__init__(x, geometry, **kwargs)
def obstacle_bound(shape, orientations): ''' return the convex hull of a shape rotated about (0,0) by the angles in the orientations sequence. ''' with nostdout(): shapes = [] for angle in orientations: shapes.append(affinity.rotate(shape, angle, origin=(0,0), use_radians=True)) union = ops.cascaded_union(shapes) bound = union.convex_hull.convex_hull # apparently sometimes one convex_hull isn't enough # TODO: check for convexity before retrying convex hull operation # sometimes convex-hull returns valid non-convex polygons well f**k if not bound.is_valid: # in case it randomly shits out # For debug: # clean shape bound = bound.buffer(0.0).convex_hull.convex_hull if not bound.is_valid: raise Exception('why doesnt this work') obstacle_bounds.append(bound) obstacle_orientations.append(orientations) return bound
def ellipse(width, length): """Create ellipse when given width and length. """ circle = geo.Point(0, 0).buffer(1) stretched = aff.scale(circle, xfact=width/2, yfact=length/2) rotated = aff.rotate(stretched, -45) return rotated
def rotate_polygon(self, rotation_pos): if rotation_pos not in Hexagon.ROTATE_ANGLES.keys(): print "Invalid rotation angle", rotation_pos return self.rotation_pos = rotation_pos self.polygon = affinity.rotate(self.original_polygon, Hexagon.ROTATE_ANGLES[rotation_pos]) pass
def to_minimise(optimiser_input): rotated = aff.rotate(to_be_aligned, optimiser_input[0]) disjoint_area = ( rotated.difference(alighn_to_this).area + alighn_to_this.difference(rotated).area ) return disjoint_area
def render_pad(self, layer_query, drill, **options): DRU = self.get_DRU() if self._layer_matches(layer_query, "Holes"): hole = shapes.Point(self.get_x(), self.get_y()).buffer(drill/2) return hole; radius = (drill/2); radius = radius + scaleAndBound(radius, DRU.rvPadTop, DRU.rlMinPadTop, DRU.rlMaxPadTop) if layer_query is not None and self.get_file().get_layer(layer_query).get_number() > 16 and not self._layer_matches(layer_query, "tStop") and not self._layer_matches(layer_query,"bStop"): return shapes.LineString() if self.get_shape() == "square": shape = shapes.box(self.get_x() - radius , self.get_y() - radius, self.get_x() + radius, self.get_y() + radius) elif self.get_shape() == "round" or self.get_shape() is None: shape = shapes.point.Point(self.get_x(), self.get_y()).buffer(radius) elif self.get_shape() == "octagon": shape = shapes.box(self.get_x() - radius, self.get_y() - radius, self.get_x() + radius, self.get_y() + radius) shape = shape.intersection(affinity.rotate(shape, 45)) elif self.get_shape() == "long": shape = shapely.ops.unary_union([shapes.point.Point(self.get_x() + DRU.psElongationLong/100.0 * radius, self.get_y()).buffer(radius), shapes.point.Point(self.get_x() - DRU.psElongationLong/100.0 * radius, self.get_y()).buffer(radius), shapes.box(self.get_x() - DRU.psElongationLong/100.0 * radius, self.get_y() - radius, self.get_x() + DRU.psElongationLong/100.0 * radius, self.get_y() + radius)]) elif self.get_shape() == "offset": shape = shapely.ops.unary_union([shapes.point.Point(self.get_x() + DRU.psElongationOffset/100.0 * radius * 2, self.get_y()).buffer(radius), shapes.point.Point(self.get_x(), self.get_y()).buffer(radius), shapes.box(self.get_x(), self.get_y() - radius, self.get_x() + DRU.psElongationLong/100.0 * radius * 2, self.get_y() + radius) ]) else: raise Swoop.SwoopError("Unknown pad shape: '{}'".format(self.get_shape())) if shape is not None: if self._layer_matches(layer_query,"tStop") or self._layer_matches(layer_query, "bStop"): shape = shape.buffer(computeStopMaskExtra(radius, DRU)) if options and "fail_on_missing" in options and options["fail_on_missing"] and shape is None: raise NotImplemented("Geometry for pad shape '{}' is not implemented yet.".format(self.get_shape())) elif shape is None: shape = shapes.LineString() return shape
def rotate_coords(coords, rot, origin): """ Rotates a set of coordinates (wrapper for shapely) coords: sequence point tuples (x, y) """ ur = LineString(unrotated) r = affinity.rotate(ur, rot, origin=ur[0]) return list(zip(r.coords.xy[0], r.coords.xy[1]))
def __call__(self, point, rotation=0): panels = [] for panel in self._panels: p = translate(panel, xoff=point.x, yoff=point.y) if rotation!=0: # Rotate around the origin p = rotate(p, rotation, origin=(0,0)) panels.append(p) return panels
def __call__(self, point, mirror=False, rotation=0): panel = Polygon([(point.x+vx, point.y+vy) for vx,vy in self._vertices]) if mirror: panel = Polygon([(point.x+vx, point.y+vy) for vx,vy in self._vertices_mirror]) if rotation!=0: # FIXME: better to rotate around vertex 0 than the center # of the polygon panel = rotate(panel, rotation) return panel
def to_shapely(self): """Convert a markings.Blotch to shapely Ellipse. Code from https://gis.stackexchange.com/questions/243459/drawing-ellipse-with-shapely/243462 """ circ = geom.Point(self.center).buffer(1) ell = affinity.scale(circ, self.data.radius_1, self.data.radius_2) ellr = affinity.rotate(ell, self.data.angle) return ellr
def testComputeAvgDir(self): crds = [[0, 0], [1, 0], [1, 2], [0, 2], [0, 0]] cell0 = g.Polygon(crds) cell = cell0 avgDir = _computeAvgDir(cell) self.assertAlmostEqual(0, avgDir) cell = a.rotate(cell0, np.pi / 6, use_radians=True) avgDir = _computeAvgDir(cell) self.assertAlmostEqual(np.pi / 6, avgDir) cell = a.rotate(cell0, np.pi / 3, use_radians=True) avgDir = _computeAvgDir(cell) self.assertAlmostEqual(np.pi / 3, avgDir) cell = a.rotate(cell0, np.pi / 2, use_radians=True) avgDir = _computeAvgDir(cell) self.assertAlmostEqual(0, avgDir)
def get_shapely_object(self): object = geometric_union([ self._gate(), self._choke_channel(), self._choke_left(), self._choke_right(), self._channel() ]) rotated_object = rotate(object, self._angle, (0, 0), True) return translate(rotated_object, self._origin[0], self._origin[1], 0)
def create_shapely_ellipse(center, lengths, angle=0): """ create a shapely ellipse. adapted from https://gis.stackexchange.com/a/243462 """ angle = math.degrees(angle) circ = Point(center).buffer(1) ell = affinity.scale(circ, int(lengths[0]), int(lengths[1])) ellr = affinity.rotate(ell, angle) return ellr
def predict_agents(self,agents,time_increment): # Loop over agents for agent in agents: # Predict Position agent.pos_pred = agent.pos_pred + agent.vel_vec*time_increment # Update prediction polygon agent.pol_pred = agent.pol_origin agent.pol_pred = affinity.translate(agent.pol_pred,agent.pos_pred[0],agent.pos_pred[1]) agent.pol_pred = affinity.rotate(agent.pol_pred,np.rad2deg(-agent.yaw), 'center')
def special(self): p = self.generating_region xmin, ymin, xmax, ymax = p.bounds mx = scale(p, xfact=-1, origin=(xmax, ymin)) my = scale(p, yfact=-1, origin=(xmax, ymin)) mxy = scale(p, xfact=-1, yfact=-1, origin=(xmax, ymin)) s1 = unary_union([p, mx, my, mxy]) s1r2 = rotate(s1, angle=240, origin=(xmax, ymax)) pr = rotate(p, angle=180, origin=(xmax / 2, 3**0.5 / 2 * xmax)) cell_quart = unary_union([p, pr, s1r2]) cell_quart_1 = scale(cell_quart, xfact=-1, origin=(xmax, ymin)) cell_quart_2 = scale(cell_quart, yfact=-1, origin=(xmax, ymin)) cell_quart_3 = scale(cell_quart, xfact=-1, yfact=-1, origin=(xmax, ymin)) cell = unary_union( [cell_quart, cell_quart_1, cell_quart_2, cell_quart_3]) self.unit = cell
def _transform(geom): centroid = geom.centroid # Bring back to origin geom = translate(geom, xoff=-centroid.x, yoff=-centroid.y) geom = rotate(geom, -self._bubble_heading, "centroid", use_radians=True) # Now apply new transformation in "vehicle coordinate space" geom = translate( geom, xoff=self._bubble.follow_offset[0], yoff=self._bubble.follow_offset[1], ) geom = rotate(geom, vehicle.heading, (0, 0), use_radians=True) geom = translate(geom, xoff=x, yoff=y) return geom
def rotate(self, angle, r_c, start_h, start_w): poly=self.polygons[0].numpy().reshape(-1,2) poly[:, 0]+=start_w poly[:, 1]+=start_h polys=Polygon(poly) r_polys=list(affinity.rotate(polys,angle,r_c).boundary.coords[:-1]) p=[] for r in r_polys: p+=list(r) return Polygons([p], size=self.size, mode=self.mode)
def __init__(self, center, width, height, theta): left = center[0] - width / 2 right = center[0] + width / 2 bottom = center[1] - height / 2 top = center[1] + height / 2 p = box(left, bottom, right, top) p = affinity.rotate(p, theta, origin='center', use_radians=True) super(RectangleCollider, self).__init__(p)
def get_base_shape(self): """ Get the base shape of this ship, in board coordinates return: Polygon representing this ship """ bx = self.base_size[0] / 2 by = self.base_size[1] / 2 base_shape = box(-bx, -by, bx, by) base_shape = rotate(base_shape, self.orientation) return translate(base_shape, self.position[0], self.position[1])
def minimum_oriented_boundingbox(self): p = self.enveloppe_convexe() m_bb = self.bounding_box().area k = 0 for i in range(360): rotated_b = affinity.rotate(p, i, origin='centroid') a = rotated_b.bounds p1 = (a[0], a[1]) p2 = (a[0], a[3]) p3 = (a[2], a[3]) p4 = (a[2], a[1]) m_cc = Polygon([p1, p2, p3, p4]).area pp = Polygon([p1, p2, p3, p4]) if m_cc < m_bb: m_bb = m_cc polygon_retenu = pp k = i vrai_poly = affinity.rotate(polygon_retenu, -k, origin='centroid') return Polygon(vrai_poly)
def _prepare(self): offset_x, offset_y = self.offset_um self.border = affinity.rotate(self.border, self.angle_deg, origin=(0, 0), use_radians=False) self.border = affinity.translate(self.border, offset_x, offset_y, 0) for i in range(0, self.N): self.polys[i] = affinity.rotate(self.polys[i], self.angle_deg, origin=(0, 0), use_radians=False) self.polys[i] = affinity.translate(self.polys[i], offset_x, offset_y, 0) t = mpl.transforms.Affine2D().rotate_deg_around(0, 0, self.angle_deg)\ .translate(offset_x, offset_y) + global_geom_ax.transData self.pieces[i].rect.set_transform(t)
def build_shapely_geometry(self) -> BaseGeometry: """ Builds the internal shapely representation of the geometry. This is used by other base class methods to build the other output types. :return: A shapely geometry specific to the derived type. :rtype: :py:class:`BaseGeometry` """ # Get the UTMSRID so we can transform the center point to a coordinate system where distance is # measured in meters. utmsrid: int = getutmsrid(self.longitude, self.latitude, self.sr_id) # Create the OGR Point center: ogr.Geometry = ogr.Geometry(ogr.wkbPoint) center.AssignSpatialReference(Geodetic2D.get_ogr_sr(self.sr_id)) center.AddPoint(self.longitude, self.latitude) # Project the point from its native projection to the UTM system. center = reproject_geom(center, self.sr_id, utmsrid) # Buffer the point with the radius to get a polygon of the circle. circle: ogr.Geometry = center.Buffer(1) # Create the shapely object so we can do the ellipse magic. proto_ellipse: BaseGeometry = loads(circle.ExportToWkt()) # stretch the ellipse along the major and minor axes scaled_ellipse: BaseGeometry = affinity.scale(proto_ellipse, self.majorAxis, self.minorAxis) rotate_angle = calculate_orientation(self.orientation) rotated_ellipse: BaseGeometry = None if rotate_angle >= 0: # Let rotate the ellipse (clockwise, x axis pointing right): rotated_ellipse = affinity.rotate(scaled_ellipse, rotate_angle, use_radians=True) else: # If one need to rotate it clockwise along an upward pointing x axis: rotated_ellipse = affinity.rotate(scaled_ellipse, 90 - rotate_angle, use_radians=True) # According to the man, a positive value means a anti-clockwise angle, # and a negative one a clockwise angle. # Now build an OGR geometry so we can reproject. ogr_ellipse: ogr.Geometry = ogr.CreateGeometryFromWkt(rotated_ellipse.wkt) ogr_ellipse.AssignSpatialReference(Geodetic2D.get_ogr_sr(utmsrid)) ogr_ellipse = reproject_geom(ogr_ellipse, utmsrid, self.sr_id) return loads(ogr_ellipse.ExportToWkt())
def create_ellipse(x,y,a,b,theta,scale): """ create a shapely ellipse. adapted from https://gis.stackexchange.com/a/243462 """ x,y,a,b = x*scale,y*scale,a*scale,b*scale circ = Point((int(x),int(y))).buffer(1) ell = affinity.scale(circ, int(a), int(b)) ellr = affinity.rotate(ell, theta) return ellr
def rotate(self, angle, r_c, start_h, start_w): r_polys = [] for poly in self.char_boxes: poly = poly.numpy() poly[0::2] += start_w poly[1::2] += start_h poly= Polygon(np.array(poly).reshape(4,2)) r_poly = np.array(list(affinity.rotate(poly, angle, r_c).boundary.coords[:-1])).reshape(-1, 8) r_polys.append(r_poly[0]) return CharPolygons(r_polys, word=self.word, use_char_ann=self.use_char_ann,char_classes=self.char_classes,size=(r_c[0]*2,r_c[1]*2), mode=self.mode)
def test_Tessellation(self): tes = mm.Tessellation(self.df_buildings, "uID", self.limit, segment=2) tessellation = tes.tessellation assert len(tessellation) == len(self.df_tessellation) bands = mm.Tessellation(self.df_streets, "nID", mm.buffered_limit(self.df_streets, 50), segment=5).tessellation assert len(bands) == len(self.df_streets) # test_enclosed_tessellation enc1 = mm.Tessellation(self.df_buildings, "uID", enclosures=self.enclosures).tessellation assert len(enc1) == 155 assert isinstance(enc1, gpd.GeoDataFrame) enc1_loop = mm.Tessellation(self.df_buildings, "uID", enclosures=self.enclosures, use_dask=False).tessellation assert len(enc1) == 155 assert isinstance(enc1, gpd.GeoDataFrame) assert len(enc1_loop) == 155 assert isinstance(enc1_loop, gpd.GeoDataFrame) assert_geodataframe_equal(enc1, enc1_loop) with pytest.raises(ValueError): mm.Tessellation(self.df_buildings, "uID", limit=self.limit, enclosures=self.enclosures) enc1_loop = mm.Tessellation(self.df_buildings, "uID", enclosures=self.enclosures, use_dask=False).tessellation assert len(enc1) == 155 assert isinstance(enc1, gpd.GeoDataFrame) # erroneous geometry df = self.df_buildings b = df.total_bounds x = np.mean([b[0], b[2]]) y = np.mean([b[1], b[3]]) df.loc[144] = [145, Polygon([(x, y), (x, y + 1), (x + 1, y)])] df.loc[145] = [146, MultiPoint([(x, y), (x + 1, y)]).buffer(0.55)] df.loc[146] = [147, affinity.rotate(df.geometry.iloc[0], 12)] tess = mm.Tessellation(df, "uID", self.limit) assert tess.collapsed == {145} assert len(tess.multipolygons) == 3
def generate_signals(polygon, angles_deg, samples=1024, cpm_points=None, vertical_error=None, horizontal_error=None, angles_deg_errors=None): if not vertical_error: vertical_error = 0 if not horizontal_error: horizontal_error = 0 if angles_deg_errors: for index, angle in enumerate(angles_deg): angles_deg[index] += angles_deg_errors[index] angles = [((i / 360) * 2 * np.pi) for i in angles_deg] # TODO: replace 100 with max distance probe_distance = 1000 probe_pos = [ Point(probe_distance * np.cos(angle), probe_distance * np.sin(angle)) for angle in angles ] probe_lines = [ geometry.LineString([Point(0, 0), pos]) for pos in probe_pos ] thetas = np.linspace(0, np.pi * 2, samples) # initialize list of signals signals = [[] for _ in range(len(angles))] # print("starting signals") for theta_index, theta in enumerate(thetas): # CPM movement translated = affinity.translate(polygon, cpm_points[theta_index][0], cpm_points[theta_index][1]) # error position of the frame translated = affinity.translate(translated, horizontal_error, vertical_error) rotated = affinity.rotate(translated, theta, use_radians=True) for index, angle in enumerate(angles): line = probe_lines[index] # intersection = line.intersection(rotated) intersection = line.intersection(rotated.boundary) dist = intersection.distance(probe_pos[index]) signals[index].append(dist) return signals
def get_forward_wall_camera_direction(self, point): wall = self.point2wall[(point.x, point.y)] vector0 = scale_line_length(LineString([(point.x, point.y), wall[0]]), ALLOWED_DISTANCE_ERROR) vector1 = scale_line_length(LineString([(point.x, point.y), wall[1]]), ALLOWED_DISTANCE_ERROR) for v in (vector0, vector1): u = rotate(v, 90, origin=point, use_radians=False) if not self.polygon.contains(Point(u.coords[1])): p1, p2 = u.coords return Point(p2[0] - p1[0], p2[1] - p1[1]) raise NotImplementedError
def create_ellipse(self, ratio): """ create a shapely ellipse. adapted from https://gis.stackexchange.com/a/243462 https://gis.stackexchange.com/questions/243459/drawing-ellipse-with-shapely/243462#243462 """ circ = Point(self.center).buffer(1.0) ell = affinity.scale(circ, float(self.lengths[0] * ratio), float(self.lengths[1] * ratio)) ellr = affinity.rotate(ell, self.angle) return ellr
def translate_and_rotate(geometry, offset, angle, columns, rows, spacing): if not geometry: return geometry if not spacing: return translate( rotate(geometry, angle if angle else 0, use_radians=True, origin=(0, 0)), *offset) return translate( geometric_union( translate( rotate(geometry, angle if angle else 0, use_radians=True, origin=(0, 0)), spacing[0] * c, spacing[1] * r) for c in range(columns) for r in range(rows)), *offset)
def getOverlapArea(self, shape=None, offset=None, angle=None): if not shape: shape = self.shape_buffer if not offset: offset = self.offset if not angle: angle = self.angle area = 0 shape = affinity.translate(affinity.rotate(shape, angle, origin=(0,0)), *offset) overlaps = [h for h in self.tree.query(shape)] for h in overlaps: area += shape.intersection(h).area area += shape.difference(self.board).area return area
def __init__(self, cx, cy, width, length, rotation=0.): self.center = [cx,cy] self.width = width self.length = length self.rotation = rotation x = numpy.array([-width/2, width/2])+cx y = numpy.array([-length/2, length/2])+cy square = asPolygon(numpy.append(numpy.roll(numpy.repeat(x,2),-1), numpy.repeat(y,2)).reshape(2,4).T) # rotate() function is provided by shapely.affinity package super(SlitAperture, self).__init__(rotate(square, rotation))
def update_abs(self, turtle): x = turtle.pos[0] y = turtle.pos[1] angle = turtle.angle pivot = (0, 0) point = Point(self.x_off, self.y_off) point = affinity.rotate(point, angle, origin=pivot) point = affinity.translate(point, xoff=x, yoff=y) self.abs_x_off = point.x self.abs_y_off = point.y self.abs_angle = angle + self.angle % 360
def fresnel(self, clearance=False): f1 = math.sqrt(self.l * self.distance / 4) radius = f1 if clearance: radius *= 0.6 S = Point(self.A.x + self.distance / 2, self.A.y) alpha = math.atan2(self.B.y - self.A.y, self.B.x - self.A.x) C = S.buffer(self.distance / 2) C = scale(C, 1, radius / (self.distance / 2)) C = rotate(C, alpha, origin=self.A, use_radians=True) return C
def setup_method(self): t1 = Polygon([(0, 0, 0), (1, 0, 0), (1, 1, 1)]) t2 = Polygon([(1, 0, 0), (2, 0, 0), (2, 1, 1)]) self.polys = GeoSeries([t1, t2], index=list('AB')) self.df = GeoDataFrame({'geometry': self.polys, 'values': [0, 1]}) multipoly1 = MultiPolygon([t1, t2]) multipoly2 = rotate(multipoly1, 180) self.df2 = GeoDataFrame({'geometry': [multipoly1, multipoly2], 'values': [0, 1]})
def createPolygon(self, item): # x,y,h,w,theta # x,y - center coordinates #h,w - its size # theta - orientations x, y, h, w, t = item coords = [(-w, -h), (w, -h), (w, h), (-w, h)] p = Polygon(coords) #print(x,y,h,w,t) return translate(rotate(p, t), x, y)
def setup_method(self): self.N = 10 self.points = GeoSeries(Point(i, i) for i in range(self.N)) values = np.arange(self.N) self.df = GeoDataFrame({'geometry': self.points, 'values': values}) multipoint1 = MultiPoint(self.points) multipoint2 = rotate(multipoint1, 90) self.df2 = GeoDataFrame({'geometry': [multipoint1, multipoint2], 'values': [0, 1]})
def infrared_right(self): ir = Polygon([ np.array(self._robot.pos.coords)[0] + (self._robot.bounding_x, self._robot.bounding_y), np.array(self._robot.pos.coords)[0] + (self._robot.bounding_x, self._robot.bounding_y) + (self.infrared_length, -self.infrared_width), np.array(self._robot.pos.coords)[0] + (self._robot.bounding_x, self._robot.bounding_y) + (self.infrared_length, self.infrared_width)]) ir = affinity.rotate(ir, self._robot.rotation + 0.07, origin=self._robot.pos, use_radians=True) return not self.area.contains(ir) \ or np.array([ir.intersects(cube) for cube in self._red_cubes]).any() \ or np.array([ir.intersects(cube) for cube in self._obstacles]).any()
def __call__(self, point, step, rotation=0): grid = [] if self.shape == 'diamond': grid = self.diamond(point, step) elif self.shape == 'square': grid = self.square(point, step) elif self.shape == 'hexagon': grid = self.hexagon(point, step) if rotation != 0: grid = [rotate(point, rotation, origin=point) for point in grid] return grid
def __call__(self, point, mirror=False, rotation=0): panel = Polygon([(point.x + vx, point.y + vy) for vx, vy in self._vertices]) if mirror: panel = Polygon([(point.x + vx, point.y + vy) for vx, vy in self._vertices_mirror]) if rotation != 0: # FIXME: better to rotate around vertex 0 than the center # of the polygon panel = rotate(panel, rotation) return panel
def __init__(self, name, x, y, angle=0, size=None, shape=None, drill=None): self.name = name self.angle = angle point = affinity.rotate(Point(x, y), angle, origin=Point(0, 0)) self.location = np.array([point.coords[0][0], point.coords[0][1], 1]) # Optional properties for pcb export self.size = size self.shape = shape self.drill = drill