<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Virtual Design Factory]]></title><description><![CDATA[Evolving Innovation]]></description><link>https://virtualdesignfactory.com.au/</link><image><url>https://virtualdesignfactory.com.au/favicon.png</url><title>Virtual Design Factory</title><link>https://virtualdesignfactory.com.au/</link></image><generator>Ghost 4.6</generator><lastBuildDate>Fri, 17 Apr 2026 21:31:16 GMT</lastBuildDate><atom:link href="https://virtualdesignfactory.com.au/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Containerising a Node Express App]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>If you need an example application to use try this <a href="/simple-json-api-express">Simple JSON API</a></p>
<p>In this basic example of how to containerize a node express app we will use <a href="https://www.docker.com/">Docker</a>. It is assumed that that you have a working express application that you are ready to put into a container for</p>]]></description><link>https://virtualdesignfactory.com.au/containerising-a-node-express-app/</link><guid isPermaLink="false">5ead864f6439520001f18644</guid><category><![CDATA[Docker]]></category><category><![CDATA[Node]]></category><category><![CDATA[Express]]></category><dc:creator><![CDATA[Doug Fleming]]></dc:creator><pubDate>Sat, 25 Apr 2020 15:23:49 GMT</pubDate><media:content url="https://virtualdesignfactory.com.au/content/images/2020/05/shipping-containers.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://virtualdesignfactory.com.au/content/images/2020/05/shipping-containers.jpg" alt="Containerising a Node Express App"><p>If you need an example application to use try this <a href="/simple-json-api-express">Simple JSON API</a></p>
<p>In this basic example of how to containerize a node express app we will use <a href="https://www.docker.com/">Docker</a>. It is assumed that that you have a working express application that you are ready to put into a container for deployment purposes.</p>
<p>Also assumed is that you have access to the <a href="https://docs.docker.com/engine/reference/commandline/cli/">Docker CLI</a> which you can verify by running the following command in your terminal:</p>
<pre><code class="language-bash">docker -v

# Docker version 19.03.5, build 633a0ea (your version may differ)
</code></pre>
<h2 id="buildingacontainer">Building A Container</h2>
<p>Navigate to your project folder and create a <a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/">Dockerfile</a></p>
<blockquote>
<p>Note: This file is case sensitive so use a capital &apos;D&apos;</p>
</blockquote>
<pre><code class="language-dockerfile"># Use apline linux where ever possible
# to keep container sizes to a minumum
FROM node:alpine

# Application Code
WORKDIR /app

# Install app dependencies
COPY package*.json ./

# Install Dependancies
RUN npm install

# Expose port 3030 from the container
EXPOSE 3030

# Run server by default
CMD [&quot;npm&quot;, &quot;start&quot;]

# Add application code
COPY . .
</code></pre>
<p>Each command in the Dockerfile results in a <code>layer</code> that is added to the base image layers. It is worth thinking about the order of operation here. Most updates that you make to your app after having deployed a build for testing will be code changes. As you can by the order of the commands copying in the application code is the <em>last</em> step. So if the only change is something in your application code only the <em>last</em> layer would need to be re-build in subsequent builds. If you were to add a new package to your project, then all the layers down to <code>COPY package*.json ./</code> would need to be discarded and rebuilt.</p>
<p>The most important part of this file is the <code>EXPOSE</code> port number, in my example app it listens on port 3000, yours may be different, change the port number to suit if required.</p>
<p>If you are using the <a href="/simple-json-api-express">Simple JSON API</a> example, this is all tha should be required to build your container. Using the docker CLI we can initiate a build using the <code>docker build</code> command:</p>
<pre><code class="language-bash">docker build -t example-json-api:dev .
</code></pre>
<p>In this command the <code>-t</code> stands for the tag name and the <code>.</code> is just referring to the current directory as the location of the <code>Dockerfile</code></p>
<p>Once the build is completed you should see the last entry on the terminal indicating success:</p>
<pre><code class="language-bash"># Successfully tagged example-json-api:dev
</code></pre>
<p>Now you should be able to see this new image in your list of local images:</p>
<pre><code class="language-bash">docker images
</code></pre>
<pre><code class="language-bash"># REPOSITORY        TAG  IMAGE ID      CREATED        SIZE
# example-json-api  dev  6ba575ffb51f  2 minutes ago  83.2MB
</code></pre>
<h2 id="runningacontainer">Running A Container</h2>
<p>You can test run the image with the following command:</p>
<pre><code class="language-bash">docker run --rm -p 3000:3000 example-json-api:dev
</code></pre>
<p>The <code>--rm</code> flag here will automatically remove the container from the local container instances once you <code>&lt;ctrl&gt; + C</code> to stop the running container.</p>
<p>The <code>-p</code> flag tells docker to map local ports to the exposed container ports <code>&lt;local port&gt;:&lt;container port&gt;</code></p>
<p>Then you should be able to interact your app on the port that is exposed. In this example by opening a new termainal and using curl. The running container should log to the console when new requests are recieved.</p>
<pre><code class="language-bash"># [2020-04-25T16:01:51.034Z] Example JSON API listening at http://localhost:3000
# [2020-04-25T16:01:54.271Z] POST /echo -&gt; {&quot;message&quot;:&quot;This is my new JSON API&quot;}
# [2020-04-25T16:01:55.284Z] GET /
</code></pre>
<p>Stop the container by using <code>&lt;ctrl&gt; + C</code> in the running container terminal.</p>
<h2 id="savingacontainer">Saving A Container</h2>
<p>Docker CLI has a very useful <a href="https://docs.docker.com/engine/reference/commandline/save/">save</a> command that we can use to convert the container into a <code>.tar.gz</code> file which can then be shared.</p>
<pre><code class="language-bash">docker save example-json-api:dev | gzip &gt; example-json-api.tar.gz
</code></pre>
<p>Alternitively if you prefer not to gzip the result you will end up with a <code>.tar</code> file</p>
<pre><code class="language-bash">docker save example-json-api:dev &gt; example-json-api.tar
</code></pre>
<h2 id="deleteacontainer">Delete A Container</h2>
<p>Using Docker CLI you can remove a container image as long as it&apos;s not currently running on in a container instance with the following command:</p>
<pre><code class="language-bash">docker rmi example-json-api:dev
</code></pre>
<p>You can check that it&apos;s successfully removed from your local images by running this command and verifying that it&apos;s not in the list:</p>
<pre><code class="language-bash">docker images
</code></pre>
<h2 id="loadingacontainer">Loading A Container</h2>
<p>Docker CLI also has a <a href="https://docs.docker.com/engine/reference/commandline/load/">load</a> command for extracting <code>.tar</code> or <code>.tar.gz</code> archives that you may have saved.</p>
<pre><code class="language-bash">docker load --input example-json-api.tar.gz
</code></pre>
<p>Or if you have a <code>.tar</code> file</p>
<pre><code class="language-bash">docker load --input example-json-api.tar
</code></pre>
<p>You can check that it&apos;s successfully loaded into your local images by running this command and verifying that it is in the list:</p>
<pre><code class="language-bash">docker images
</code></pre>
<pre><code class="language-bash"># REPOSITORY        TAG  IMAGE ID      CREATED        SIZE
# example-json-api  dev  6ba575ffb51f  5 minutes ago  83.2MB
</code></pre>
<hr>
<p>The beauty of containerising your application is that it will be able to run on any platform that docker can run on, and there will not be any cross platform issues that mean there are subtle differences in how your  app runs or unexpected bugs based on different underlying hardware.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Simple JSON API using Express]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><a href="https://expressjs.com/">Express</a> is a very popular web framework for <a href="https://nodejs.org/en/">Node JS</a> which is a javascript runtime built on <a href="https://v8.dev/">Chrome&apos;s V8 javascript engine</a>. Node can run on Windows, Mac or Linux and so can be used on your web server.</p>
<p>If you are new to Express, this is for you.</p>]]></description><link>https://virtualdesignfactory.com.au/simple-json-api-express/</link><guid isPermaLink="false">5ead864f6439520001f18646</guid><category><![CDATA[Node]]></category><category><![CDATA[Express]]></category><dc:creator><![CDATA[Doug Fleming]]></dc:creator><pubDate>Sat, 25 Apr 2020 14:16:48 GMT</pubDate><media:content url="https://virtualdesignfactory.com.au/content/images/2020/05/express.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://virtualdesignfactory.com.au/content/images/2020/05/express.png" alt="Simple JSON API using Express"><p><a href="https://expressjs.com/">Express</a> is a very popular web framework for <a href="https://nodejs.org/en/">Node JS</a> which is a javascript runtime built on <a href="https://v8.dev/">Chrome&apos;s V8 javascript engine</a>. Node can run on Windows, Mac or Linux and so can be used on your web server.</p>
<p>If you are new to Express, this is for you. Basic knowledge of Node and requiring node packages in your code is required.</p>
<p>Before we can get into programming the API itself, first we need to make a project folder and initialize <code>package.json</code> file so we can install the Express framework.</p>
<p>Make a new directory for your example API and change into it:</p>
<pre><code class="language-bash">mkdir ExampleAPI
cd ExampleAPI
</code></pre>
<p>Create a <code>package.json</code> file with no questions asked and install the express framework</p>
<pre><code class="language-bash">npm init -y
npm i express compression cors helmet body-parser
</code></pre>
<p>After a small download you should now see a new folder in your project directory called <code>node_modules</code> this is where the node package manager stores your project specific dependencies.</p>
<blockquote>
<p>Note: If you are using source control, you should update your <code>.gitignore</code> file to ignore this <code>node_modules</code> folder. If you clone this on another machine, to install the packages again you just type <code>npm i</code> in the project directory.</p>
</blockquote>
<p>We have installed the express framework itself, along with some popular middleware that helps with security performace and parsing requests.</p>
<p>Express has a simple hello world example on their website, that we will use to get up and running with our extremely simple example API quickly. We are going to modify it slightly in order to use some middleware and return a JSON response. We&apos;ll also add a simple echoing endpoint for post requests so our API behaves much like other API&apos;s you might be familiar with.</p>
<p>Making a more interesting API is a challenge I leave to you.</p>
<p>index.js:</p>
<pre><code class="language-js">// Require all the dependencies
const express = require(&apos;express&apos;);
const compression = require(&apos;compression&apos;);
const cors = require(&apos;cors&apos;);
const helmet = require(&apos;helmet&apos;);
const bodyParser = require(&apos;body-parser&apos;);

// Create the app
const app = express();
const port = 3000;

// Rudimentary logging
function log(message) {
  console.log(`[${new Date().toISOString()}] ${message}`);
}

// Add middleware to the express app
app.use(cors());
app.use(helmet());
app.use(compression());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json({ extended: true }));

// Routes are registered prior to starting the server
// for more info on how routing works see the docs
// https://expressjs.com/en/guide/routing.html

// Simple route for displaying a messing on the root route
app.get(&apos;/&apos;, (req, res) =&gt; {
  log(`GET /`);
  res.status(200).json({ message: &apos;Hello World&apos; });
});

// Echo back any data provided under the &apos;message&apos; key
app.post(&apos;/echo&apos;, (req, res) =&gt; {
  log(`POST /echo -&gt; ${JSON.stringify(req.body)}`);
  res.status(200).json({ message: req.body.message });
});

// Start the server
app.listen(port, () =&gt; {
  log(`Example JSON API listening at http://localhost:${port}`);
});


</code></pre>
<p>With that done, we can test our new API by starting up the app from the terminal:</p>
<pre><code class="language-bash">node index.js

# Example app listening at http://localhost:3000
</code></pre>
<p>Using <code>curl</code> in a new terminal window you can test the response from the root route</p>
<pre><code class="language-bash">curl http://localhost:3000

# {&quot;message&quot;:&quot;Hello World&quot;}
</code></pre>
<p>And also we can <code>POST</code> some JSON data to our echo endpoint:</p>
<pre><code class="language-bash">curl --header &quot;Content-Type: application/json&quot; \
     --request POST \
     --data &apos;{ &quot;message&quot;: &quot;This is my new JSON API&quot; }&apos; \
     http://localhost:3000/echo
     
# {&quot;message&quot;:&quot;This is my new JSON API&quot;}
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Installing Docker on Ubuntu Server]]></title><description><![CDATA[<!--kg-card-begin: markdown--><h2 id="whatisdocker">What is Docker?</h2>
<p>According to Wikipedia <a href="https://www.docker.com/">Docker</a> is a set of platform as a service products that uses OS-level virtualization to deliver software in packages called containers.</p>
<p>Containers are isolated from each other and contain their own software and configuration files. Containers are able to communitcate through private networks setup</p>]]></description><link>https://virtualdesignfactory.com.au/installing-docker-on-ubuntu-server/</link><guid isPermaLink="false">5ead864f6439520001f1863e</guid><category><![CDATA[Docker]]></category><category><![CDATA[Ubuntu]]></category><dc:creator><![CDATA[Doug Fleming]]></dc:creator><pubDate>Sat, 11 Apr 2020 05:53:27 GMT</pubDate><media:content url="https://virtualdesignfactory.com.au/content/images/2020/05/docker-logo.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="whatisdocker">What is Docker?</h2>
<img src="https://virtualdesignfactory.com.au/content/images/2020/05/docker-logo.jpg" alt="Installing Docker on Ubuntu Server"><p>According to Wikipedia <a href="https://www.docker.com/">Docker</a> is a set of platform as a service products that uses OS-level virtualization to deliver software in packages called containers.</p>
<p>Containers are isolated from each other and contain their own software and configuration files. Containers are able to communitcate through private networks setup by docker.</p>
<h2 id="whyputitonyourserver">Why put it on your server?</h2>
<p>Installing Docker and configuring containers to run on an Ubuntu server can greatly simplify the task of setting up and maintaining the various software and services you may wish to run on your sever.</p>
<p>There is an emense collection of pre-built containers that you can use with docker for everything from hosting a simple web server to deploying complex microservices and more.</p>
<h2 id="installation">Installation</h2>
<p>Now that we&apos;ve covered the what and why, it&apos;s time to actaully get started with the installation. For the purpose of this post, we&apos;ll assume that you have a vanilla installation of <code>UbuntuServer 18.04.4 LTS</code> that you currently have SSH access to.</p>
<p>Docker exists in the standard repositorys. It is possible to add the offical Docker repository to your sources list, but unless you have a particular need to do so, I find that it&apos;s simpler and easier to use the one available in the standard repository.</p>
<p>First things first:</p>
<pre><code class="language-bash">sudo apt update &amp;&amp; sudo apt upgrade -y
</code></pre>
<p>Then install Docker:</p>
<pre><code class="language-bash">sudo apt install docker.io
</code></pre>
<p>If you plan to use <a href="https://docs.docker.com/compose/">docker-compose</a> to configure and run multiple containers at one, you will need to install that seperatley:</p>
<pre><code class="language-bash">sudo apt install docker-compose
</code></pre>
<p>Next we should start Docker:</p>
<pre><code class="language-bash">sudo systemctl start docker
</code></pre>
<p>Once that is all done, you can optionally configure Docker to start on boot:</p>
<pre><code class="language-bash">sudo systemctl enable docker
</code></pre>
<p>To work with docker without having to use <code>sudo</code> you should add yourself to the <code>docker</code> group:</p>
<pre><code class="language-bash">sudo usermod -aG docker &lt;your user name&gt;
</code></pre>
<p>In order for group assignments to take effect you may need to log out and back in to your server before continuing.</p>
<p>And you should be able to check the Docker version without any errors appearing in the terminal:</p>
<pre><code class="language-bash">docker --version
</code></pre>
<p>At the time of writing the lastest docker version was</p>
<p><code>Docker version 19.03.6, build 369ce74a3c</code></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Working with the Win32 API]]></title><description><![CDATA[<!--kg-card-begin: markdown--><h2 id="mainwindowrequirements">Main Window Requirements</h2>
<ol>
<li>Window Procedure Function</li>
<li>Main Window Function</li>
<li>Window Class (not a c++ class)</li>
<li>Message Loop</li>
<li>Resource file (optional)</li>
</ol>
<p>The windows API uses a LOT of preprocessor instructions to modify function definitions that can be very confusing at first. Also most of the interactions with the API will be</p>]]></description><link>https://virtualdesignfactory.com.au/working-with-the-win32-api/</link><guid isPermaLink="false">5ead864f6439520001f18643</guid><category><![CDATA[C++]]></category><dc:creator><![CDATA[Doug Fleming]]></dc:creator><pubDate>Tue, 30 Jul 2019 17:02:00 GMT</pubDate><media:content url="https://virtualdesignfactory.com.au/content/images/2020/05/win32-api.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="mainwindowrequirements">Main Window Requirements</h2>
<ol>
<li>Window Procedure Function</li>
<li>Main Window Function</li>
<li>Window Class (not a c++ class)</li>
<li>Message Loop</li>
<li>Resource file (optional)</li>
</ol>
<img src="https://virtualdesignfactory.com.au/content/images/2020/05/win32-api.jpg" alt="Working with the Win32 API"><p>The windows API uses a LOT of preprocessor instructions to modify function definitions that can be very confusing at first. Also most of the interactions with the API will be through Macros rather than functions.</p>
<h2 id="firstthingsfirst">First things first</h2>
<p>Text encoding should be UNICODE as that is the standard these days. To enable unicode you will need to add two define statements:</p>
<pre><code class="language-cpp">#define UNICODE
#define _UNICODE
</code></pre>
<p>Without these define statements, either in the code or as a compiler flag the wrong functions might be called. When using an IDE put them in the code, and make sure there are no automatic defines assumed by the IDE so as not to show confusing results with code paths.</p>
<h2 id="windowsprocedurefunction">Windows Procedure Function</h2>
<p>The window procedure needs to be defined, or at least declared prior to the main window function. The signature is:</p>
<pre><code class="language-cpp">LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM)
</code></pre>
<p><code>LRESULT</code> is a window API typedef<br>
<code>CALLBACK</code> expands to __stdcall and is absolutely required for this function to work</p>
<p>For the main window procedure, you should pass on any unprocessed messages to the default windows procedure:</p>
<pre><code class="language-cpp">return DefWindowProc(hand, msg, wParam, lParam);
</code></pre>
<h2 id="mainwindowfunction">Main Window Function</h2>
<p>The main window function is a macro and the inclusion of the header file <code>&lt;windows.h&gt;</code> causes the compiler to use a different entry point (not main) and will prepare and call the <code>WinMain</code> function with the listed parameters.</p>
<pre><code class="language-cpp">Int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
</code></pre>
<p><code>APIENTRY</code> expads to __stdcall and is required<br>
<code>hInstance</code> is a handle to the module (.exe)<br>
<code>hPrevInstance</code> is a hold over from the win16 api and is no longer used<br>
<code>lpCmdLine</code> is a string pointer containing the command line args<br>
<code>nCmdShow</code> is an int containing command line info regarding how the window should be show on start, useful for shortcut configurations</p>
<h2 id="windowclass">Window Class</h2>
<p>The window class is a <code>STRUCT</code> and needs to be filled out completely prior to being registered with the system. Incorrect details will cause the class registration to fail&#x2026;</p>
<p>Use <code>WNDCLASSEX</code> (extended)</p>
<p>See example program at the bottom.</p>
<h2 id="messageloop">Message Loop</h2>
<p>The message loop is blocking and runs for the entire time the window executable is running.</p>
<p>Messages are obtained from the system, and then translated and distributed to the running application. Note the while loop for this, the logical comparison &gt; 0 is important here, as negative values here would indicate an error so don&#x2019;t use != 0 or leave it off.</p>
<h2 id="resourcefile">Resource File</h2>
<p>Using a resource file will allow the use of a manifest and also greatly simplify loading resources. See useful website references for details.</p>
<p>The file should be <code>resource.rc</code></p>
<p>It needs to be compiled with the program objects.</p>
<p>To get an object compiled from a resource file you need to use a program called <code>winders</code>:</p>
<pre><code class="language-bash">windres -i resource.rc -o resource.o
</code></pre>
<p>Include resources in the program like this:</p>
<p><code>MAKEINTRESOURCE(IDI_APPICON)</code></p>
<p>Or depending on the use case just access the custom resource directly</p>
<p><code>IDI_APPICON</code></p>
<p><code>IDI_APPICON</code> in this case is a custom defined resource and will be in the resource.h file</p>
<h2 id="exampleprogram">Example Program</h2>
<p>This is an example of a minimal program from which you could build off:</p>
<pre><code class="language-cpp">#define UNICODE
#define _UNICODE

#include &lt;windows.h&gt;

const wchar_t className[] = TEXT(&quot;WindowClass&quot;);

LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, INT nCmdShow)
{
    WNDCLASSEX wc;
    HWND hWnd;
    MSG msg;

    wc.cbClsExtra = 0;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wc.hInstance = hInstance;
    wc.lpfnWndProc = WindowProc;
    wc.lpszClassName = className;
    wc.lpszMenuName = NULL;
    wc.style = 0;

    // Register the window class
    if (!RegisterClassEx(&amp;wc))
    {
        MessageBox(NULL, TEXT(&quot;Could not register the window class&quot;), TEXT(&quot;Error&quot;), MB_OK | MB_ICONERROR);
        return 1;
    }

    // Create the window
    hWnd = CreateWindowEx(
        0,
        className,
        TEXT(&quot;Window Title&quot;),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
        NULL, NULL, hInstance, NULL);

    if (!hWnd)
    {
        MessageBox(NULL, TEXT(&quot;Could not create window&quot;), TEXT(&quot;Error&quot;), MB_OK | MB_ICONERROR);
        return 1;
    }

    // Show the window
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    // Handle the message loop
    while (GetMessage(&amp;msg, hWnd, 0, 0) &gt; 0)
    {
        TranslateMessage(&amp;msg);
        DispatchMessage(&amp;msg);
    }

    return (INT)msg.lParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }

    return DefWindowProc(hWnd, msg, wParam, lParam);
}
</code></pre>
<hr>
<p>I found a lot of useful resources while figuring out how to work with the Win32 API:</p>
<p><a href="https://docs.microsoft.com/en-us/windows/win32/learnwin32/learn-to-program-for-windows">Official Microsoft Documentation</a><br>
<a href="http://zetcode.com/gui/winapi/gdi">Some GUI Examples</a><br>
<a href="https://bobobobo.wordpress.com/2009/03/30/adding-an-icon-system-tray-win32-c">Minimizing C++ Win32 App To System Tray</a><br>
<a href="https://www.transmissionzero.co.uk/computing/win32-apps-with-mingw">Building Win32 GUI apps with MinGW</a><br>
<a href="http://www.winpr&amp;aed::og.org/tutorial/">The Forgers Win32 API Programming Tutorial</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Three Dimensional Vectors]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>3D graphics requires points in <a href="https://en.wikipedia.org/wiki/Three-dimensional_space">three dimensional space</a> expressed as <code>x</code> <code>y</code> <code>z</code></p>
<p>There are a number of different possible orientations in a <a href="https://en.wikipedia.org/wiki/Cartesian_coordinate_system">Cartesian coordinate system</a>, however converting between different systems is reasonably straight forward.</p>
<p>A simple <code>Vector3</code> class is all that is required to get started. Example code will</p>]]></description><link>https://virtualdesignfactory.com.au/three-dimensional-vectors/</link><guid isPermaLink="false">5ead864f6439520001f18640</guid><category><![CDATA[Geometry]]></category><dc:creator><![CDATA[Doug Fleming]]></dc:creator><pubDate>Fri, 21 Jun 2019 16:21:00 GMT</pubDate><media:content url="https://virtualdesignfactory.com.au/content/images/2020/05/three-dimensional-vectors.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://virtualdesignfactory.com.au/content/images/2020/05/three-dimensional-vectors.jpg" alt="Three Dimensional Vectors"><p>3D graphics requires points in <a href="https://en.wikipedia.org/wiki/Three-dimensional_space">three dimensional space</a> expressed as <code>x</code> <code>y</code> <code>z</code></p>
<p>There are a number of different possible orientations in a <a href="https://en.wikipedia.org/wiki/Cartesian_coordinate_system">Cartesian coordinate system</a>, however converting between different systems is reasonably straight forward.</p>
<p>A simple <code>Vector3</code> class is all that is required to get started. Example code will be shown in typescript.</p>
<pre><code class="language-ts">export class Vector3 {
    // Initialise values to 0 if not supplied
    constructor(public x: number = 0, public y: number = 0, public z: number = 0) {}

    // Provide a simple to array method to export vector fields
    toArray() {
        return [this.x, this.y, this.z];
    }
    
    // Provide a simple from array method to import vector fields
    fromArray(array: number[]) {
        if (array.length !== 3) {
            throw new Error(&apos;x, y, z values required&apos;);
        }
        
        this.x = array[0];
        this.y = array[1];
        this.z = array[2];
        
        return this;
    }
    
    // extend the class here with functions below
}
</code></pre>
<p>You would create and use an instance of this class as follows:</p>
<pre><code class="language-ts">const vector1 = new Vector3();
const vector2 = new Vector3(1, 2, 3);

console.log(vector1.toArray());
// [0, 0, 0]

console.log(vector2.toArray());
// [1, 2, 3]
</code></pre>
<blockquote>
<p>In order to allow multiple operations chained together it&apos;s advantageous to always <code>return this;</code> at the end of any methods that effect the current vector instance (any methods that would otherwise return void). This technique allows for method chaining as you will see in the examples I have.</p>
</blockquote>
<p>By itself this class is simply a container for the labeled data <code>x</code> <code>y</code> <code>z</code>. It would be very useful to extend this class so that different <code>Vector3</code> instances could interact with simple methods such as these:</p>
<pre><code class="language-ts">//... after constructor

add(vector: Vector3) {
    this.x += vector.x;
    this.y += vector.y;
    this.z += vector.z;
    
    return this;
}

sub(vector: Vector3) {
    this.x -= vector.x;
    this.y -= vector.y;
    this.z -= vector.z;
    
    return this;
}

// ... before end curly brace
</code></pre>
<p>Multiplication can also be done with vectors, for 3D graphics it is usually enough to provide a scalar value with which to apply to all the axis:</p>
<pre><code class="language-ts">multiplyScalar(value: number) {
    this.x *= value;
    this.y *= value;
    this.z *= value;
    
    return this;
}
</code></pre>
<p>The magnitude of a vector is just the same as the total length of the vector and can be calculated as the square root of all the individual vector elements squared:</p>
<pre><code class="language-ts">magnitude(): number {
    return Math.sqrt(this.x ** 2 + this.y ** 2 + this.z ** 2);
}
</code></pre>
<p>A normalised vector (normal) or otherwise knows as a <a href="https://en.wikipedia.org/wiki/Unit_vector">unit vector</a> is a vector that has a magnitude of <code>1</code>. It can be very useful to take a vector and normalise it, so that you can then apply the <code>multiplyScalar</code> method to it, thereby extending it to a specific length. For example applying <code>multiplyScalar(5)</code> to a unit vector will ensure that the vector is now 5 units long:</p>
<pre><code class="language-ts">normalize() {
    const currentMagnitude = this.magnitude();
    
    this.x /= currentMagnitude;
    this.y /= currentMagnitude;
    this.z /= currentMagnitude;
    
    return this;
}
</code></pre>
<p>Calculating a dot product for the vector yeilds a single number, and is useful in a number of other vector calculation. It can be caluclated as follows:</p>
<pre><code class="language-ts">dot(vector: Vector3): number {
    return this.x * vector.x + this.y * vector.y + this.z * vector.z;
}
</code></pre>
<p>The angle between two vectors can also be calculated and uses some of the previous methods we&apos;ve added to get the result:</p>
<pre><code class="language-ts">angleBetween(vector: Vector3): number {
    // Note: this will return the angle in radians
    return Math.acos(this.dot(vector) / (this.magnitude() * vector.magnitude()));
}
</code></pre>
<p>Here is an example of using the <code>angleBetween</code> method:</p>
<pre><code class="language-ts">const vector1 = new Vector3(3, 1, 0);
const vector2 = new Vector3(4, 0, 0);

console.log(vector1.angleBetween(vector2));
// 0.3217505543966423

// Convert to degrees by multiplying by 180 and dividing by PI
//   0.3217505543966423 * 180 / Math.PI;
// 18.434948822922017
</code></pre>
<p>A clone method is also useful in case you do not wish to change the value of a vector when performing calculations with it:</p>
<pre><code class="language-ts">clone(): Vector3 {
    return new Vector3(this.x, this.y, this.z);
}
</code></pre>
<p>As an example of this:</p>
<pre><code class="language-ts">const vector1 = new Vector3(1, 2, 3);
const vector2 = new Vector3(4, 5, 5);

// The add method would normally change the vector it&apos;s called on
// vector1.add(vector2);
// will alter the values of vector1 to be [5, 7, 9]

// To create a new vector based on vector1, leaving vector1
// unmodified in the process call the clone method
const vector3 = vector1.clone().add(vector2);

console.log(vector1);
// Vector3 { x: 1, y: 2, z: 3 }

console.log(vector2);
// Vector3 { x: 4, y: 5, z: 5 }

console.log(vector3);
// Vector3 { x: 5, y: 7, z: 8 }

</code></pre>
<p>The cross product of a vector will modify a vector to be perpendicular to the plane of the original vector and the vector passed in. This is very useful for calculating face normals for groups of vectors or points:</p>
<pre><code class="language-ts">cross(vector: Vector3) {
    const x = this.y * vector.z - this.z * vector.y;
    const y = this.x * vector.z - this.z * vector.x;
    const z = this.x * vector.y - this.y * vector.x;

    // The Y value needs to be inverted but I don&apos;t
    // like the value -0 so we will check for that
    // posibility with the turnery operator
    this.x = x;
    this.y = y === 0 ? 0 : -y;
    this.z = z;

    return this;
}
</code></pre>
<p>Let&apos;s look at an example of getting the plane normal from three points that we might use to create a polygon face:</p>
<pre><code class="language-ts">// This is an array of points creating a
// simple triangle along the X-Y plane
const polyFace = [
  new Vector3(1, 1, 0), // point 0
  new Vector3(5, 1, 0), // point 1
  new Vector3(1, 3, 0), // point 2
];

// The vector from point 0 to point 1 - Vector3 { x: 4, y: 0, z: 0 }
const vector1 = polyFace[1].clone().sub(polyFace[0]);

// The vector from point 0 to point 2 - Vector3 { x: 0, y: 2, z: 0 }
const vector2 = polyFace[2].clone().sub(polyFace[0]);

// Use the cross product to calculate the perpendicular vector
// Then normalise
const planeNormal = vector1.clone().cross(vector2).normalize();

console.log(planeNormal);
// Vector3 { x: 0, y: 0, z: 1 }

// The resulting vector points straight up on the Z axis
</code></pre>
<p>That is the basic toolkit for working with 3D vectors. Further improvments could be made to this class by adding in a <code>fromArray()</code> method. I&apos;m sure that other methods will also to mind when you start working with the vector class.</p>
<!--kg-card-end: markdown--><p></p>]]></content:encoded></item></channel></rss>