Section 3 Transformations [Translation, Rotation and Scaling]
Transcript of Section 3 Transformations [Translation, Rotation and Scaling]
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 co-ordinate 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 co-ordinate 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>
<Appearance USE='White'/>
<Sphere/>
</Shape>
</Transform>
<Transform scale='0.3 2 0.75'>
<Transform USE='Wing'/>
<Transform USE='Fuselage'/>
</Transform>
</Group>
</Scene>
Wing
Fuselage
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
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>
<body onload="draw();">
<canvas id="canvas" width="600" height="600"></canvas>
</body>
</html>
canvasTranslateExample.html
These coordinate systems are
nested
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
<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>
canvasOrderOfTransformsExample.html
Canvas scale example
<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>
canvasScaleExample.html
Canvas: programmatic graphics example
<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>
canvasRotateLoopExample.html