def blend_xy_sep_transform(trans1, trans2): """ If trans1 and trans2 are SeparableTransformation instances, you can build a new SeparableTransformation from them by extracting the x and y bounding points and functions and recomposing a new SeparableTransformation This function extracts all the relevant bits from trans1 and trans2 and returns the new Transformation instance. This is useful, for example, if you want to specify x in data coordinates and y in axes coordinates. """ inboxx = trans1.get_bbox1() inboxy = trans2.get_bbox1() outboxx = trans1.get_bbox2() outboxy = trans2.get_bbox2() xminIn = inboxx.ll().x() xmaxIn = inboxx.ur().x() xminOut = outboxx.ll().x() xmaxOut = outboxx.ur().x() yminIn = inboxy.ll().y() ymaxIn = inboxy.ur().y() yminOut = outboxy.ll().y() ymaxOut = outboxy.ur().y() funcx = trans1.get_funcx() funcy = trans2.get_funcy() boxin = Bbox(Point(xminIn, yminIn), Point(xmaxIn, ymaxIn)) boxout = Bbox(Point(xminOut, yminOut), Point(xmaxOut, ymaxOut)) return SeparableTransformation(boxin, boxout, funcx, funcy)
def bbox_all(bboxes): """ Return the Bbox that bounds all bboxes """ # this is a good candidate to move to _transforms assert (len(bboxes)) if len(bboxes) == 1: return bboxes[0] bbox = bboxes[0] minx = bbox.xmin() miny = bbox.ymin() maxx = bbox.xmax() maxy = bbox.ymax() for bbox in bboxes[1:]: thisminx = bbox.xmin() thisminy = bbox.ymin() thismaxx = bbox.xmax() thismaxy = bbox.ymax() if thisminx < minx: minx = thisminx if thismaxx > maxx: maxx = thismaxx if thisminy < miny: miny = thisminy if thismaxy > maxy: maxy = thismaxy return Bbox(Point(Value(minx), Value(miny)), Point(Value(maxx), Value(maxy)))
def inverse_transform_bbox(trans, bbox): 'inverse transform the bbox' xmin, xmax = bbox.intervalx().get_bounds() ymin, ymax = bbox.intervaly().get_bounds() xmin, ymin = trans.inverse_xy_tup((xmin, ymin)) xmax, ymax = trans.inverse_xy_tup((xmax, ymax)) return Bbox(Point(Value(xmin), Value(ymin)), Point(Value(xmax), Value(ymax)))
def scale_sep_transform(sx, sy): """ Return a pure scale transformation as a SeparableTransformation; sx and sy are LazyValue instances (Values or binary opertations on values) """ bboxin = unit_bbox() bboxout = Bbox(Point(zero(), zero()), Point(sx, sy)) return SeparableTransformation(bboxin, bboxout, Func(IDENTITY), Func(IDENTITY))
def copy_bbox_transform(trans): 'return a deep copy of the bbox transform' inbox = trans.get_bbox1() xmin, xmax = inbox.intervalx().get_bounds() ymin, ymax = inbox.intervaly().get_bounds() newInbox = Bbox(Point(Value(xmin), Value(ymin)), Point(Value(xmax), Value(ymax))) outbox = trans.get_bbox2() xmin, xmax = outbox.intervalx().get_bounds() ymin, ymax = outbox.intervaly().get_bounds() newOutbox = Bbox(Point(Value(xmin), Value(ymin)), Point(Value(xmax), Value(ymax))) typex = trans.get_funcx().get_type() typey = trans.get_funcy().get_type() newtrans = get_bbox_transform(newInbox, newOutbox) newtrans.get_funcx().set_type(typex) newtrans.get_funcy().set_type(typey) return newtrans
def bound_vertices(verts): """ Return the Bbox of the sequence of x,y tuples in verts """ # this is a good candidate to move to _transforms xs = [x for x, y in verts] ys = [y for x, y in verts] minx = min(xs) maxx = max(xs) miny = min(ys) maxy = max(ys) return Bbox(Point(Value(minx), Value(miny)), Point(Value(maxx), Value(maxy)))
def lbwh_to_bbox(l, b, w, h): return Bbox(Point(Value(l), Value(b)), Point(Value(l + w), Value(b + h)))
def unit_bbox(): """ Get a 0,0 -> 1,1 Bbox instance """ return Bbox(origin(), Point(one(), one()))