Bart
WiseBart
GM Version: ALL (the code makes use of ds_grid accessors but that is not a requirement)
Target Platform: ALL
Download: N/A
Links: N/A
Summary
This tutorial series shows how certain calculations can be done using ds_grids.
Each tutorial focuses on a specific calculation or algorithm.
Tutorial 1: The basics
This first tutorial introduces the basic idea.
We look at a way to calculate many dot products seemingly at once.
(Of course a loop is executed in the background but in this case it's nothing that we, as the programmer, need to worry about)
Representing vectors in ds_grids
First we need a way to store vectors in a ds_grid.
That's actually pretty straightforward to do: in each column we store a vector's components.
The number of rows gives us the size of the vectors we're working with (vec2, vec3).
In this case, we extend this idea to a "list" of vectors, where each column contains a vector:
! Keep in mind when working with ds_grids that the x coordinate represents the column and the y coordinate represents the row.
Each column contains a vector and the rows contain the components.
If we now run the game in debug mode and have a look at grd_vectors we see the following:
Quite intuitive. For each vector in the list we can click the (+) in front of it to see its components.
Time to do some maths with this!
Interpreting the formula
Once we have the data in the grid, we can truly go full speed.
As the most simple example, let's take a look at a common mathematical operation: the dot product.
For two vectors with 3 components, it looks like this:
The thing here is to actually get an idea of what the formula does.
We see:
That makes ds_grids particularly interesting for this since we can use ds_grid_multiply_grid_region and have those 3 multiplications done with a single line of code.
And it gets even better: if we pass the entire grid as the region, i.e. the "list of vectors", the multiplications are performed on all pairs of vectors at once!
For the addition, we can use ds_grid_sum on the column of resulting products to get the actual dot product of two specific vectors.
The code
We first define one grid for the list of left inputs of the dot product, one grid for the list of right inputs and one for the products.
Then we set two vectors. Obviously you can define as many as 100 in this example and the code won't change.
We then copy the values in A to the results grid since we obviously don't want to overwrite them during the calculations - only as an input - and them multiply the components for all vectors.
From then on it's possible to get the result of each dot product using ds_grid_sum.
If we look at our example and do the maths ourselves we get
Which corresponds to the value of
And that's all for now. We basically made an alternative to dot_product_3d that does at least part of the math "in parallel" for several pairs of vectors at once.
But we're not entirely there yet. The current method requires no less than 3 ds_grids and we still need to use a loop if we want to get the dot product for each pair of vectors.
In the next tutorial, we'll have a look at how to fix that and optimize the calculation even further!
Target Platform: ALL
Download: N/A
Links: N/A
Summary
This tutorial series shows how certain calculations can be done using ds_grids.
Each tutorial focuses on a specific calculation or algorithm.
Tutorial 1: The basics
This first tutorial introduces the basic idea.
We look at a way to calculate many dot products seemingly at once.
(Of course a loop is executed in the background but in this case it's nothing that we, as the programmer, need to worry about)
Representing vectors in ds_grids
First we need a way to store vectors in a ds_grid.
That's actually pretty straightforward to do: in each column we store a vector's components.
The number of rows gives us the size of the vectors we're working with (vec2, vec3).
In this case, we extend this idea to a "list" of vectors, where each column contains a vector:
GML:
// Let's take enough vectors
vectors = 100;
// Create the grid, all values are set to 0 by default
// (i.e. the grid contains all zero vectors)
grd_vectors = ds_grid_create(vectors, 3);
// Vector 1
grd_vectors[# 0, 0] = 0;
grd_vectors[# 0, 1] = 1;
grd_vectors[# 0, 2] = 2;
// Vector 2
grd_vectors[# 1, 0] = 3;
grd_vectors[# 1, 1] = 4;
grd_vectors[# 1, 2] = 5;
// Etc.
// ...
! Keep in mind when working with ds_grids that the x coordinate represents the column and the y coordinate represents the row.
Each column contains a vector and the rows contain the components.
If we now run the game in debug mode and have a look at grd_vectors we see the following:
Quite intuitive. For each vector in the list we can click the (+) in front of it to see its components.
Time to do some maths with this!
Interpreting the formula
Once we have the data in the grid, we can truly go full speed.
As the most simple example, let's take a look at a common mathematical operation: the dot product.
For two vectors with 3 components, it looks like this:
GML:
dot = ax*bx + ay*by + az*bz;
We see:
- Three times a multiplication *
- Two times an addition +
That makes ds_grids particularly interesting for this since we can use ds_grid_multiply_grid_region and have those 3 multiplications done with a single line of code.
And it gets even better: if we pass the entire grid as the region, i.e. the "list of vectors", the multiplications are performed on all pairs of vectors at once!
For the addition, we can use ds_grid_sum on the column of resulting products to get the actual dot product of two specific vectors.
The code
GML:
// Create the grids that we'll use
vectors = 100;
grd_A = ds_grid_create(vectors, 3);
grd_B = ds_grid_create(vectors, 3);
grd_result = ds_grid_create(vectors, 3);
// Add two "vectors" that are the inputs of the first dot product
grd_A[# 0, 0] = 0;
grd_A[# 0, 1] = 1;
grd_A[# 0, 2] = 2;
grd_B[# 0, 0] = 3;
grd_B[# 0, 1] = 4;
grd_B[# 0, 2] = 5;
// First copy the values in grd_A to the grd_result since we don't want to overwrite values!
ds_grid_copy(grd_result, grd_A);
// Perform the multiplication component per component
ds_grid_multiply_grid_region(grd_result, grd_B, 0, 0, ds_grid_width(grd_result)-1, ds_grid_height(grd_result)-1, 0, 0); // ax*bx, ay*by, az*bz
// Get the final result by taking the sum of the products (note the indices!)
dot = ds_grid_get_sum(grd_result, 0, 0, 0, 2); // (ax*bx)+(ay*by)+(az*bz)
Then we set two vectors. Obviously you can define as many as 100 in this example and the code won't change.
We then copy the values in A to the results grid since we obviously don't want to overwrite them during the calculations - only as an input - and them multiply the components for all vectors.
From then on it's possible to get the result of each dot product using ds_grid_sum.
If we look at our example and do the maths ourselves we get
0*3+1*4+2*5 = 14
Which corresponds to the value of
dot
.And that's all for now. We basically made an alternative to dot_product_3d that does at least part of the math "in parallel" for several pairs of vectors at once.
But we're not entirely there yet. The current method requires no less than 3 ds_grids and we still need to use a loop if we want to get the dot product for each pair of vectors.
In the next tutorial, we'll have a look at how to fix that and optimize the calculation even further!
Last edited: