Announcements

Please check here weekly, and before your class, for announcements!
2026-02-25: The lab today, from 14:00 to 16:00 (group B4) will be moved on-line, Friday, 14:00-16:00 (as discussed with the B4 group).
2026-03-10, 2026-03-11: No lectures for Computer Graphics this week. Will recoup in week 8. There will be no lecture tests in week 8. This also applies for the A1 lab on Wednesday, 14:00-16:00. All the requirements for CG2 and SG2 are on the page.

2026-03-16: The CG lectures on 2026-03-17 and 2026-03-18 will be held on-line. So will the A1 lab on 2026-03-18.
2026-03-17T14:00-15:00: meet.google.com/fdv-zsys-fbe
2026-03-17T15:00-16:00: meet.google.com/grc-yjyv-vye
2026-03-17T16:00-17:00: meet.google.com/xvq-wciy-qoy
2026-03-17T17:00-18:00: meet.google.com/zqz-pgak-opm
2026-03-17T18:00 (thesis advising): meet.google.com/zvo-yhcm-tdn

2026-03-18T12:00-13:00: meet.google.com/kcq-eykk-ynw
2026-03-18T13:00-14:00: meet.google.com/sof-zyci-yyz
2026-03-18T14:00-15:00: meet.google.com/sbs-usit-qpx
2026-03-18T15:00-16:00: meet.google.com/piq-ewsq-gmf

2026-03-23: The lectures and the A1, B3 and B4 labs this week will be on-line.
2026-03-24T14:00: meet.google.com/qes-gxnz-pto
2026-03-24T16:00: meet.google.com/bth-qrex-ycs
2026-03-24T18:00: meet.google.com/jut-xfyw-ith

2026-03-25T12:00 (E): meet.google.com/sgz-fgdt-xoy
2026-03-25T14:00 (A1): meet.google.com/swd-qryf-ohs
2026-03-25T15:00 (A1): meet.google.com/fmj-pzmk-hum

2026-03-25T12:00-14:00 (B3): meet.google.com/hvq-hmbs-szg
2026-03-25T14:00-16:00 (B4): meet.google.com/fts-tpqu-dzb

2026-03-30: The lectures and the A1 lab will, once again, be held on-line this week.
2026-03-31T14:00: meet.google.com/zey-zhpz-wjs
2026-03-31T15:00: meet.google.com/xic-qvnj-tww
2026-03-31T16:00: meet.google.com/iks-mgtb-wzj
2026-03-31T17:00: meet.google.com/prc-ggdf-hma
2026-03-31T18:00: meet.google.com/bxu-dijk-rqx

2026-04-01T12:00: meet.google.com/awz-fpqa-kzo
2026-04-01T13:00: meet.google.com/vom-xmjn-fob
2026-04-01T14:00: meet.google.com/umn-epqt-gbz
2026-04-01T15:00: meet.google.com/aec-wqth-djy

2026-04-06: The lectures in week 8 will take place on Wednesday, 12:00, on-line. Link to be provided on the day. No CG labs on week 8.
2026-04-08T12:00: meet.google.com/rek-yweq-xmo

Basic Description


Topics: This subject teaches an introduction to Computer Graphics. The lectures represent a quick overview, covering topics such as graphics pipelines, rasterisation, 3D geometry, shaders, but also touching on adjacent numerical simulation and scientific data plotting.
Labs: Students, working in teams of 2, implement a subset of the topics covered by the lectures. Those are organised in two tracks (Computer Graphics and Scientific Graphics), each track having 4 sets of tasks as homework.
Computer Graphics track: This track's 4 sets of tasks are centred on: basic fractal drawing, rasterisation, 3D geometry, and shaders.
Scientific Graphics track: This track's 4 sets of tasks are about: 2D function plotting in OpenGL, 2D function plotting in LaTeX, 3D plotting in LaTeX using PGFPplots and GNUPlot, numerical simulation.

Grading, practical: each set of tasks has a work time of 2 weeks, and receives between 0 and 5 points upon evaluation. Delays are penalised 10% per week. A student needs at least 8 points in order to pass the practical part of this subject, out of a total maximum of 20.
Grading, theoretical: during lectures, students may be individually tested with short written tests about the theoretical aspects of previous lectures. Students will receive up to 10 points during the whole semester. There is no minimal number of points required here.
Final grade: The grade is determined by summing up the points (up to 20 from homework and 10 from lecture tests), and dividing by 3. This number, rounded to the nearest integer, yields the final grade. This grade needs to be at least 5. (Therefore, a student needs at least 13.5 points overall, out of which at least 8 from homework). In short: Hw >= 8; Round( (Hw + Lect) / 3) >= 5.

Notes: Students will be evaluated on how well they can explain their work and theoretical knowledge. Within a team, students may receive different grades, if the quality of their explanations differs. Students are required to send their homework electronically, and delays are counted from when the homework is received. A week ends Sunday, 24:00 (as in, just past 23:59), local time.

First lab: For the first lab, please make sure you have a functional C++ working environment. To be sure, make a Hello World and run it. It would also be great to install the GLUT library, as this would save you time during the lab.

Tutorial

In the first lab, you should create a functional OpenGL program. Please consider downloading and reading the example files.
You are not required to solve the small tasks in this example, but you are required to understand and be able to explain the code, as this example forms the basis for future homework (and solving the tasks will help you). Please read the extensive comments.

The following is a tutorial for Visual Studio (but not VS Code!), as path definitions within VS projects can make local library dependencies confusing. (If you prefer to use another IDE, please do.)
  • Download and extract cg0.zip and freeglut.zip .
  • Start with an empty C++ project. (If your version of C++ doesn't have the option for empty C++ projects, create a C++ console application, and check the options to have it be an empty project.)
  • Create an empty .cpp file within your project in Visual Studio.
  • !! Do not add the pre-existing cg0.cpp file into your project, as this would scramble the paths in your project.
  • Copy-paste the contents of cg0.cpp from the archive to the .cpp file in your project.
  • Close cg0.cpp. Delete it.
  • If your code has the line '#include <GL/glut.h>', change it to #include "glut.h".
  • Open the directory of your project (you can do this from the side-panel in Visual Studio).
  • Copy-paste (not move) the contents of freeglut.zip to your project, making sure glut.h is in the same directory as your project's .cpp file.
  • Attempt to build and run your project.
  • If building fails, re-check previous steps, or ask colleagues for help.
  • If building succeeds, but running fails, that's fine. Navigate to where your project's .exe file resides, and copy the .dll there. You should now be able to run the program.
  • Press the keys 1, 2, 3, 4.


In other IDEs: install glut/freeglut, add it as a dependency or use the enclosed Makefile.

Example running from console:
Debian/Ubuntu and variants:
  • Update package index: $ sudo apt-get update
  • Install: $ sudo apt-get install g++ freeglut3-dev
  • Build the binary: $ g++ -o cg0.bin cg0.cpp -lGL -lGLU -lglut
  • Run the binary: $ ./cg0.bin

Arch / Manjaro:
  • Update package index: $ sudo pacman -Syu
  • Test you have g++ available: $ g++ --version
  • Search for freeglut: $ sudo pacman -Ss freeglut
  • Install freeglut: use the package name found above $ sudo pacman -S "packageName" Could be as simple as: sudo pacman -S freeglut
  • Build the binary: $ g++ -o cg0.bin cg0.cpp -lGL -lGLU -lglut
  • Run the binary: $ ./cg0.bin

MSYS:
  • Make sure to run MSYS2 MINGW64 (or adapt this tutorial to the version you use, such as MSYS or UCRT64).
  • Update package index: $ pacman -Syu
  • Install gcc. First search: $ pacman -Ss gcc Then install the appropriate version, e.g. $ pacman -S mingw64/mingw-w64-x86_64-gcc
  • Test you have g++ available: $ g++ --version
  • Search for and install Mesa (which provides OpenGL): $ pacman -Ss mesa $ pacman -S mingw64/mingw-w64-x86_64-mesa
  • Search for and install Freeglut: $ pacman -Ss freeglut $ pacman -S mingw64/mingw-w64-x86_64-freeglut
  • Build the binary. Due to the library names on MINGW, you need to change the linking flags: $ g++ -o cg0.bin cg0.cpp -lopengl32 -lglu32 -lfreeglut
  • Run the binary: $ ./cg0.bin


The basic example file: cg0.zip
The required MSVC library files: freeglut.zip


Alternatively, a Python OpenGL program. Largely equivalent. cg0.py

Homework



Homework upload form: here .
The registation numbers (ro: nr. matricol) for all team members are mandatory.
Please consider uploading after your evaluation, if you still have time until the deadline, to make sure everything is OK with your file.
Homework assignment number Computer Graphics track Scientific Graphics track Lab discussion week Deadline week
1 cg1.cpp Fractal drawing sg1.cpp 2D function plotting 2 4
2 Rasterisation. Source file not provided, please read the task. sg2.tex 2D plotting in LaTeX. 4 6
3 cg3.cpp 3D geometry sg3.tex 3D plotting in LaTeX 6 8
4 Shaders: cg4.html webgl-utils.js MatrixOperations.js Numerical simulation: sg4.py 9 -

CG1

Fractal drawing in OpenGL.
We'll cover two kinds of fractals - those which can be drawn line-by-line, and those which can be drawn pixel-by-pixel. Additionally, the example code is substantial, and you are required to understand it (except the commented utility functions).
For the first kind of fractal, we're using a Turtle Graphics class. You can think of a Turtle as a very simple robot which has a position, faces a certain direction, and can move a specified distance. If it leaves a trail as it moves, we can draw lines with it.

The following line fractals are drawn recursively. We start by drawing a line but, instead of drawing it, replace it with another pattern, and recurse on each of the lines in the pattern. Only upon reaching the max recursion level do we draw a simple line (and the pattern emerges).

The Koch Snowflake starts from a triangle. The recursive step consists of extruding the middle third of each line into the other two sides of an equilateral triangle (so the line has a 'shark fin'). The circle is drawn to show that the snowflake's limit touches a circle.


The binary tree fractal is quite simple; each line sprouts another two lines, half in length, at 45 degree angles.


1.1) You'll receive 1.5 points for the recursive-square fractal below. Make sure all the image elements are there, and the recursion level and images match. You are not allowed to directly use glBegin(). Use only Turtle Graphics.


1.2) You'll receive 1.5 points for the hex-line fractal below. Make sure that the recursion level and images match. Use only Turtle Graphics.


The Julia-Fatou set is a fractal which can give interesting images while being sampled pixel-by-pixel.


Each point in the JF fractal exists in a 4-dimensional hyperspace. By freezing two dimensions, we can sample a 2D slice of that space, and display it. If we have a function JF(x, y, a, b), x and y can be screen coordinates, and a and b are the constants on the frozen dimensions.
JF computations make sense for complex numbers, so, the first thing is to make two complex numbers: \(z_0 = x + yi, \; c = a + bi \).
Then, a number sequence \( \left( z_n \right)_{n\in\mathbb{N}} \) is generated using the following rule: \( z_{n+1} = z_n^2 + c \).
If this number sequence converges to a finite (complex) value, we consider it to be inside the JF set (and can draw it in a certain colour).
If the sequence converges to infinity (it diverges), we consider it to be outside the JF set (and can draw it in a different colour).
The fractal arises from the shape of the boundary, which, for certain values of a and b, can be of infinite length (in a finite area).

The interesting things happen in the space \( \left[ -2, 2 \right]^4 \). We test the limit of the number sequence numerically, not analytically, by generating new elements in the sequence, and seeing if their complex magnitude exceeds a certain radius. The minimal radius is 2 (but can be increased, to reduce the rate of false positives in divergence detection), and the number of elements generated can be above 50 (but can be increased, to reduce the rate of false negatives in divergence detection, at a cost of requiring more computational power).

If the JF fractal is sampled by freezing two dimensions in the 4D space (and can therefore generate an infinite number of orthogonal slices), the Mandelbrot fractal is sampled across the first diagonal plane.
MB(x, y) = JF(x, y, x, y). (In complex arguments, MB(z0) = JF(z0, z0)).

2.1) You'll receive 1 point for a simple two-colour Mandelbrot fractal,
2.2) and another 1 points (2 in total) for displaying it with a gradient, palette, or rainbow of colours.

SG1

2D function plotting in OpenGL.
Examples:
1) Nicomedes' Conchoid:
\(x = a + b \cdot cos(t),\; y = a \cdot tg(t) + b \cdot sin(t) \; \) or
\(x = a - b \cdot cos(t),\; y = a \cdot tg(t) - b \cdot sin(t) \; \) where
\(t \in (-\pi / 2, \pi / 2) \)
which can also be written as:
\(x = a \pm b \cdot cos(t),\; y = a \cdot tg(t) \pm b \cdot sin(t), \; t \in (-\pi / 2, \pi / 2) \)
Nicomedes' Conchoid

2) Modulated sinusoid:
\(f(x) = \left| sin(x) \right| \cdot e^{-sin(x)}, x \in \left[ 0, 8 \cdot \pi \right] \)
Modulated sinusoid


Tasks to solve:
In general, respect borders, proportions, and do not miss plot elements. Do not join elements when they're supposed to be split, nor split them if they should be joined.
Colour patterns are not mandatory - you can draw every plot in black.
1) 1 point to plot the following function:
\( f(x) = \left\{ \begin{array}{cl} 1 & x = 0 \\ \frac{d(x)}{x} & x \gt 0\\ \end{array} \right. \)
where \(d(x)\) is the distance between x and the closest integer, and \( x \in [0, 100] \)
Function 3

2) 1 point to plot the following 4 functions;

2) Circle Concoid (Limaçon, Pascal's Snail):
\(x = 2 \cdot (a \cdot cos(t) + b) \cdot cos(t), \; y = 2 \cdot (a \cdot cos(t) + b) \cdot sin(t), \; t \in (-\pi, \pi)\) .
For this plot, \(a = 0.3, \; b = 0.2\) .
Function 4

2) Cicloid:
\(x = a \cdot t - b \cdot sin(t), \; y = a - b \cdot cos(t), \; t \in \mathbb{R} \) .
For this plot, \(a = 0.1, \; b = 0.2\) .
Make sure to scale each axis properly.
Function 5

2) Epicicloid:
\(x = (a + b) \cdot cos\left( \frac{b}{a} \cdot t \right) - b \cdot cos\left(t + \frac{b}{a}\cdot t \right) \)
\(y = (a + b) \cdot sin\left( \frac{b}{a} \cdot t \right) - b \cdot sin\left(t + \frac{b}{a}\cdot t \right) \)
\( t \in \left[ 0, 2\pi \right] \) .
For this plot, \(a = 0.1, \; b = 0.3\) .
Function 6

2) Hipocicloid:
\(x = (a - b) \cdot cos\left( \frac{b}{a} \cdot t \right) - b \cdot cos\left(t - \frac{b}{a}\cdot t \right) \)
\(y = (a - b) \cdot sin\left( \frac{b}{a} \cdot t \right) - b \cdot sin\left(t - \frac{b}{a}\cdot t \right) \)
\( t \in \left[ 0, 2\pi \right] \) .
For this plot, \(a = 0.1, \; b = 0.3\) .
Function 7

3) 1 point to create a generic plotting function which plots the above 4 functions.
E.g.:
void plot(double (*x)(double, double, double), double (*y)(double, double, double), double a, double b, double intervalStart, double intervalEnd, double step = 0.05, double scaleX = 1, double scaleY = 1, GLint primitive = GL_LINE_STRIP);

4) 1 point to plot the following 2 polar functions (it is possible to use the generic plotting function from 3) ):
Polar functions are defined according to the angle (t) and radius (r).
Afterwards, we convert them to Cartesian coordinates:
\( x = r \cdot cos(t), \; y = r \cdot sin(t) \)

4) Logarithmic spiral:
\( r = a \cdot e^{1+t}, \; t \in (0, \infty) \) .
For this plot, \(a = 0.02\) .
You don't need to get precisely this plot. The spiral may extend in whichever direction.
Function 8

4) Sine polar flower:
\( r = sin(a \cdot t), \; t \in \left[ 0, 2 \pi \right] \) .
For this plot, \(a = 10\), and the number of 'petals' is \( 2 \cdot a \). Think about why.
Make sure to have the plot properly rounded.
Function 9

5) 0.5 Points to obtain the following drawing;
0.5 points to provide a mathematical explanation for it during evaluation (on paper, .pdf/LaTeX file, Jupyter notebook etc.). You need not send the explanation (as you're required to upload a single file).
The following function doesn't yield quite this plot; you need to slightly manipulate its definition, use it to generate the edge of the plot, and fill it in with triangles with your own algorithm. (You're required to provide a mathematical explanation of the function definition manipulation, not the triangle-drawing algorithm.)
Longchamps' Trisectrix (Equilateral Trefoil):
\(\displaystyle x = \frac{a}{4 \cdot cos^2(t) - 3}, \; y = \frac{a \cdot tg(t)}{4 \cdot cos^2(t) - 3}, \; t \in (-\pi/2, \pi/2) \setminus \{ -\pi/6, \pi/6 \}\) .
For this plot, \(a = 0.2\) .
You don't need to get the precisely same triangles, and small defects are acceptable (such as the red triangle on the very left in the image below). However, the plot of the function needs to be accurate, without any additional lines drawn.
Function 10 Function 10

CG2


Rasterisation: the mid-point algorithm for the line segment and circle.
For this homework, you will not have a starting source file provided. You may start from previous ones, e.g. cg0.
Your algorithmic task is to implement Bresenham's mid-point algorithm for rasterising the line and circle.
In order to view the results of the algorithm, you also need to implement a small library which can draw a raster grid, and draw pixels on it.

Tasks:
1) (2 points) Implement a library which can draw a raster grid, can draw discs on it, signifying pixels on the grid, and can also draw virtual geometric primitives (line segment and circle).
Grid Self-scaling grid
1.*) Requirements (with penalties inside parentheses, minimum points = 0):
1.1) (-0.5 points) The cells of the grid must remain square, visually, no matter how stretched the window is.
1.2) (-1 point) You must only use glBegin() inside this library; also, you must draw your pixels using a function taking integer values for the coordinates.
1.3) (-0.5 points) The discs must be distinct discs, not squares, cut/partial/joined discs, etc.
1.4) (-0.5 points) Draw the geometric primitives you rasterise (the blue lines in the images above).
1.5) (-0.5 points) You must draw lines thicker than 1 disc, as seen in the images above.

2) (1.5 points) Implement Bresenham's mid-point line rasterisation algorithm.
Self-scaling grid
2.*) Requirements (with penalties inside parentheses, minimum points = 0):
2.1) (-1.2 points - so, at most 0.3 points) You must implement Bresenham's mid-point algorithm; simpler, less efficient algorithms receive far fewer points.
2.2) (-0.5) Your algorithm must do all computations in the loop using additions / subtractions. Multiplications are only allowed before the algorithm's loop, for variable initialisation.
2.3) (-0.5) You must draw lines of any slope; with the 2.2) condition, this means you must implement 4 sub-algorithms.
2.4) (-1.5, down 0 points) You must draw, minimally, at least 2 octants, with 2 distinct functions. Drawing a single octant will receive 0 points.
Do note that, in the image above, the lines are never vertical / horizontal / first diagonal. You may draw another shape, as long as all octants are displayed, and the pixels clearly visible and separable.

3) (1.5 points) Implement the mid-point circle rasterisation algorithm.
Self-scaling grid
3.*) Requirements (with penalties inside parentheses, minimum points = 0):
3.1) (-1.0) You must implement the circle mid-point algorithm without multiplications inside the loop; using multiplications inside the loop receives the penalty.
3.2) (-1.5) You must implement the algorithm using only integer computations.
3.3) (-0.5) You must draw all 8 octants (using 4 distinct functions).
3.4) (-1.5) You must draw, minimally, at least 2 octants, with 2 distinct functions. Drawing a single octant will receive 0 points.
3.5) (-0.5) You must also fill the inside of the circle.
Self-scaling grid

SG2


You should produce a .pdf file similar to: sg2.pdf.
Your tasks are:
1) (1 point) Draw the hexagons as in Fig. Task 1.
2) (1 point) Draw the Circle Concoid as in Fig. Task 2. Make sure the drawing is not interrupted. See SG1 for the function definition.
3) (1 point) Draw the polar flower as in Fig. Task 3. See SG1 for the function definition.
4) (1 point) Draw the full MPG file, as in Fig. 4. The data might be incomplete, make sure to clean it manually first (search for '?' characters). For this sub-task, you only need the blue marks, not the red line.
5) (1 point) Draw a regression of the data (as in Fig. 4, the red line). You need to work externally, e.g. in R. You need to do the subtask 4) to do 5). You need to provide an explanation of your regression during the lab.
Alternatively, you may plot another data file (such as Iris) at 4), or plot another refinement of the data at 5). You also need to explain your refinement, be it regression, clustering, pie chart division, etc.
https://pgfplots.sourceforge.net/gallery.html might be a useful gallery for plots.

CG3


3D Geometry: transforms and projections.
The basic program shows how you can set up an orthogonal projection, set objects in the scene, and animate a smooth rotation.
You are required to:


1) (2 points) Decompose a rotation along the first diagonal (glRotatef(angle, 1, 1, 1)) in a series of rotations along the axes (glRotatef(angleX, 1, 0, 0), glRotatef(angleY, 0, 1, 0), glRotatef(angleZ, 0, 0, 1)). You may change the first image, and there is no need to maintain the animation.
You will receive 0 points if you use a glRotate() function which doesn't have at least two 0 values as arguments (i.e. rotate by a vector which is not one of the axes of the coordinate system) .
+0.5 points if you smoothly animate the intermediate rotations.
(-1.5 points) You must do the symbolic decomposition - you will receive at most 0.5 points here if you e.g. perform small rotations and check coordinate values.
Hint: if you need to rotate along the first diagonal, and you're only allowed to rotate along an axis, you must make the first diagonal be an axis.



2) (0.5 points) Draw the following two images. The only difference between the two must be a small rotation (e.g. by -10 degrees along the axis \(Oy\) ).
Task 2 Task 2

3) (0.5 points) Draw the following two images. The only difference between the two must be a small rotation (e.g. by -10 degrees along the axis \(Oy\) ).
Task 3 Task 3

4) (2 points) Draw the following image. Please pay attention to the image details, to understand the correct task you must perform.
Task 4
4) (-0.5 points) If you obtain the following image, you are close to the correct solution.
Task 4

General advice: you need to understand rotation, translation and scaling, as well as the different types of projections, in order to see, from the given images, which transform / projection is required. If you want to implement general matrix math in your code (such as matrix * vector multiplication), you are allowed to do so; but, if you only need matrix multiplication, look up the function glMultMatrix(\( \cdot \)) .
You may not change the shape of the cube (i.e. you must start with a cube, and only through the stadard geometric transforms and projections can the image of the cube be changed); if more than one cube is required in a scene, both must be the same size (again, as you draw them in code, and the standard transforms and projections can change the produced image).

SG3


You should produce a .pdf file similar to: sg3.pdf.
You need to either set-up gnuplot on your system, or use LuaLaTeX. 3D plots require computing many points, and the old pdflatex engine is too slow. If you're working on e.g. Overleaf, please test that you can produce the required .pdf files, otherwise, you might need to install a local LaTeX distribution.
Your tasks are:
1) (2 points) Plot Rastrigin's Function as described in the .pdf file.
2) (2 points) Plot a 3D scatterplot of the Iris dataset, where each label is plotted differently (either mark shape or colour).
3) (1 point) Draw an useful explanation for the dataset on the scatterplot. Such as: draw separating planes between clusters, or draw the clusters as clouds, or manage to draw all the 4 features (add Petal width) on the 3D plot.
You may choose a different dataset and solve the tasks above.

CG4


You should work with the provided .html file, and change only the shaders within to achieve the requirements.
While you need to use the two included .js files, you don't need to read them. (Nor should you upload them as homework.)
The provided .html displays some cubes, which bounce up and down:


You need to obtain something similar to:


The sub-tasks are:
1) (2p) Make the cubes rotate around the centre of the window, in a circle or ellipse, instead of just bouncing up and down.
2) (1.5p) Colour the cubes (at least one colour channel) depending on the x, y or z coordinate of the window or of the scene. (The colour already depends on the x, y and z coordinate of the cube, relative to itself, so that will not be given points.)
3) (1.5p) Make the colour of the cubes depend on time. In the example above, the vertical red lines move along the x axis as time passes.
The relevant parts of the .html files are marked with comments.

SG4


You should work with the provided .py file, changing only the numerical integration part, and simulate the motion of the particles:



The sub-tasks are:
1) (1p) Integrate the speed of each object, so that the speed changes position.
2) (1p) Also integrate the acceleration, so it influences speed.
3) (1p) Do a correct integration with the above, e.g. semi-implicit Euler (also called symplectic Euler), or the more advanced Runge-Kutta 4. Semi-implicit Euler, for a positive delta-time, requires speed be updated first, and then position (using the updated speed).
4) (1p) Do particle collision with the bounding box.
5) (1p) Apply collision elasticity (0.5p) and collision friction (0.5p).

Lecture Slides