• Home
  • Textbooks
  • Mathematics for Game Programming and Computer Graphics: Explore the essential mathematics for creating, rendering, and manipulating 3D virtual environments
  • Mastering Affine Transformations

Mathematics for Game Programming and Computer Graphics: Explore the essential mathematics for creating, rendering, and manipulating 3D virtual environments

Penny de Byl

Chapter 12

Mastering Affine Transformations - all with Video Answers

Educators


Section 1

Translating points in 3D

Problem 1

Make a new Chapter_12 folder in PyCharm and copy the contents of the Chapter_11 folder into it.

Check back soon!

Problem 2

Create a new Python script called Scalingobjects.py and add a copy of the code from Vectors.py in Chapter_ 9 to it.

Check back soon!

Problem 3

When you run scalingobjects.py, you will notice a familiar scene of a blue grid with two cubes on top of each other. The whole scene will, however, be rotating, thanks to some leftover code in Object . py. Let's remove this as it will no longer be needed, and while we are modifying the code, we will add new lines to work with scaling.
Open object . py and modify the update method, like this:
def update (self, events = None):
glPushMatrix ()
for $c$ in self.components:
if isinstance (c, Transform) :
pos $=$ c.get_position ()
scale $=$ c.get_scale ()
glTranslatef(pos.x, pos.y, pos.z)
glscalef(scale.x, scale.y, scale.z)
elif isinstance (c, Mesh3D) :
.
This code gets the object's scale from the Transform class, and then uses the glScalef () OpenGL method to set the scales of the $x, y$, and $z$ coordinates separately.

Check back soon!

Problem 4

To accommodate the use of this scaling when the object is being drawn, we must update the Transform class thus:
class Transform:
def_init_(self, position=pygame. Vector3 $(0,0$,
$0)$, scale=pygame. $\operatorname{Vector3}(1,1,1))$ :
self.position $=$ pygame.Vector3 (position)
self.scale $=$ pygame. $\operatorname{Vector3}($ scale $)$
.
def get_scale(self) :
return self.scale
def set_scale(self, amount: pygame.Vector3):
self.scale = amount
This code adds scale as a property of the Trans form class as well as setting default values for the position and scale in the constructor. Note that a scale of 1 will do nothing to the object. At the end of the class, two new methods, get_scale () and set_scale (), are added to allow the scale to be set and retrieved as required.

Check back soon!

Problem 5

Finally, the code for Scalingobjects . py requires updating. We will only want one cube for now, so any other objects can be removed thus:
.
objects_3d $=[]$
objects_2d $=[]$
cube $=$ Object ("Cube")
cube.add_component (Transform $((0,0,-5)))$
cube.add_component (Cube (GL_POLYGON,
"images/wall.tif"))
objects_3d.append (cube)
grid $=\operatorname{Object}($ "Grid")
grid.add_component (Transform $((0,0,-5)))$
In the code you copied from Vectors . py in step 2, you will notice there is a second cube called cube 2 added. All references to this can be removed to leave just one object and the grid.

Check back soon!

Problem 6

In the same Scalingobjects. py code, references to cube2 can be removed before the main game loop, the spacebar controls removed, and the up- and down-arrow keys programmed to scale the cube up and down, like this:
.
glviewport (0, 0, screen.get_width(),
screen.get_height ())
glEnable (GL_DEPTH_TEST)
trans: Transform $=$ cube.get_component (Transform)
while not done:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
done = True
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
trans.set_scale(pygame.Vector3(2, 2, 2))
if keys[pygame.K_DOWN]:
trans.set_scale(pygame.Vector3(0.5, 0.5, 0.5))
glPushMatrix()

Check back soon!
01:50

Problem 7

When you run this, you will be able to scale the original cube by half by pressing the downarrow key and scale it by two using the up-arrow key, as shown in Figure 12.5:
(Figure can't copy)
Notice that when you press the arrow keys, the cube isn't continually rescaled, such that it won't get larger and larger or smaller and smaller, because it is always using the cube's original set of vertices from which the cube is scaled each time. I'll leave this particular functionality for you as the next challenge.

Julie Silva
Julie Silva
Numerade Educator