Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Sunday, June 7, 2020

Computing arithmetic gymnastics

Today was a day well spent on programming a bruteforce solution to a simple arithmetic puzzle. The puzzle is something I came up with during a daydream a long time ago. It’s simple arithmetic gymnastics for when you have nothing better to do.

You start off with a 4 digit number, let’s take 1234 as an example. The goal is to create a sum out of the separate digits with any of the four basic mathematical operations: add, subtract, multiply or divide, where the answer to this sum must be exactly zero. You may switch the order of any digit, and add parentheses everywhere.

Correct examples in this case would be:

1 + 2 + 3 + 4 = 10
1 - 2 + 3 - 4 = -2
(1 + 3 - 4) * 2 = 0

Where the last example would satisfy the condition and create a solution in this case.

I found that every number I tried had a solution, and I could not find a number that was not solvable. However the question remained: is every 4 digit number solvable? So today I set out to find the answer.

Programming out the problem

When we calculate a solution to this problem, we often use heuristics to quickly find obvious solutions. The most obvious strategy is that when a number contains a zero, you can just multiply all numbers and end with a zero. Another simple strategy is found when you have two digits that are the same, subtracting the two will create your zero and hence the solution again.

Before arriving at heuristics to speed up computation I wanted to solve this problem the hard way: brute forcing a solution. Since computers can do way more instructions per second than I do solving simple arithmetics, this should be easy to solve for a problem this size. I did not care for performance at first, the simplest solution would do. The language of choice was C# for its ease of use.

The problem at hand is easy to imagine, since we are very used to calculating these numbers daily. It is however harder to program out all possible solutions. The method I used to arrive at a solution was to use some combinatorics.

Part one: calculating all possible number combinations

The first observation I made was that some of the operations were not commutative: subtraction and division produce different results when you swap the digits around. For this reason we would need all permutations of the numbers instead of combinations, since the order in which numbers appear does matter!

Creating a recursive function to generate all possible digit permutations looks as follows:

private static IEnumerable<int[]> CalculatePermutations(IEnumerable<int> list, int length)
{
    if (length == 1)
        return list.Select(t => new [] { t });

    return CalculatePermutations(list, length - 1)
        .SelectMany(x => list.Where(element => !x.Contains(element)), (t1, t2) => t1.Concat(new [] { t2 })
        .ToArray());
}

I create all permutations up to a given length, which is useful if we want to solve the problem with more or less than 4 digits later on. Note that this function is used to create permutations of unique indices and not the numbers themselves. This has two advantages: we can move the computation out of the for loop for every number, and we don’t have to deal with duplicate number permutations.

Part two: all possible operator combinations

Similar to the digits we will have to fill N-1 operators between the digits with any of the arithmetics. However in this case we need permutations with repetitions, as the multiply operator could be used multiple times for example.

We can realize this by creating the same function as previously mentioned with a small change: we don’t filter results that have duplicates:

private static IEnumerable<T[]> CalculatePermutationsWithRepetition<T>(IEnumerable<T> list, int length)
{
    if (length == 1)
        return list.Select(t => new [] { t });

    return CalculatePermutationsWithRepetition(list, length - 1)
        .SelectMany(x => list, (t1, t2) => t1.Concat(new [] { t2 })
        .ToArray());
}

Stringing it all together

Now that we have all possible number and operator permutations we can start adding them together. The sum will be solved from left to right, simply accumulating the result during the process. Note that all numbers will have to be floating point numbers since we involve a division operator that can lead to fractions.

But what about the parentheses? Since we have all possible permutations for every number and for every operator, we generate all possible orders. However this does not include all possible parentheses, it's easy to see that the combination:

1 / (2 + 3 + 4) 

is never included with the possible orders since we only calculate the sum from left to right. I have decided to leave out non-commutative solutions as this would introduce another set of permutations, and thus increasing the already factorial runtime even more.

The findings

I ran the simulation for multiple solution spaces, 1 digit numbers up to 7 digit numbers. For each of these ranges I calculated the amount of numbers that had a solution and converted those to percentages as seen in the graph below.


The 0-10 digit range is easy to explain, one zero equals 10 percent. The two digit realm doubles these numbers, as you have numbers containing zeroes (10, 20, etc) and one other combination of similar digits per each ten numbers (11, 22, etc) adds up to 20 percent. I expected the three digit numbers to be very hard to solve, as it’s quite easy to come up with numbers that can’t be solved. I never thought that it would practically be little more than a coinflip whether or not a random number could be solved!

The four digit range will finally answer my burning question of the ages: 97.3 percent of all numbers in this range had an answer! That explains why I never found a number that could not be solved. Basically one in every 40 four digit numbers you come up with should be impossible to solve, yet I never encountered one thus far.

As I initially expected, if you have more numbers to work with the puzzle should get more probable to have a solution. It probably isn’t easier to solve, but the solution is out there!

While the graph above has a neat explanation for each range, the numbers are a bit incorrect, here’s why: in the range of 10-100 we consider 90 numbers, some of which are double and some of which are not. For example 35 and the other permutation 53 both appear, but this is not the case for 60, since “06” was a single digit number. The graph below shows the percentages if we take this minor difference into account:


Digging deeper

Of course I didn’t stop here. While I was implementing this solution I started out with numbers that were only integers to test. Using only integers, I could not use divisions. I wondered if there were any numbers that only had a solution with one or more divisions.

This resulted in arguably the most interesting result from the whole experiment. The exact count of numbers that only have a solution using one or more divisions in the 4 digit range: 24. As I soon realized this is equal to the amount of permutations of a 4 digit number!

That means there is exactly one number (in a variety of different orders), and that number is 3468. I took the moment to appreciate the beauty here and just calculated numerous ways of solving it.

What is it about that 2.4% of numbers that have no solution? Strikingly similar to the above, 2.4% of 10000 equals 240 numbers. Once more we can see that these are permutations of 10 unique numbers. These are the 10 numbers:

1468
1479
1579
3678
3789
4568
4678
4689
5679
5789

Unfortunately I can’t find some black magic that ties all these numbers together yet, but maybe you can! Be sure to let me know! Below are two data pieces I gathered for all of these numbers: their sum, and the permutation of digits and operators that came the closest to zero.



The final thing I calculated is what would change if the solution was a different number than zero:
Which looks like something close to a skewed normal distribution. Interesting solutions were -24 with just over 50% and 72 with just under 50% of all numbers generating a solution.

Conclusion

Thanks for taking the time to read about this overanalyzed strange number game. I hope you still learned a thing or two from this futile effort to promote my nonsense arithmetics. If you enjoy me getting enthusiastic about absolutely nothing, feel free to bookmark this page.

Wednesday, August 21, 2019

Ryne

I just released a tech demo of Ryne, my game-engine-to-be. You can find more information and media on the Ryne Engine website.

Ryne is an experimental voxel pathtracer. You can try the tech demo yourself to see if it runs on your PC.

In the future I will release the C# scripting side open source. This will allow you to change most of the engine features yourself. You can see an overview of the functionality currently included in that project here. 



Why “release” it now?

I don’t want to create endless videos about a new technology that you will have to believe is real. Instead I’d like to include as many of you as possible while Ryne is in development. I know Ryne still has flaws and is nowhere near as usable as I want it to be, but I’m still convinced that putting out tech demos like these will bring the point across that we will get there eventually. This will both help me focus on the most important issues, and make everyone aware this is no longer a dream, but we can actually render something right now.

I’m trying to keep a stream of releases going out whenever I feel a new set of features or bug fixes are good to go.

If you’d like to discuss or have more questions, feel free to join the discord server.

Thursday, July 6, 2017

Automated marshalling of managed- to unmanaged structures

An art that I wouldn't even wish upon my greatest enemies to figure out.

I recently started a new project in a language very familiar to me: C#, a managed language. This means that all the memory management is done for you, which is both a blessing and a curse. For this project, I happened to struggle over the "curse part" of automatic memory management.

The problem I encountered is as follows: when you have two structures that are identical in terms of their members, their respective sizes can (and often will) differ in managed languages compared to unmanaged languages. For example, I have the following structure in C# and C++ respectively:

// C#
[StructLayout(LayoutKind.Sequential)]
struct DebugComponent
{
    public float4 Float4;
    public float Float;
}

// C++
struct CPP_DebugComponent
{
    float4 Float4;
    float Float;
};

The size of the structure can be found in C# by using Marshal.SizeOf() (or sizeof() in unsafe code) and reports that the structure is 20 bytes in size, which is correct. Note that I already applied the StructLayout to Sequential, as this will create a layout similar to unmanaged code.

The size of the same structure in C++ using sizeof() reports that the structure is 32 bytes. This is also correct, because the float4 type here is aligned to 16 bytes, meaning the structure will receive another 12 bytes of padding at the end, to make sure it aligns with 16 bytes.

Unfortunately trying to use this structure in a tool such as ManagedCuda, the CUDA kernel struct will use the C++ version, and when you call the kernel from your C# code you will have to use the other version. This creates a mismatch in memory layout, resulting in very weird artifacts after running the kernel, or even crashing because you're writing to unallocated memory in this case.

The "simple" solution I found is to manually expand the C# structure by using the StructLayout.Size attribute to extend the structure to 32 bytes instead of 20. After asking my question on StackOverflow, I didn't solve the problem to create these structures automatically without counting the sizes of every individual type in the structure itself.

So I had to switch up my solution a little bit. I created a project which contains the raw C# structures that I want to use, along with all their functionality like loading and serialization. I then created another C# project for the automated code generation. Using this project we can load our Structures as a dll, from which we can derive all the structures and what types they contain in text templates:
  • Structures: project that contains raw structures that will be used on the GPU
  • Tools: my general purpose project that will generate GPU versions of the structs defined in Structures.
In order to make this conversion as secure as possible I don't want to manually check every time I create a new structure if the GPU version has the same alignment and size. So I created two more projects:
  • AlignedStructsWrapper: A C++/CLI project that combines managed and unmanaged code
  • Tests: a unit test project
Using the CLI project, we can load both our versions of the structure: the managed C# version and the unmanaged C++ version. We can now measure the difference in their sizes:

public ref struct WrapperGpuDebugComponent
{
public:
 int SizeDiff()
 {
  int managedSize = sizeof(Tools::Content::Generated::DebugComponent);
  int nativeSize = sizeof(CUDA::CPP_DebugComponent);
  return managedSize - nativeSize;
 }
};

In the unit test project we load our CLI from reference and we can create a simple unit test that calls the SizeDiff function and checks if the difference is indeed 0:

[TestMethod]
public void CheckStructureSizes()
{
 WrapperGpuDebugComponent debugcomponent = new WrapperGpuDebugComponent();
 Assert.AreEqual(debugcomponent.SizeDiff(), 0);
}

Of course I also generated the CLI structures and the unit test functions automatically for every structure so I only have to recompile the projects and have everything tested.

Friday, April 3, 2015

Compute Shader Framework

In the last few posts about ray tracing I briefly mentioned compute shaders. If you don't know what they are, here is a short summary:

Introduction


Compute shaders are not part of the ordinary graphics pipeline, they can be used separately of any other stage. They are particularly meant for computation on the GPU. The compute shaders are in the same language as the other pipeline stages, like the pixel shader. In this case, HLSL. The compute shader takes advantage of the huge speedup the GPU has to offer over the CPU. This is done by taking into account the parallel computation power of the GPU.

When I first started out with compute shaders, I saw it as a black box and didn't really understand how to get started using one. After I found out that it can be really useful for large computations, I decided to implement one for my ray tracing project (with success). After this, I decided to make a simple framework allowing everyone access to compute shaders in a more user friendly way. This is only intented for DirectX compute shaders in C#

Framework

So without further ado, here is the framework: ComputeShader. You can also view it on GitHub.
On the first run, the framework will download some NuGet packages from SharpDX. If you have already have SharpDX installed, you can simply reference them to skip this part.

With this framework it's possible to bind any structure to the GPU. You can do numerous things with these structures in your shader, and then output some data that you want to know. You can read this data back in your code and use it later on! A simple example would be updating a particle system: you dump all positions and velocities to the GPU, and then calculate the next positions in your shader.

Usage:
In your project, either reference the ComputeShaderAddon.dll or add the project to your solution and reference the project.
You can now calculate anything on the GPU by using the next 4 lines of code (don't forget to include ComputeShaderAddon):
ComputeShaderHelper CSHelper = new ComputeShaderHelper(Device, "effect.fx");
int index = CSHelper.SetData<ExampleStruct>(data);
CSHelper.Execute(50);
CSHelper.GetData<ExampleStruct>(index);

This is the code from the example in the framework. What it does per line:
- Initialize the helper, this compiles the shader (if necessary) and sets it up.
- Set your data from any possible struct to the GPU buffers. The index is stored to retrieve the data later on.
- Executes the compute shader, the number is the amount of cores used on the GPU. The maximum number of cores is 1024, however this will use all calculation power of the GPU at once!
- Retrieve the data from the GPU, using the index from above.
Create your compute shader. Set the amount of cores you want to use in the brackets above the main function like this:[numthreads(cores, 1, 1)]

Likewise, save the length of the array of structs somewhere in the compute shader, if you want to use this like I did in the framework.
Done! Run your project!

Results
The example is a small program I wrote to test the computation power of the GPU in comparison with the CPU. The operation to perform is simple: for every struct you get, count numbers from zero to the length of the array and store them in the struct. Below you'll find a CPU and GPU version of this in code:
// CPU
for (int i = 0; i < amount; i++)
{
 int result = 0;
 for (int j = 0; j < amount; j++)
 result += j;
 data[i].Data = new Vector3(result, result, result);
}

// GPU -- ComputeShaderExample.fx in framework
[numthreads(nThreads, 1, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
 int range = nStructs / nThreads;
 for (uint i = id.x * range; i < id.x * range + range; i++)
 {
 int result = 0;
 for (uint j = 0; j < nStructs; j++)
 {
 result += j;
 }
 data[i].Data = float3(result, result, result);
 }
}

The framework ran with 50 cores on the GPU, and the results are as follows:

Last data: X:4,9995E+07 Y:4,9995E+07 Z:4,9995E+07
It took the GPU: 102 milliseconds
Last data: X:4,9995E+07 Y:4,9995E+07 Z:4,9995E+07
It took the CPU: 283 milliseconds

With this small calculation the GPU, using 50 cores, is about 3 times faster than the CPU, using only one core.

Some scalings:
StructsCoresGPU time (ms)CPU time (ms)
10k50102283
20k503801131
30k507512463
10k10452283
10k100119283
10k1000480283
You can see that the amount of cores is something to fiddle with, since the resulting time differs greatly. This is because the overhead of running all the threads costs more than the actual computation itself, so be careful with this!

Fun stuff: the outcome is easily calculated by: n(n + 1) / 2. This is an easy way to calculate a numerical sequence like this. In this case, n = 9999 (because we start at 0).

Future work

This framework currently only supports Unordered View bindings, so if you would use DirectX 10 you can only bind one array of structures to the compute shader and that's it. In DirectX 11 this is increased to 8, which is supported in this example project.

Currently you still have to set the length of the array and the amount of threads manually in the compute shader. I don't know if it's possible to change this dynamically from code, but if I ever find a way, I will update the framework for sure.

Wednesday, January 21, 2015

Raytracing Part 3

The final post in this series about my ray tracer. I spent last weekend creating some black magic called a compute shader. It allows you to use your GPU to aid in calculations. In my case this came in quite handy with all these ray calculations. The GPU is optimal for calculations that can be executed completely in parallel. Fortunately, raytracing falls in this category. 

This is the first result worth looking at:



First thing to notice is that it's quite grainy. This is because there are not that many samples per pixel, only about 5. However, the (still local) Cook Torrance shading is already working as you can see on the metal-ish sphere in the back.



The main thing to notice here are the soft shadows. A small change, but 'realism' awaits. There are some incorrect results in this image, because you can see the diffuse reflection of the green box is still biased. The local shading model from two lights draws the reflecting rays in their direction, meaning this is not a totally correct result.



The box in the middle suddenly became radioactive and now emits light. The image is still biased, even the emitting box only emits towards the light sources.



Experimenting with rougher surfaces and more glossy surfaces.



The first results of refracting rays.



Perfectly refracting sphere showing the bias is indeed gone here. The grain is also gone since I actually took the time to sit back and wait for the image to converge (this image took about two minutes to converge to this state).



The same scene with different materials and a more emitting 'roof'.

Wednesday, January 14, 2015

Raytracing Part 2

In this post some more images of the continuing project on raytracing. First of all, I found out that the bounding spheres were way too big, and a big performance hit on my ray tracing project. Instead of spheres I now calculate bounding boxes around all the triangles in the model and test with these instead of the spheres. All in all, this improvement alone did not speed up things enough. By looking at my quickly made octree, I found some fatal flaws rendering the octree quite worthless. All of the triangles were stored in the topmost bounding box instead of the leaves as they should be.

This image shows the octree of the Stanford dragon and 2 teapots:



After I got all this working I was quite amazed by the quick rendering times. It took almost half the time as before, making it possible to even render this huge dragon:





The next image shows some reflections in the windows and the body of the car:



Of course, I could never stop here. So why not add some refraction as well:



By combining the result of reflections and refraction:



Now, these images are already quite fancy. However, there is still a lot of work to do. The following image shows a sneak peak of the next and final part of this raytracing series. By tracing multiple rays within a pixel area we have more information about the color. Combining this with a nice gaussian function over multiple pixels I have created a nice anti-aliasing function:



In the next part I will show results of a distributed raytracer slowly converging towards rendering an image with global illumination effects.

Tuesday, January 6, 2015

Raytracing Part 1

This post shows the progress for an assignment I'm currently creating for a university course. It's about creating a raytracer starting from scratch. I chose to implement it using SharpDX. I first started by creating a standard renderer, which draws triangles on the GPU using DirectX. After I could load in simple objects and draw them on the screen, I created a basic raytracer.

First I had to convert the loaded models in SharpDX to triangles I could actually use to trace. After some work I finally got some results and started taking screenshots. Hence the result so far in graphical representation:

The model drawn with the basic effect



Silhouette by raytracing the boundary. The gray area is the bounding sphere (which is a little off scale).



Material loading, getting the 'correct' colors for the car. The light color interfered here, thats why the colors are still a little off.



I forgot to order the triangles by depth! What a mess..



After ordering the triangles



Blinn-phong shading.



More lights! Shadows!



Soft shading, taking the average of three normals for each point on a triangle.



Our car is back! However some normals are still incorrect, you can see headlights missing.



Soft Shadows! Sending 20 rays from every point to the lightsource to see if we have shadow. The correct normals have been put in.


Blinn-Phong shading back in the picture. The car looks really metallic now:

There are still some strange 'light artifacts' on the floor and the car window. More updates will be in the next post.

Monday, September 8, 2014

From zero to lighting in 2D

This tutorial is about spicing up your 2D game with some awesome lighting. I made this tutorial because there aren't any out there yet, and it's a very cool effect to add to your 2D game.

What you need to know

First off, I assume you have some familiarity with C#, or coding in general. Secondly it is advised to at least have programmed in a shader language before. Used in this tutorial is HLSL. The rest is what this tutorial is for!

The final result

You can download the code example here (or you can scroll down to find some explanations). The final result will look something like this:




Normal maps

Normal maps are textures to containing a color indicating the normal of a certain pixel. How does this work? Take the normal map used in the code example alongside the original texture:




The left texture contains the normal colors, and on the right is the generated color defining the normal. To calculate the actual normal vector, we have to apply a little transformation:
$$normal = 2.0 * pixelcolor - 1.0$$

To explain this better, we take the most common color in the picture, a light blue-ish color. In RGB values it is about $((128, 128, 255)$), which is reduced in the range of [0,1]as $((0.5, 0.5, 1.0)$). After applying our transformation the value becomes $((0.0, 0.0, 1.0)$) which is a normal pointing in the Z direction.

In our 2D game this value will point from screen towards the viewer. As you can see in the normal image, there are several red and green colored portions, which will affect the direction of the normal. With this information we can add fake depth to a plain 2D texture!

The drawing setup

To pass this information to our lighting effect we need to have this normal map ready, which means we can't draw everything on the screen immediately. The setup used for this comes close to Deferred Shading. We only need the color and normal buffer, since the depth buffer is worthless here.

All the normal sprites are drawn first, as you're used to, except, this time we save them to a rendertarget. After which I draw all of the normals to another rendertarget. Unlike standard deferred shading, I chose to render the lights to a seperate rendertarget here. If you wish, you can combine drawing the textures and drawing the lights to a single pass. This was merely done to show the different rendering steps here.

The actual lighting magic
Because it's a 2D game, you expect to need to draw a "lighting texture", something like this:




But we don't need to! Since we have a normal, we can simply apply the technique to draw a light in 3D, which is really fancy and easy to create. The effect I used to create this tutorial with is called Diffuse Reflection, or Lambertian Reflectance. We set up a point light (which is, a point from which light emanates) and calculate the pixel color on the GPU.

Diffuse reflection requires three things: the position of the light, the position of the current pixel being shaded, and the normal at that position. From the first two you can calculate the light direction, and by looking at the value of the dot product from the light direction and the normal you can determine the lighting coefficient.

Sometimes you will want to rotate the normal retrieved from the normal map. This is done by creating a separate rotation matrix and adding it to the shader. More information about creating such a matrix can be found in my other tutorial series on rotations.

Finding the correct normal on the pixel position is rather easy: we have a full screen buffer of normals, and a position given by the draw call. Dividing this position by the screen size, we have the texture coordinates of the normal pixel ranging in [0,1]. Exactly what we need!

Code example

All of this code can be found in the source code, I'd like to point out a few things in this article though, here's the code used for lighting in HLSL:
// Basic XNA Vertex shader
float4x4 MatrixTransform;
void SpriteVertexShader(inout float4 color    : COLOR0,
     inout float2 texCoord : TEXCOORD0,
     inout float4 position : SV_Position)
{
     position = mul(position, MatrixTransform);
}

float4 PixelShaderFunction(float2 position : SV_POSITION, 
         float4 color : COLOR0,
         float2 TexCoordsUV : TEXCOORD0) : COLOR0
{
     // Obtain texture coordinates corresponding to the current pixel on screen
     float2 TexCoords = position.xy / screenSize;
     TexCoords += 0.5f / screenSize;

     // Sample the input texture
     float4 normal = 2.0f * tex2D(NormalSampler, TexCoords) - 1.0f;

     // Transform input position to view space
     float3 newPos = float3(position.xy, 0.0f);
     float4 pos = mul(newPos, InverseVP);

     // Calculate the lighting with given normal and position
     float4 lighting = CalculateLight(pos.xyz, normal.xyz);
     return lighting;
}

// Calculates diffuse light with attenuation and normal dot light
float4 CalculateLight(float3 pos, float3 normal)
{
   float3 lightDir = LightPosition - pos;

   float attenuation = saturate(1.0f - length(lightDir) / LightRadius);
   lightDir = normalize(lightDir); 
 
   float NdL = max(0, dot(normal, lightDir));
   float4 diffuseLight = NdL * LightColor * LightIntensity * attenuation;
 
   return float4(diffuseLight.rgb, 1.0f);
}



As you can see, the shader consists of a vertex and pixel shader. The vertex shader simply passes on the color, texture coordinates and position. It only transforms the position with the given matrix. After the vertex shader we know the rectangle on the screen and the pixel shader will analyze all the pixel inside of it.

What you first see in the pixel shader is getting the texture coordinates from the position. This is done by dividing it through the screen size and adding half a pixel width (so we're in the center of the pixel). With this coordinate we can sample the normal map to get the color of the normal, and as shown in this article, calculate the actual normal from it. What happens next is retrieving the original position, by multiplying it with the inverse view-projection matrix. We can now calculate the lighting with given parameters.

Where the light calculation method is nothing more than a normal times lightdirection to see if the surface should get lit. Of course, not to forget, the attenuation which looks at the range of the light and caps it (smoothly) by multiplying it with this value.


Optimization

You want to draw a lot of lights, right? Normal deferred shading can't handle a lot of point lights, since you have to redraw the whole screen for every pointlight. Thus follows the first optimization: if we only draw a small square on the screen were we expect the light to shine, we don't draw the rest of the screen. This is done quite simple by adding a light radius, from which we can create a rectangle to draw in spritebatch.

Since we don't need to draw any textures, and we still have to make a draw call, I found the following optimization: in spritebatch you have to supply a texture for a draw call, the best way to use our previous optimization is drawing a pixel and upsize it to the square. This way, the pixel shader can sample the normal map and output the lighting on the positions given by the draw call. In the code I just pass the normal map as texture for simplicity.


I hope you learned something from this tutorial, and sure hope to see some awesome games created with this effect!

Wednesday, January 29, 2014

Mathematics behind rotation part 3

Back to Part 2

In this final part I will show how you can use the last two parts of the tutorial in code for XNA. First we'll look at the Draw command from XNA's SpriteBatch and to conclude this series a little abstraction to rotating 3D models.

XNA is a very powerful game-development tool, and it surprisingly easy to use for rotations. If we want to draw the green square from part 1 in the Draw function from XNA, the code would look like this:
// The standard Draw method
Texture2D square; // Your square texture
public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
{            
    Vector2 position = Vector2.Zero;
    Vector2 origin = new Vector2(square.Width / 2, square.Height / 2);
    float rotation = (float)Math.PI / 4;
    float scale = 1.0f;
    float depth = 0.0f;
    spriteBatch.Draw(square, position, null, Color.White, rotation, origin, scale, SpriteEffects.None, depth);
}

This special overload for the Draw function allows us to rotate the sprite with a certain amount. It takes a radian as input, represented in a float value of $\frac{\pi}{4}$ which equals 45 degrees. I'm not going throught the rest of the arguments you have to fill in as most of them are quite obvious and is out of scope for this tutorial. All of the theory that I've explained about rotations is well hidden in the code of XNA itself. You only have to define an origin and then draw the texture in this special overload of the Draw.

For creating rotations in 3D you will have to use rotation matrices. You can use them to rotate in 2D as well if you use the rotation over the Z-axis of course. To define a rotation matrix you can use the following code:
Vector3 position = Vector3.Zero;
float angle = (float)Math.PI / 4;
Matrix rotationX = Matrix.CreateRotationX(angle);
Matrix rotationY = Matrix.CreateRotationY(angle);
Matrix rotationZ = Matrix.CreateRotationZ(angle);
position = Vector3.Transform(position, rotationZ)

This will create a rotation over the Z-asix for our defined position here. I've also included the X and Y matrices, just for example. These matrices are in fact the matrices we've talked about in the last part. Note here that Vector3.Transform() does not apply any "magic" behind the scenes, it only rotates around the origin. An example to demonstrate this:



The green circle here represents only a rotation applied to an object. If, however, you first chose to do a translation on the object (the red arrow) and then apply a rotation, it will still rotate around the origin, being the center of the axis here. So my tip (and warning) here is to apply the rotations first and then apply other matrix operations. This will make the model rotate on the spot and then translate to the position, which is hopefully the result you wanted :).

This is it for this tutorial series on rotations, I hope you learned something from all of this and definitely hope to see you back for my next blog entry! If you have any questions, you can leave a comment below.