[CT404]: Add Week 1 lecture notes
@ -28,6 +28,8 @@
|
|||||||
\usepackage[final, colorlinks = false, urlcolor = linkblue]{hyperref}
|
\usepackage[final, colorlinks = false, urlcolor = linkblue]{hyperref}
|
||||||
% \newcommand{\secref}[1]{\textbf{§~\nameref{#1}}}
|
% \newcommand{\secref}[1]{\textbf{§~\nameref{#1}}}
|
||||||
\newcommand{\secref}[1]{\textbf{§\ref{#1}~\nameref{#1}}}
|
\newcommand{\secref}[1]{\textbf{§\ref{#1}~\nameref{#1}}}
|
||||||
|
\usepackage{multicol}
|
||||||
|
\usepackage{amsmath}
|
||||||
|
|
||||||
\usepackage{changepage} % adjust margins on the fly
|
\usepackage{changepage} % adjust margins on the fly
|
||||||
|
|
||||||
@ -67,6 +69,8 @@
|
|||||||
\hrule
|
\hrule
|
||||||
|
|
||||||
\vfill
|
\vfill
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\textwidth]{images/cover.png}
|
||||||
\vfill
|
\vfill
|
||||||
|
|
||||||
\hrule
|
\hrule
|
||||||
@ -97,5 +101,490 @@
|
|||||||
\pagenumbering{arabic}
|
\pagenumbering{arabic}
|
||||||
|
|
||||||
\section{Introduction}
|
\section{Introduction}
|
||||||
|
Textbooks:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Main textbook: \textit{Image Processing and Analysis} -- Stan Birchfield (ISBN: 978-1285179520).
|
||||||
|
\item \textit{Introduction to Computer Graphics} -- David J. Eck. (Available online at \url{https://math.hws.edu/graphicsbook/}).
|
||||||
|
\item \textit{Computer Graphics: Principles and Practice} -- John F. Hughes et al. (ISBN: 0-321-39952-8).
|
||||||
|
\item \textit{Computer Vision: Algorithms and Applications} -- Richard Szeliski (ISBN: 978-3-030-34371-2).
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\textbf{Computer graphics} is the processing \& displaying of images of objects that exist conceptually rather than
|
||||||
|
physically with emphasis on the generation of an image from a model of the objects, illumination, etc. and the
|
||||||
|
real-time rendering of images.
|
||||||
|
Ideas from 2D graphics extend to 3D graphics.
|
||||||
|
\\\\
|
||||||
|
\textbf{Digital Image processing/analysis} is the processing \& display of images of real objects, with an emphasis
|
||||||
|
on the modification and/or analysis of the image in order to automatically or semi-automatically extract useful
|
||||||
|
information.
|
||||||
|
Image processing leads to more advanced feature extraction \& pattern recognition techniques for image analysis \&
|
||||||
|
understanding.
|
||||||
|
|
||||||
|
\subsection{Grading}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Assignments: 30\%.
|
||||||
|
\item Final Exam: 70\%.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\subsubsection{Reflection on Exams}
|
||||||
|
``A lot of people give far too little detail in these questions, and/or don't address the discussion
|
||||||
|
parts -- they just give some high-level definitions and consider it done -- which isn't enough for
|
||||||
|
final year undergrad, and isn't answering the question.
|
||||||
|
More is expected in answers than just repeating what's in my slides.
|
||||||
|
The top performers demonstrate a higher level of understanding and synthesis as well as more
|
||||||
|
detail about techniques and discussion of what they do on a technical level and how they fit
|
||||||
|
together''
|
||||||
|
|
||||||
|
\subsection{Lecturer Contact Information}
|
||||||
|
\begin{multicols}{2}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Dr. Nazre Batool.
|
||||||
|
\item \href{mailto://nazre.batool@universityofgalway.ie}{\texttt{nazre.batool@universityofgalway.ie}}
|
||||||
|
\item Office Hours: Thursdays 16:00 -- 17:00, CSB-2009.
|
||||||
|
|
||||||
|
\item Dr. Waqar Shahid Qureshi.
|
||||||
|
\item \href{mailto://waqarshahid.qureshi@universityofgalway.ie}{\texttt{waqarshahid.qureshi@universityofgalway.ie}}.
|
||||||
|
\item Office Hours: Thursdays 16:00 -- 17:00, CSB-3001.
|
||||||
|
\end{itemize}
|
||||||
|
\end{multicols}
|
||||||
|
|
||||||
|
\section{Introduction to 2D Graphics}
|
||||||
|
\subsection{Digital Images -- Bitmaps}
|
||||||
|
\textbf{Bitmaps} are grid-based arrays of colour or brightness (greyscale) information.
|
||||||
|
\textbf{Pixels} (\textit{picture elements}) are the cells of a bitmap.
|
||||||
|
The \textbf{depth} of a bitmap is the number of bits-per-pixel (bpp).
|
||||||
|
|
||||||
|
\subsection{Colour Encoding Schemes}
|
||||||
|
Colour is most commonly represented using the \textbf{RGB (Red, Green, Blue)} scheme, typically using 24-bit colour
|
||||||
|
with one 8-bit number representing the level of each colour channel in that pixel.
|
||||||
|
\\\\
|
||||||
|
Alternatively, images can also be represented in \textbf{greyscale} wherein pixels are represented with one
|
||||||
|
(typically 8-bit) brightness value (or scale of grey) .
|
||||||
|
|
||||||
|
\subsection{The Real-Time Graphics Pipeline}
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\textwidth]{images/real_time_graphics_pipeline.png}
|
||||||
|
\caption{The Real-Time Graphics Pipeline}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsection{Graphics Software}
|
||||||
|
The \textbf{Graphics Processing Unit (GPU)} of a computer is a hardware unit designed for digital image processing \& to
|
||||||
|
accelerate computer graphics that is included in modern computers to complement the CPU.
|
||||||
|
They have internal, rapid-access GPU memory and parallel processors for vertices \& fragments to speed up graphics
|
||||||
|
renderings.
|
||||||
|
\\\\
|
||||||
|
\textbf{OpenGL} is a 2D \& 3D graphics API that has existed since 1992 that is supported by the graphics hardware in most
|
||||||
|
computing devices today.
|
||||||
|
\textbf{WebGL} is a web-based implementation of OpenGL for use within web browsers.
|
||||||
|
OpenGL ES for Embedded Systems such as tablets \& mobile phones also exists.
|
||||||
|
\\\\
|
||||||
|
OpenGL was originally a client/server system with the CPU+Application acting as a client sending commands \& data to the GPU
|
||||||
|
acting as a server.
|
||||||
|
This was later replaced by a programmable graphics interface (OpenGL 3.0) to write GPU programs (shaders) to be run by the
|
||||||
|
GPU directly.
|
||||||
|
It is being replaced by newer APIs such as Vulkan, Metal, \& Direct3D and WebGL is being replaced by WebGPU.
|
||||||
|
|
||||||
|
\subsection{Graphics Formats}
|
||||||
|
\textbf{Vector graphics} are images described in terms of co-ordinate drawing operations, e.g. AutoCAD, PowerPoint, Flash,
|
||||||
|
SVG.
|
||||||
|
\textbf{SVG (Scalable Vector Graphics)} is an image specified by vectors which are scalable without losing any quality.
|
||||||
|
\\\\
|
||||||
|
\textbf{Raster graphics} are images described as pixel-based bitmaps.
|
||||||
|
File formats such as GIF, PNG, JPEG represent the image by storing colour values for each pixel.
|
||||||
|
|
||||||
|
\section{2D Vector Graphics}
|
||||||
|
\textbf{2D vector graphics} describe drawings as a series of instructions related to a 2-dimensional co-ordinate system.
|
||||||
|
Any point in this co-ordinate system can be specified using two numbers $(x, y)$:
|
||||||
|
\begin{itemize}
|
||||||
|
\item The horizontal component $x$, measuring the distance from the left-hand edge of the screen or window.
|
||||||
|
\item The vertical component $y$, measuring the distance from the bottom of the screen or window (or sometimes from the
|
||||||
|
top).
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\subsection{Transformations}
|
||||||
|
\subsubsection{2D Translation}
|
||||||
|
The \textbf{translation} of a point in 2 dimensions is the movement of a point $(x,y)$ to some other point $(x', y')$.
|
||||||
|
$$
|
||||||
|
x' = x + a
|
||||||
|
$$
|
||||||
|
$$
|
||||||
|
y' = y + b
|
||||||
|
$$
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.5\textwidth]{images/2d_translation.png}
|
||||||
|
\caption{2D Translation of a Point}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsubsection{2D Rotation of a \textit{Point}}
|
||||||
|
The simplest rotation of a point around the origin is given by:
|
||||||
|
$$
|
||||||
|
x' = x \cos \theta - y \sin \theta
|
||||||
|
$$
|
||||||
|
$$
|
||||||
|
y' = x \cos \theta + y \sin \theta
|
||||||
|
$$
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.5\textwidth]{images/2d_point_rotation.png}
|
||||||
|
\caption{2D Rotation of a Point}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsubsection{2D Rotation of an \textit{Object}}
|
||||||
|
In vector graphics, \textbf{objects} are defined as series of drawing operations (e.g., straight lines) performed on a set
|
||||||
|
of vertices.
|
||||||
|
To rotate a line or more complex object, we simply apply the equations to rotate a point to the $(x,y)$ co-ordinates of each
|
||||||
|
vertex.
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.7\textwidth]{images/2d_object_rotation.png}
|
||||||
|
\caption{2D Rotation of an Object}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsubsection{Arbitrary 2D Rotation}
|
||||||
|
In order to rotate around an arbitrary point $(a,b)$, we perform translation, then rotation, then reverse the translation.
|
||||||
|
$$
|
||||||
|
x' = a + (x - a) \cos \theta - (y - b) \sin \theta
|
||||||
|
$$
|
||||||
|
$$
|
||||||
|
y' = a + (x - a) \cos \theta + (y - b) \sin \theta
|
||||||
|
$$
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.5\textwidth]{images/2d_arbitrary_rotation.png}
|
||||||
|
\caption{Arbitrary 2D Rotation}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsubsection{Matrix Notation}
|
||||||
|
\textbf{Matrix notation} is commonly used for vector graphics as more complex operations are often easier in matrix format
|
||||||
|
and because several operations can be combined easily into one matrix using matrix algebra.
|
||||||
|
|
||||||
|
Rotation about $(0,0)$:
|
||||||
|
$$
|
||||||
|
\begin{bmatrix}
|
||||||
|
x' & y'
|
||||||
|
\end{bmatrix}
|
||||||
|
=
|
||||||
|
\begin{bmatrix}
|
||||||
|
x & y
|
||||||
|
\end{bmatrix}
|
||||||
|
\begin{bmatrix}
|
||||||
|
\cos \theta & \sin \theta \\
|
||||||
|
-\sin \theta & \cos \theta
|
||||||
|
\end{bmatrix}
|
||||||
|
$$
|
||||||
|
|
||||||
|
Translation:
|
||||||
|
$$
|
||||||
|
\begin{bmatrix}
|
||||||
|
x' & y' 1
|
||||||
|
\end{bmatrix}
|
||||||
|
=
|
||||||
|
\begin{bmatrix}
|
||||||
|
x & y & 1
|
||||||
|
\end{bmatrix}
|
||||||
|
\begin{bmatrix}
|
||||||
|
1 & 0 & 0 \\
|
||||||
|
0 & 1 & 0 \\
|
||||||
|
a & 0 & 1
|
||||||
|
\end{bmatrix}
|
||||||
|
$$
|
||||||
|
|
||||||
|
\subsubsection{Scaling}
|
||||||
|
\textbf{Scaling} of an object is achieved by considering each of its vertices in turn, multiplying said vertex's $x$ \& $y$
|
||||||
|
values by the scaling factor.
|
||||||
|
A scaling factor of 2 will double the size of the object, while a scaling factor of 0.5 will halve it.
|
||||||
|
It is possible to have different scaling factors for $x$ \& $y$, resulting in a \textbf{stretch}:
|
||||||
|
$$
|
||||||
|
x' = x \times s
|
||||||
|
$$
|
||||||
|
$$
|
||||||
|
y' = y \times t
|
||||||
|
$$
|
||||||
|
|
||||||
|
If the object is not centred on the origin, then scaling it will also effect a translation.
|
||||||
|
|
||||||
|
\subsubsection{Order of Transformations}
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.8\textwidth]{images/order_of_transformations.png}
|
||||||
|
\caption{Order of Transformations}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\section{2D Raster Graphics}
|
||||||
|
The raster approach to 2D graphics considers digital images to be grid-based arrays of pixels and operates on the
|
||||||
|
images at the pixel level.
|
||||||
|
|
||||||
|
\subsection{Introduction to HTML5/Canvas}
|
||||||
|
\textbf{HTML} or HyperText Markup Language is a page-description language used primarily for website.
|
||||||
|
\textbf{HTML5} brings major updates \& improvements to the power of client-side web development.
|
||||||
|
\\\\
|
||||||
|
A \textbf{canvas} is a 2D raster graphics component in HTML5.
|
||||||
|
There is also a \textbf{canvas with 3D} (WebGL) which is a 3D graphics component that is more likely to be
|
||||||
|
hardware-accelerated but is also more complex.
|
||||||
|
|
||||||
|
\subsubsection{Canvas: Rendering Contexts}
|
||||||
|
\mintinline{html}{<canvas>} creates a fixed-size drawing surface that exposes one or more \textbf{rendering contexts}.
|
||||||
|
The \mintinline{javascript}{getContext()} method returns an object with tools (methods) for drawing.
|
||||||
|
|
||||||
|
\begin{minted}[linenos, breaklines, frame=single]{html}
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
function draw() {
|
||||||
|
var canvas = document.getElementById("canvas");
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.fillStyle = "rgb(200,0,0)";
|
||||||
|
ctx.fillRect (10, 10, 55, 50);
|
||||||
|
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
|
||||||
|
ctx.fillRect (30, 30, 55, 50);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="draw();">
|
||||||
|
<canvas id="canvas" width="150" height="150"></canvas>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
\end{minted}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.2\textwidth]{images/canvas_rendering_contexts.png}
|
||||||
|
\caption{Rendering of the Above HTML Code}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsubsection{Canvas2D: Primitives}
|
||||||
|
Canvas2D only supports one primitive shape: rectangles.
|
||||||
|
All other shapes must be created by combining one or more \textit{paths}.
|
||||||
|
Fortunately, there are a collection of path-drawing functions which make it possible to compose complex shapes.
|
||||||
|
|
||||||
|
\begin{minted}[linenos, breaklines, frame=single]{javascript}
|
||||||
|
function draw(){
|
||||||
|
var canvas = document.getElementById('canvas');
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
ctx.fillRect(125,25,100,100);
|
||||||
|
ctx.clearRect(145,45,60,60);
|
||||||
|
ctx.strokeRect(150,50,50,50);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(75,75,50,0,Math.PI*2,true); // Outer circle
|
||||||
|
ctx.moveTo(110,75);
|
||||||
|
ctx.arc(75,75,35,0,Math.PI,false); // Mouth (clockwise)
|
||||||
|
ctx.moveTo(65,65);
|
||||||
|
ctx.arc(60,65,5,0,Math.PI*2,true); // Left eye
|
||||||
|
ctx.moveTo(95,65);
|
||||||
|
ctx.arc(90,65,5,0,Math.PI*2,true); // Right eye
|
||||||
|
ctx.stroke(); // renders the Path that has been built up..
|
||||||
|
}
|
||||||
|
\end{minted}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.3\textwidth]{images/canvas2d_primitives.png}
|
||||||
|
\caption{Rendering of the Above JavaScript Code}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsubsection{Canvas2D: \mintinline{javascript}{drawImage()}}
|
||||||
|
The example below uses an external image as the backdrop of a small line graph:
|
||||||
|
\begin{minted}[linenos, breaklines, frame=single]{javascript}
|
||||||
|
function draw() {
|
||||||
|
var ctx = document.getElementById('canvas').getContext('2d');
|
||||||
|
var img = new Image();
|
||||||
|
img.src = 'backdrop.png';
|
||||||
|
img.onload = function(){
|
||||||
|
ctx.drawImage(img,0,0);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(30,96);
|
||||||
|
ctx.lineTo(70,66);
|
||||||
|
ctx.lineTo(103,76);
|
||||||
|
ctx.lineTo(170,15);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{minted}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.3\textwidth]{images/canvas2d_drawimage.png}
|
||||||
|
\caption{Rendering of the Above JavaScript Code}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsubsection{Canvas2D: Fill \& Stroke Colours}
|
||||||
|
\begin{minted}[linenos, breaklines, frame=single]{html}
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
function draw() {
|
||||||
|
var canvas = document.getElementById("canvas");
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
// Filled Star
|
||||||
|
context.lineWidth=3;
|
||||||
|
context.fillStyle="#CC00FF";
|
||||||
|
context.strokeStyle="#ffff00"; // NOT lineStyle!
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(100,50);
|
||||||
|
context.lineTo(175,200);
|
||||||
|
context.lineTo(0,100);
|
||||||
|
context.lineTo(200,100);
|
||||||
|
context.lineTo(25,200);
|
||||||
|
context.lineTo(100,50);
|
||||||
|
context.fill(); // colour the interior
|
||||||
|
context.stroke(); // draw the lines
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="draw();">
|
||||||
|
<canvas id="canvas" width="300" height="300"></canvas>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
\end{minted}
|
||||||
|
|
||||||
|
Colours can be specified by name (\mintinline{javascript}{red}), by a string of the form
|
||||||
|
\mintinline{javascript}{rgb(r,g,b)}, or by hexadecimal colour codes \mintinline[escapeinside=||]{javascript}{|#|RRGGBB}.
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.3\textwidth]{images/canvas2d_fill_stroke.png}
|
||||||
|
\caption{Rendering of the Above JavaScript Code}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsubsection{Canvas2D: Translations}
|
||||||
|
\begin{minted}[linenos, breaklines, frame=single]{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(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-ordinate system
|
||||||
|
context.translate(75,50);
|
||||||
|
context.fillStyle="#0000FF"; // blue
|
||||||
|
context.fillRect(100,0,100,100);
|
||||||
|
context.restore(); // recover the default (root) co-ordinate 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>
|
||||||
|
\end{minted}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.3\textwidth]{images/canvas2d_translations.png}
|
||||||
|
\caption{Rendering of the Above JavaScript Code}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsubsection{Canvas2D: Order of Transformations}
|
||||||
|
\begin{minted}[linenos, breaklines, frame=single]{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>
|
||||||
|
\end{minted}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.2\textwidth]{images/canvas2d_order_of_transformations.png}
|
||||||
|
\caption{Rendering of the Above JavaScript Code}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsubsection{Scaling}
|
||||||
|
\begin{minted}[linenos, breaklines, frame=single]{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>
|
||||||
|
\end{minted}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.2\textwidth]{images/canvas2d_scaling.png}
|
||||||
|
\caption{Rendering of the Above JavaScript Code}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsubsection{Canvas2D: Programmatic Graphics}
|
||||||
|
\begin{minted}[linenos, breaklines, frame=single]{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>
|
||||||
|
\end{minted}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.2\textwidth]{images/canvas2d_programmatic_graphics.png}
|
||||||
|
\caption{Rendering of the Above JavaScript Code}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
|
||||||
\end{document}
|
\end{document}
|
||||||
|
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 685 B |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 120 KiB |
After Width: | Height: | Size: 252 KiB |