CT336/CT404
Graphics & Image Processing
Section 3
Transformations
[Translation, Rotation and Scaling]
3D: X3D
2D: Canvas
3D Translation
To translate a 3D point, modify each dimension
separately:
x' = x + a1
y' = y + a2
z' = z + a3
Or in Matrix format:
3D Rotation: axis of rotation
In 3D, we need to specify not only
the angle (or amount) of rotation,
but also the axis of rotation
The “Right Hand Rule” for
rotations: grasp axis with right hand
with thumb oriented in positive
direction of axis
Your fingers will then curl in the
direction of positive rotation for
that axis
Rotation about the Principle
Axes
These matrices define
rotations by angle
about the principle
axes
As a point rotates
about the x axis, its x
component remains
unchanged
To use one of these
matrices, multiply
your [x y z] matrix by
it, e.g.
[x' y' z'] = [x y z] RX
Transformations in X3D
A 3D coordinate system is a set of X, Y and Z axes that cross
at an origin. Positions within a coordinate system are
specified by X, Y and Z distances measured along each of the
axes
In X3D, translation, rotation and scaling of shapes are all
accomplished using the Transform node
A Transform node defines a child or nested coordinate
system: any shapes contained within it will be centred on the
origin of its own coordinate system
The top-most coordinate system is called the root or world
coordinate system
Nested Coordinate Systems
(Top): a nested coordinate
system defined as a translation
relative to the world coordinate
system by -3.0 units along the X
axis, 2.0 units along the Y axis,
and 2.0 units along the Z axis
(Bottom): A box shape
contained in this nested coordinate system
Why Nested Coordinate
Systems are Useful
Consider the steps required to build a room with a table and a lamp on it:
Build a lamp, with each component relative to a lamp coordinate system
Build a table, with each component relative to a table coordinate system
Place the lamp on the table by nesting the lamp coordinate system in the
table coordinate system
Build a room, with each component relative to a room coordinate system
Place the table (and its lamp) by nesting the table coordinate system in the
room coordinate system
This approach has allowed us to build each piece of the world
independently: the structure of the lamp, for example, is independent of
where it is placed on the table.
This helps manage complexity as well as promote reusability and
simplify the transformations of objects composed of multiple primitive
shapes
The X3D Transform Node
The Transform node provides the functionality of translation, rotation
and scaling
Its children are typically Shape nodes and further Transform nodes
By putting a Transform node inside (as a child of) another transform
node, you are creating a child/nested coordinate system
< Transform
bboxCenter='0 0 0'
bboxSize='-1 -1 -1'
center='0 0 0'
rotation='0 0 1 0'
scale='1 1 1'
translation='0 0 0'
>
</Transform>
(These are the default values
for the fields)
X3D Translation Example
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "http://www.web3d.org/specifications/x3d-3.0.dtd">
<X3D xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' profile='Full' version='3.0'
xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-3.0.xsd'>
<Scene DEF='scene'>
<Transform translation='2 1 -2'>
<Shape>
<Appearance>
<Material/>
</Appearance>
<Cylinder/>
</Shape>
</Transform>
</Scene>
</X3D>
X3D Nested Coordinate
System Example – a hut
<Scene DEF='scene'>
<Group>
<Shape>
<Appearance>
<Material diffuseColor='0.7 0.0 0.2'/>
</Appearance>
<Cylinder radius='2'/>
</Shape>
<Transform translation='0 2 0'>
<Shape>
<Appearance>
<Material diffuseColor='0.7 0.0 0.7'/>
</Appearance>
<Cone bottomRadius='2.5'/>
</Shape>
</Transform>
</Group>
</Scene>
X3D Example – Two
archways on the ground
<Scene DEF='scene'>
<Group>
<Shape>
<Appearance DEF='White'>
<Material/>
</Appearance>
<Box size='25 0.1 25'/>
</Shape>
<Transform DEF='LeftColumn'
translation='-2 3 0'>
<Shape DEF='Column'>
<Appearance USE='White'/>
<Cylinder height='6' radius='0.3'/>
</Shape>
</Transform>
<Transform DEF='RightColumn'
translation='2 3 0'>
<Shape USE='Column'/>
</Transform>
<Transform DEF='ArchwaySpan'
translation='0 6.05 0'>
<Shape>
<Appearance USE='White'/>
<Box size='4.6 0.4 0.6'/>
</Shape>
</Transform>
<Transform translation='0 0 -2'>
<Transform USE='LeftColumn'/>
<Transform USE='RightColumn'/>
<Transform USE='ArchwaySpan'/>
</Transform>
</Group>
</Scene>
X/Y/Z Rotations: Pitch, Yaw,
Roll
Rotation about the x axis is often
called ‘pitch’
Rotation about the y axis is often
called ‘yaw’
Rotation about the z axis is often
called ‘roll’
Since all components of this
aeroplane are inside its coordinate
system, transformations of that
coordinate system will preserve the
relative positions of the components
Rotation using the
Transform Node
In X3D, you can rotate about any line, not just the principal
axes.
You specify a 3D co-ordinate, and the axis of rotation is
defined as the line that joins the origin to this point.
e.g. a toy spinning top will rotate about the Y axis, defined as (0.0,
1.0, 0.0)
You must also specify the amount to rotate by: this is
measured as an angle in Radians
Hence, rotations are defined using 4 numbers: the first 3
define the axis and the 4th defines the angle (amount)
the centre of rotation is, by default, the origin of the
coordinate system. To change this, specify a 3D co-ordinate
in the transform node's center field
Rotation Example
<Scene DEF='scene'>
<Transform rotation='1 0 0 -0.785'>
<Shape>
<Appearance>
<Material/>
</Appearance>
<Box/>
</Shape>
</Transform>
</Scene>
Example
<Scene DEF='scene'>
<Group>
<Shape DEF='Arm1'>
<Appearance>
<Material/>
</Appearance>
<Cylinder height='1' radius='0.1'/>
</Shape>
<Transform rotation='0 0 1 1.047'>
<Shape USE='Arm1'/>
</Transform>
<Transform rotation='0 0 1 2.094'>
<Shape USE='Arm1'/>
</Transform>
</Group>
</Scene>
Another Example
<Scene DEF='scene'>
<Group>
<Shape DEF='Arm1'>
<Appearance>
<Material/>
</Appearance>
<Cylinder height='1' radius='0.1'/>
</Shape>
<Transform DEF='Arm2' rotation='0 0 1 1.047'>
<Shape USE='Arm1'/>
</Transform>
<Transform DEF='Arm3' rotation='0 0 1 2.094'>
<Shape USE='Arm1'/>
</Transform>
<Transform rotation='0 1 0 1.785'>
<Transform USE='Arm2'/>
<Transform USE='Arm3'/>
</Transform>
</Group>
</Scene>
Example using centre of
rotation
<Scene DEF='scene'>
<Group>
<Shape>
<Appearance DEF='White'>
<Material/>
</Appearance>
<Cylinder height='0.01' radius='0.1'/>
</Shape>
<Transform center='0 -0.15 0' rotation='1 0 0 -0.7' translation='0 0.15 0'>
<Shape DEF='LampArm'>
<Appearance USE='White'/>
<Cylinder height='0.3' radius='0.01'/>
</Shape>
<Transform center='0 -0.15 0' rotation='1 0 0 1.9' translation='0 0.3 0'>
<Shape USE='LampArm'/>
</Transform>
</Transform>
</Group>
</Scene>
Scaling in X3D
The Transform node allows you to scale a co-ordinate system's
size relative to its parent co-ordinate system
The scale is specified as a multiplication factor: to make
something half of its original size, its scale factor is 0.5, while to
make it triple its original size, its scale factor is 3.0
The Transform node's scale field uses three scale factors: one for
each axis. By using different numbers here, you will scale a coordinate system by different amounts in the different directions.
The transform node's scaleOrientation field allows you to specify
a rotation prior to scaling, thereby enabling you to stretch a shape
in any direction, not just along the principal axes
The transform node's center field defines the centre point for
scaling (as well as rotation). This allows you to scale a shape
without moving it (e.g. a growing tree)
Scaling Example
<Scene DEF='scene'>
<Group>
<Transform DEF='Wing' scale='0.5 1 1.5'>
<Shape>
<Appearance DEF='White'>
<Material/>
</Appearance>
<Cylinder height='0.025'/>
</Shape>
</Transform>
<Transform DEF='Fuselage' scale='2 0.2 0.5'>
<Shape>
Fuselage
<Appearance USE='White'/>
<Sphere/>
</Shape>
Wing
</Transform>
<Transform scale='0.3 2 0.75'>
<Transform USE='Wing'/>
<Transform USE='Fuselage'/>
</Transform>
</Group>
</Scene>
2D Translations with Canvas
<html>
<head>
<script>
function draw() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.save(); // save the default (root) co-ord system
canvasTranslateExample.html
context.fillStyle="#CC00FF"; // purple
context.fillRect(100,0,100,100);
// translates from the origin, producing a nested co-ordinate system
context.translate(75,50);
context.fillStyle="#FFFF00"; // yellow
context.fillRect(100,0,100,100);
// transforms further, to produce another nested co-ord system
context.translate(75,50);
context.fillStyle="#0000FF"; // blue
context.fillRect(100,0,100,100);
context.restore(); // recover the default (root) co-ord system
context.translate(-75,90);
context.fillStyle="#00FF00"; // green
context.fillRect(100,0,100,100);
}
</script>
</head>
These coordinate systems are
nested
<body onload="draw();">
<canvas id="canvas" width="600" height="600"></canvas>
</body>
</html>
Order of Transformations
Rotation by 45 degrees
Then Translation 2 units
along the red axis
Translation 2 units along the
red axis
Then Rotation by 45 degrees
Order of Transforms example
canvasOrderOfTransformsExample.html
<html>
<head>
<script>
function draw() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.save(); // save the default (root) co-ord system
context.fillStyle="#CC00FF"; // purple
context.fillRect(0,0,100,100); // positioned with TL corner at 0,0
// translate then rotate
context.translate(100,0);
context.rotate(Math.PI/3);
context.fillStyle="#FF0000"; // red
context.fillRect(0,0,100,100); // positioned with TL corner at 0,0
// recover the root co-ord system
context.restore();
// rotate then translate
context.rotate(Math.PI/3);
context.translate(100,0);
context.fillStyle="#FFFF00"; // yellow
context.fillRect(0,0,100,100); // positioned with TL corner at 0,0
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="600" height="600"></canvas>
</body>
</html>
Canvas scale example
canvasScaleExample.html
<html>
<head>
<script>
function draw() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.fillStyle="#CC00FF"; // purple
context.fillRect(0,0,100,100); // positioned with TL corner at 0,0
context.translate(150,0);
context.scale(2,1.5);
context.fillStyle="#FF0000"; // red
context.fillRect(0,0,100,100); // positioned with TL corner at 0,0
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="600" height="600"></canvas>
</body>
</html>
Canvas: programmatic
graphics example
canvasRotateLoopExample.html
<html>
<head>
<script>
function draw() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.translate(150,150);
for (i=0;i<15;i++) {
context.fillStyle = "rgb("+(i*255/15)+",0,0)";
context.fillRect(0,0,100,100);
context.rotate(2*Math.PI/15);
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="600" height="600"></canvas>
</body>
</html>
© Copyright 2026 Paperzz