- Assignment 06 due tonight
- Assignment 07 posted soon
- make a site that incorporates recursion and coordinate transformation to make a self-similar image
- due next Monday

- Quiz this Wednesday: coordinate transformations
- define a
`matrix`

transformation given transformation’s geometric description - given a
`matrix`

and original image, draw the transformed image

- define a

- Binary Trees
- Activity: Drawing Binary Trees by Hand
- Aesthetic and Pragmatic Principles
- Greedy Procedure
- Knuth Layout

We illustrated the depth-first search algorithm on graphs

We illustrated the depth-first search algorithm on graphs

User drew input graph graph by hand

- from clicks, obtained graph structure
- geometry of graph layout defined with graph

**Input.** A graph

- vertices
- edges

**Output.** A drawing of the graph

- visual representation of vertices
- geometric locations
- usually “points”

- visual representation of edges
- usual lines or curves between vertices

Algorithms for drawing **binary trees**

A (rooted) **binary tree** consists of

- a set $V$ of vertices
- a
**root**vertex - each vertex has:
- a
**left child**(possibly null) - a
**right child**(possibly null)

- a

satisfying:

- the root is not anyone’s child
- every node is the child of exaclty one node
- every node is a descendant of the root

`V = {0, 1, 2, 3, 4}`

`root = 0`

`left(0) = 2, right(0) = 3`

`left(3) = 4, right(3) = 1`

- unassigned children are
`null`

```
V = {0,...,13}
root: 0
left(0) = 1, right(0) = 2
left(1) = 3, right(1) = 4
right(2) = 5
left(4) = 6, right(4) = 7
right(5) = 8
left(8) = 9
left(9) = 10, right(9) = 11
left(10) = 12, right(10) = 13
```

- What information do we want to convey about the tree?
- What constraints might we have on our drawing?
- What aesthetic considerations might we have?
- when does a tree “look nice?”

**Aesthetic Principle 1.** Vertices at the same **depth** should lie along a horizontal line with deeper nodes lower than shallower nodes.

- what physical requirements does this impose?

Have to contend with width

- What can we do about it?

How can we achieve minimum possible **width** subject to

- lower bound on horizontal spacing
- Aesthetic Principle 1

**Idea**

- draw vertices in rows according to
**depth**- depth = distance from root

- root goes alone in the top row, next row at depth 1, etc.
- draw each row with vertices from “left to right”
- what does this mean?

**Promise**

- Use as few columns as possible!
- minimize width requirement

```
V = {0,...,7}
root: 0
left(0) = 1, right(0) = 2
left(1) = 3, right(1) = 4
right(2) = 5
left(4) = 6, right(4) = 7
```

**Input:** tree (just the root?)

**Output:** row and column for each node

My implementation:

- set depth when each vertex is added
- depth of a vertex is parent’s depth + 1
- store a
`Map`

:- keys are vertex IDs
- values are depths

**Observation.** If $u$ is a left child of $v$ and $w$ is a right child of $v$, then $u$ should be in a column to the left of $v$.

**Idea.** Starting from the root:

- place vertex in the left-most un-assigned column in its row (depth)
- place
**left**descendants - place
**right**descendants

This is *pre-order traversal!*

```
V = {0,...,7}
root: 0
left(0) = 1, right(0) = 2
left(1) = 3, right(1) = 4
right(2) = 5
left(4) = 6, right(4) = 7
```

Computing Depths:

```
const BinaryTree = function (root) {
this.depths = new Map();
...
this.addLeftChild = function (parentID, childID) {
...
this.depths.set(childID, this.depths.get(parentID) + 1);
}
}
```

Getting vertices in “pre-order”

```
this.verticesPreOrder = function (from = this.root) {
let vertices = [];
vertices.push(from);
if (from.left != null)
vertices = vertices.concat(this.verticesPreOrder(from.left));
if (from.right != null)
vertices = vertices.concat(this.verticesPreOrder(from.right));
return vertices;
```

Getting Rows and Columns

```
this.setLayoutGreedy = function () {
const vertices = this.tree.verticesPreOrder();
const depths = this.tree.depths;
...
const cols = []; // current col for each row, initialized to 0
...
for (let vtx of vertices) {
let row = depths.get(vtx.id)
let col = cols[row];
cols[row]++;
/* set position of vtx to this row and col */
}}
```

`lec13-binary-tree.zip`

**Aesthetic Principle 2.** The left child of any node should appear to the left of its parent, and a right child should appear to the right of its parent.

Rows and Columns

- rows are defined by depth (Aesthetic Principle 1)
- columns are “in-order” traversal order
- each vertex gets own column

- guarantees
- left descendants to the left
- right descenadants to the right

```
this.verticesInOrder = function (from = this.root) {
let vertices = [];
if (from.left != null)
vertices = vertices.concat(this.verticesPreOrder(from.left));
vertices.push(from);
if (from.right != null)
vertices = vertices.concat(this.verticesPreOrder(from.right));
return vertices;
```

```
this.setLayoutKnuth = function () {
const vertices = this.tree.verticesInOrder();
const depths = this.tree.depths;
for (let i = 0; i < vertices.length; i++) {
let vtx = vertices[i];
let depth = depths.get(vtx.id);
/* set vtx location to row depth, column i */
}
}
```

`lec13-binary-tree.zip`

**Aesthetic Principle 3.** If a node has two children, it’s $x$-coordinate should be the midpoint of its childrens’ $x$-coordinates

- How can we satisfy all three aesthetic principles?
- How can all be satisfied while also minimizing the width of the drawing?
- What tradeoffs are we forced to make balancinng these principles?