drafting.geometry.Rect

class Rect(*rect)

Representation of a rectangle as (x, y, w, h), indexable

Constructor handles multiple formats, including:

  • x, y, w, h

  • [x, y, w, h]

  • w, h (x and y default to 0, 0)

Rect objects can be splat’d where lists are expected as individual arguments (as in drawBot), i.e. rect(*my_rect), or can be passed directly to functions expected a list representation of a rectangle.

FromCenter(w, h=None)

Create a rect given a center point and a width and height (optional, height will default to width if not specified”)

FromMnMnMxMx()

Create a rectangle from xmin, ymin, xmax, ymax

divide(amount, edge, forcePixel=False)

Dividing

Derived from the behavior of the classic Cocoa function CGRectDivide, which takes a rectangle and breaks it into two pieces, based on a pixel amount and an edge.

A quick example: assume you have a rectangle, r, defined as such:

r = Rect(0, 0, 300, 100)

If you want to break that into a left-hand rectangle that’s 100 pixels wide and a right-hand rectangle that’s 200 pixels wide, you could either say:

left, right = r.divide(100, "mnx")

or you could say

right, left = r.divide(200, "mxx")

where mxx is the rightmost edge, and mnx is the leftmost edge.

Centering

A special use-case is if you want to break a rectangle into three rectangles, based on the center “edge”, you can do something like this:

left, center, right = r.divide(200, "mdx")

This will result in three rectangles, always left-to-right, where left is 50px wide, then center is 200px wide, then right is also 50px wide — anything not in the center will be evenly distributed between left and right, or top-and-bottom in the case of a Y edge.

grid(rows=2, columns=2)

Construct a grid

inset(dx, dy=None)

Creates padding in the amount of dx and dy. Also does expansion with negative values, or both at once

ipos(pt, defaults=(0.5, 0.5), clamp=True)

Get scaled 0-1 bounded (optional) value from a point in a rectangle

mnmnmxmx()

Return extents of rectangle as list

origin()

(x, y) as tuple

p(eh, ev=<Edge.MinX: 4>)

Get a Point at a given compass direction, chosen from

  • C

  • W

  • NW

  • N

  • NE

  • E

  • SE

  • S

  • SW

point(eh, ev=<Edge.MinX: 4>)

Get a Point at a given compass direction, chosen from

  • C

  • W

  • NW

  • N

  • NE

  • E

  • SE

  • S

  • SW

rect()

x,y,w,h in list

round()

round the values in the rectangle to the nearest integer

square()

take a square from the center of this rect

subdivide(amount, edge)

Like divide, but here you specify the number of equal pieces you want (like columns or rows), and then what edge to start at, i.e.

r = Rect(0, 0, 500, 100)
r.subdivide(5, "mxx")
=> [Rect([400.0, 0, 100.0, 100]), Rect([300.0, 0, 100.0, 100]), Rect([200.0, 0, 100.0, 100]), Rect([100.0, 0, 100.0, 100]), Rect([0, 0, 100.0, 100])]

will get you five 100-px wide rectangles, right-to-left

(N.B. Does not support center edges, as that makes no sense)

subdivide_with_leading(count, leading, edge, forcePixel=True)

Same as subdivide, but inserts leading between each subdivision

subdivide_with_leadings(count, leadings, edge, forcePixel=True)

Same as subdivide_with_leadings, but inserts leading between each subdivision, indexing the size of the leading from a list of leadings

subtract(amount, edge)

The opposite of take, this will remove and not return a piece of the given amount from the given edge.

Let’s say you have a 100px-wide square and you want to drop 10px from the right-hand side, you would do:

Rect(100, 100).subtract(10, Edge.MaxX), which leaves you with Rect([0, 0, 90, 100])

take(amount, edge, forcePixel=False)

Like divide, but here it just returns the “first” rect from a divide call, not all the resulting pieces, i.e. you can “take” 200px from the center of a rectangle by doing this Rect(0, 0, 300, 100).take(200, "mdx") which will result in Rect([50, 0, 200, 100])

wh()

the width and height as a tuple

xy()

equivalent to origin