matrix
transformation given transformation’s geometric descriptionmatrix
and original image, draw the transformed imageWe illustrated the depth-first search algorithm on graphs
We illustrated the depth-first search algorithm on graphs
User drew input graph graph by hand
Input. A graph
Output. A drawing of the graph
Algorithms for drawing binary trees
A (rooted) binary tree consists of
satisfying:
V = {0, 1, 2, 3, 4}
root = 0
left(0) = 2, right(0) = 3
left(3) = 4, right(3) = 1
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
Aesthetic Principle 1. Vertices at the same depth should lie along a horizontal line with deeper nodes lower than shallower nodes.
Have to contend with width
How can we achieve minimum possible width subject to
Idea
Promise
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:
Map
:
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:
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
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