# reset()

## Syntax

```reset()
```

## Description

Resets the current transform to its default state (the identity matrix).

Transformations in PlotDevice build up an incremental state. For example, once `rotate(90)` is called, all subsequent shapes, paths, text, and images are rotated 90 degrees (i.e., the rotation ‘state’ is 90°). If called again – e.g., `rotate(30)` – the rotation state becomes 120 degrees (90+30).

Once reset() is called, the rotation state becomes 0 degrees (the default rotation) again. Since reset() affects the entire transform state, it will also wipe out any previously applied translations, skews, and scale-factors.

## Context Manager

As with the other transform commands, reset() can be used in a `with` statement to limit its scope to drawing commands within the following block of code.

## Example ```font(14), fill(0.2)

rotate(90)
text("one", 30, 80)
text("two", 45, 80)

reset()
text("three", 70, 80)
```

# rotate()

## Syntax

```rotate(amount) # amount to rotate (in default unit)
```
```rotate(percent=0.5) # 0 ... 1.0
rotate(degrees=180) # 0 ... 360
rotate(radians=pi)  # 0 ... 2*pi (a.k.a. tau)
```

## Description

Rotates all subsequent drawing commands. The rotate() command accepts one parameter to specify the angle (in degrees by default). The angle-unit can be changed by calling geometry() with `DEGREES`, `RADIANS`, or `PERCENT`. Subsequent calls to rotate() will then be interpreted in the chosen units.

Alternatively, a rotation can specify its units explicitly by using a keyword argument. For example, you can use radians to flip the canvas upside down (regardless of the current geometry-unit) wtih:

```rotate(radians=tau/2)
```

Like other transform operations, the rotate() command works incrementally: if you call `rotate(30)`, and later on call `rotate(60)`, all commands following that second rotate() will be rotated 90° (30+60).

## Context Manager

As with the other transform commands, rotate() can be used in a `with` statement to limit its scope to drawing commands within the indented block of code.

## Example ```fill(0.2)
rotate(-45)
rect(30, 30, 40, 40)
```

# scale()

## Syntax

```scale(x, y=None)
```

## Description

Increases, decreases, or streches the size of all subsequent drawing commands. The first parameter sets the horizontal scale and the optional second parameter the vertical scale. You can also call scale() with a single parameter that sets both the horizontal and vertical scale. Scale values are specified as floating-point (decimal) numbers with 1.0 corresponding to 100%.

The scale() command works incrementally: if you call `scale(0.5)`, and later on call `scale(0.2)`, all subsequent drawing commands will be sized to 10% (0.2 of 0.5).

## Context Manager

As with the other transform commands, scale() can be used in a `with` statement to limit its scope to drawing commands within the following block of code.

## Example ```fill(0.2)
poly(30,30, 20)
scale(0.5)
poly(70,30, 20)
```

# skew()

## Syntax

```skew(x, y=None)
```

## Description

Slants the direction of all subsequent drawing commands. The first parameter sets the horizontal skew. The second parameter is optional and sets the vertical skew.

Skew values are expressed as angles using the current geometry() unit (`DEGREES` by default). The skew() command works incrementally: if you call `skew(10)`, and later on call `skew(20)`, all subsequent drawing commands will be skewed by 30° (10+20).

## Context Manager

As with the other transform commands, skew() can be used in a `with` statement to limit its scope to drawing commands within the indented block of code.

## Example ```fill(0.2)
skew(10.0)
rect(20, 10, 40, 40)
```

# transform()

## Syntax

```transform(mode)
```

Set the current transform mode (to `CENTER` or `CORNER`)

```transform(matrix=[m11, m21, m12, m22, tX, tY])
```

Overwrite the current transform matrix with a new one

```with transform(mode=None, matrix=None):
... # drawing & transformation commands
```

Restore the transformation state at the end of the indented block (and optionally change the transform mode/matrix for the duration)

## Description

The `mode` parameter sets the registration point – the offset for rotate(), scale() and skew() commands. By default, primitives, text, and images rotate around their own centerpoints. But if you call transform() with `CORNER` as its `mode` parameter, transformations will be applied relative to canvas’s ‘origin point’ rather than being relative to the objects’ centerpoint origins.

In addition to changing the mode, the transform() command also allows you to overwrite the underlying transformation matrix with a new set of values. Pass a 6-element list or tuple as the `matrix` argument to update the current transform (see Apple’s docs for all the math-y details). Note that you can omit the `mode` arg when setting a new matrix if you don’t want the transformation origin to change.

## Context Manager

When called as part of a `with` block, transform() will ensure that any subsequent transformation commands will apply only within the block. At the end of the block, the transformation state will be reset to what it was before the transform() call. This is equivalent to calling push() and pop() at the beginning and end of the block respectively, though transform() will also reset the `mode` on exit.

```with transform(CORNER):
translate(100,20)
line(0,0, 40,0)
```

is equivalent to:

```oldmode = CENTER
transform(CORNER)
push()
translate(100,20)
line(0,0, 40,0)
pop()
transform(oldmode)
```

## Returns

a Transform object with the canvas’s ‘current’ state. You can use this object’s apply() method with Points or Beziers to calculate the ‘screen coordinates’ that would result from drawing with the current transformation state.

## Examples ```fill(0.2)
fontsize(14)
rotate(90)
text("one", 40, 80)

with transform():
rotate(-90)
text("two", 40, 40)

text("three", 50, 80)
```

# translate()

## Syntax

```translate(x, y)
```

## Description

Shifts the origin used when interpreting drawing commands’ coordinates. The first parameter sets the horizontal offset, the second parameter the vertical offset. Translating is the same as dragging something across the screen. Or the same as moving the canvas registration point, which is situated in the upper left corner by default.

After calling translate(), all subsequent drawing commands are shifted by the specified offsets. This can be useful when positioning groups of multiple elements.

## Context Manager

As with the other transform commands, translate() can be used in a `with` statement to limit its scope to drawing commands within the following block of code.

## Example ```fill(0.2)
arc(10,10, 20)
translate(50, 50)
arc(10,10, 20)
```

# Transform

## Syntax

```Transform()
```

## Description

A local transformation state (independent of the global, canvas transform). You can use Transform objects to apply translation, rotation, scaling and skewing to a path before drawing it.

## Methods

```t.translate(x=0, y=0)
t.scale(x=1, y=None)
t.skew(x=0, y=0)
t.invert()
```
```t.append(t)
t.prepend(t)
```
```t.apply(path_or_point)
```
```t.copy()
```

The apply() method returns a new `Bezier` or `Point` with the defined transformations applied to it.

# push() & pop()

## Syntax

```push()
```
```pop()
```

## Description

PlotDevice is a so-called state-machine in which certain types of modifications are cumulative. For example, once `rotate(45)` is called, all subsequent shapes, paths, text and images are rotated 45 degrees – the rotation ‘state’ has been set to 45°.

All transformations, such as rotate() and skew(), defined between a push() and pop() call last only until pop() is called. Thereafter the previous state is used. For example, a rotate(-30) within a rotate(45) means a rotation state of 15° until pop() is called and the rotation state becomes 45 degrees again.

## PlotDevice Equivalent

While push() & pop() allow your script to save and restore the state manually (and leave it up to you to ensure that a call to one is balanced by a call to the other). The transform() command provides a context manager to limit the scope of these state changes to an indented block of code.

## Example ```fill(0.2)
fontsize(14)
rotate(90)
text("one", 40, 80)

push()
rotate(-90)
text("two", 40, 40)
pop()

text("three", 50, 80)
```