C#/C++: How to visualize muli-dimensional arrays - c#

For example: A two-dimensional array can be visualized like a brick-wall with square bricks, where every brick represents a coordinate in our array. A 3-dimensional array can in the same way be visualized as a box, or cube.
But, here is the tricky part, how do you visualize an array with multiple (More than 3) dimensions? Or, for that part, how do you visualize an array with not only multiple dimensions, but multiple dimensions in several layers?
For example: How do you visualize an array such as this: Array[3,3,3,3][3,3][3,3,3,3,3][3]?

How you visualize the arrays really depends on their practical use. If you are using the arrays for spacial relations then you can benefit from imagining it as a cube, but you also lose the need to imagine more than 3 dimensions. If you really and truly wanted to implement a fourth time dimension, you could just imagine your cube with the contents changing as time progresses.
Otherwise you may be keeping track of strongly related records. Perhaps each of the first elements is a galaxy, the second-level elements are star clusters, the third-level elements are solar systems, the fourth-level elements are planets, the fifth-level elements are continents...
In this case you can imagine it was arrays within arrays. If you need a 4-dimensional array then you can imagine a cube, but each sub-cube is actually a one-dimensional array.
If you need a 5-dimensional array then you can imagine a cube, but each sub-cube is divided into your "brick wall" example.
6-dimensional is a cube with each sub-cube being its own divided cube.
This tends to fall apart at after 6 dimensions. Beyond this there is usually a more practical reason that you need so many dimensions. For example, websites like eHarmony do their match-making by using normal geometry on 20+ -dimensional spaces. You have one dimension for "humor", one for "good looks", one for "love of shopping"... Then you can take two people and apply distance formula (square each of the dimensional differences, add these differences, square root) and determine how compatible the two people are. So if one person scored "5, 3, 9, 2, 8, 4, 7, 3, 1" on our 9-dimensional personality matrix and another scored "9, 3, 7, 1, 8, 2, 8, 4, 7" then your compatibility is:
sqrt((5-9)^2+(3-3)^2+(9-7)^2+...)
This can be applied over infinite dimensions and still work. Since these dimensions don't apply to space, however, there's no need to visualize them as such. Instead, in this particular case, we can actually imagine it as just a single-dimensional array with several integer values. The reason we can simplify this array, mind you, is that our multi-dimensional array only contains a single "1" and all of the rest are "0"s (indicating the location of the person in this array).
Moving away from the eHarmony example, the point is- after a certain amount of dimensions you usually have a practical purpose for the array which lends itself to a method of perceiving it.

Some people can mentally model n-dimensional geometry for n > 3, at least as far as simple shapes go, and some cannot. (I was quite surprised when recently talking to someone whose field was advanced n-dimensional geometry to learn that he couldn't visualise a hypercube, while I can but find his mathematics quite beyond me).
It isn't really necessary though. Indeed, it's rarely particularly necessary to visualise a two-dimensional array as Cartesian coördinates either - when you are using a 2-dimensional array in practice you have some purpose for each axis, and that purpose quickly becomes more important than any visual representation.
If you do need to, then consider that a 2-dimensional array can also be considered as an ordered set of 1-dimensional structures. Likewise a 3-dimensional array can be considered an ordered set of 2-dimensional structures, or a set of sets of 1-dimensional (with these sets of equal size - allowing different sizes moves matters into jagged arrays).
Hence a 4-dimensional array can be considered an ordered set of 3-dimensional structures, and so on.

You don't. It's rare that you even need more than 2 or 3 dimensions. If you need more than that, then perhaps the extra dimensions should be modeled as properties on an object instead, in which case you can see them as attributes and not try to imagine some mythical hypercube.

There are many lovely ways to visualize multidimensional data. One of my favorites is Alfred Inselberg's Parallel Coordinates, which represents each dimension as a vertical axis, and each data point as a thread connecting them all:
Another great visualization is Ramana Rao's Table Lens (pdf):
This represents each dimension as a column, as in a spreadsheet, but graphically rather than numerically. It is particularly good at showing correlation between dimensions; as you sort by one dimension, it is easy to see how correlated dimensions sort alongside it.

Try being subtractive about it. If you need to imagine, say, a ten dimensional array then start by imagining the set of all n-dimensional real-valued Euclidean vector spaces for all finite non-negative integers n. { R0, R1, R2, ... }
Now imagine taking away almost all of that, leaving just R10.
Now imagine taking away almost all of that, so that you have just the integer lattice points in R10 left.
Now imagine taking away almost all of that, so that you have just a hyper-rectangular subset of the integer lattice points.
And you're done; that's a good visualization of a 10-dimensional array. It's really very small when you think about it as a subset of the set of all possible n-dimensional vector spaces.
If the subject of high-dimensional spaces interests you, you might want to read my gentle introduction to some interesting facts about search algorithms on high-dimensional vector space databases:
http://blogs.msdn.com/b/ericlippert/archive/tags/high+dimensional+spaces/

Over 3 dimensions, your only options are either a tree view or a drill-down.

The same way you visualize 4 spatial dimensions: "slice", superimpose, or project it onto what you already understand and can visualize.

Think of every extra dimension as an "enclosing box". Think of a 2D array as an array of 1D arrays, of a 3D array as an array of 2D arrays, and so on.
Here are some examples...
1D 1x2 array:
[ 1, 2 ]
2D 2x2 array:
{ [ 1, 2 ], [ 3, 4 ] }
{ [ 5, 6 ], [ 7, 8 ] }
3D 2x2x2 array:
( { [ 1, 2 ], [ 3, 4 ] }, { [ 5, 6 ], [ 7, 8 ] } )
( { [ 9, 0 ], [ 1, 2 ] }, { [ 3, 4 ], [ 5, 6 ] } )

You could visualise a financial report as an array where data is coming in from multiple entities in spreadsheet form:
a single spreadsheet of sales data would be a 2D array (e.g. sales for each month in the quarter per profit centre);
multiple tabs in a workbook (one for each subsidiary) would be a 3D array;
Then, for purposes of global consolidation, a Controller may receive a workbook from each Region - this would be the 4th dimension. A fifth dimension could be "time" if you have a need to manipulate sales data over time (to spot trends for instance).
In theory, you could hold multi-year, multi-region sales data in a single 5D array variable.
As people have said above, you really need to have an application in mind first and then the logical data structure will help define a suitable physical form. Any set of attributes that can be modelled relationally can be placed in an array normally.
tony

Visualize a 4D array as a 1D array of cubes. A 5D array as a 2D array of cubes. And a 6D array as a 3D array of cubes, or a cube of cubes. A 7D array as a 1D array of cubes of cubes, etc...

Ignoring whether these dimensions are neeeded, why not just envision a 4D array as a 1D array (line) of "cubes". (ie: an 1D array where each element points to a 3D cube). This can be scaled up as needed (ie: 2D surface where each element points to a cube). This of course isn't how a hypercube would 'look', but that isn't required.

tabs :)
tabs of 3 dimensional data gives you 4 dimensions, tabs of tabs gives you n dimensional.
not thats necessarily the best way to visualize it. Also not good for rotating in any of the dimensions.
but then, it depends what you are trying to visualise
RGB for instance can be turned into a 2D map and then projected onto a cube, giving you 4d information

Not looking to give away the farm here, but this is an example of how I look at multidimensional arrays in PHP.
$map[room][x][y][z][id][photopath][flag1][flag2]
I imagine what it would look like as a point in 3D space, then I just add sorting attributes. Here, imagine you're playing Doom 3. Each map is divisible into rooms, which have pixels with x, y, and z coordinates. Each of those points can have an object id (monster, item, etc.) associated with it. I've added more attributes for my application, but this is basically it. A point in the array doesn't necessarily have to be geometrically accurate; it can have any meaning. Whether this is similar to what other people do, I don't know. I do know that using the gd graphics library would make a nice visualizer for multidimensional arrays on the fly, but I didn't get to that project last time I was working for this client.

Related

Divide a 2d array into another 2d arrays

I am trying make a falling sand simulation game something like Noita.
and I need to figure out how they divided Noita's world into chunks 'since that's what the devs said in theyr gdc talk for optimizing the world' and I am not sure on how they did that.
I also found this person called "MARF" on youtube:
https://www.youtube.com/watch?v=5Ka3tbbT-9E&list=PLn0iQu83pjfaNwbpEGbn0orKQHbKeD81p&index=2&t=1140s&ab_channel=MARF
in "17:35" he says that he divided the world into chunks and He didn't even show how he did it.
so does someone know how to do this?
I thought of using the Array.copy function to copy every 16 x 16 bit into a new array and then I add it into a List of 2d arrays and then Updating everychunk needed. but this method is supported for only 1d arrays. :/
I alsow tried making 16 x 16 worlds as chunks and then offsetting them.. I couldn't offset the arrays properly and it would be a nightmare to figure out how to move elements between chunks.
You are asking the wrong questions.
Please look up "quad trees" on google.
Not great for moving objects, but good for static 2D worlds.
The idea of a chunk is to divide the word into smaller parts.
By dividing the screen into smaller units as an array for moving objects, collisions can be limited to those array values near the object in question.
A chunk is simply an array where the dimensions are reduced by a fixed value. For example, 32x32 pixels is represented by a single element in the array.

Indoor path-finding c# wpf

I am currently developing an indoor path-finding. I have multiple floors and different rooms. How will I be able to implement a* algorithm in the images of each floor using c# wpf?
I use spatial A* for the game I'm working on.
Spatial A* uses movement "cost" to work out the best route between two points. The cost mentions is supplied by an array. Usually a 2d array of number - float uint or whatever.
Moving through a square/cell at position x,y thus costs the number in that 2d array. EG costs[2,3] would be the cost of movement through the cell 2 cells across from the left and 3 down from the top of an imaginary grid projected onto your "room".
If the move is diagonal then there's also a multiplier to consider but that will be in whichever implementation you go with.
Hence you need a 2d costed array per floor.
You would need to somehow analyse your pictures and work out an appropriate size for a costed cell. This should match the smallest size of a significant piece of terrain in your floor.
You would then translate your picture into a costed array. You've not told us anywhere near enough to tell you specifically how to do that. Maybe that would have to be a manual process though.
Blocked cells get the max number, empty cells get 1. Depending on your requirements that might be that. Or alternatively you might have actors leaping tables and chairs etc.
You give the pathing algorithm start and target location (x,y), the appropriate costed array and it works out the cheapest route.

Cartesian product with restrictions

Hello, I am new in C# Programming and I would like to ask a question related to the cartesian product. I found the method for calculating through StackOverflow and I used it. The method I use is:
char[] letters = { 'A', 'B', 'C' };
int[] numbers = { 1, 2, 3, 4 };
string[] colours = { "Red", "Blue" };
var cartesianProduct = from letter in letters
from number in numbers
from colour in colours
select new { letter, number, colour };
In my case the cartesian product means something. For example for the combination "A1Red" I upload to the program an array with the consistency values between A and 1 and A and Red. What I need from the program is to give me the sum of this values.
It works perfectly if i have 10 arrays to find the combinations but it stuck when I need to calculate over 23 arrays and total amount of combinations more than 100 trillions.
Is there something that I can do to make it run fast?
Unfortunately, there is not much you can do. Your problem requires so-called "exponential time".
As #esel points out, you can do some optimizations, and you can use parallellism.
But unless there is an underlying structure to your arrays, something correlation between the data that you can exploit, you're simply stuck with this "exponential time". Every array added to your list, will multiply the amount of time needed to compute. This escalates fast.
There is a very small consolation: as soon as any of your arrays is empty, this flattens the whole thing to the empty set.
See if there is an underlying structure to your data that you can exploit.
Edit:
In the comments, you mention taking the first 10.000 combinations. I'm not quite sure I understand the rest, but if you need the first 10.000 of cartesianProduct (i.e. unprocessed), then there is a way:
var first10000 = cartesianProduct.Take(10000);
This works because LinQ uses "lazy evaluation": it will not calculate the values in the cartesian product until it has to. As a consequence, no more than 10000 values will be calculated.
However, if some processing needs to be done first, like sorting, then I'm afraid you're out of luck.
There are ways to make some algorithms run more quickly, using parallelism to process multiple parts of the domain at once by taking advantage of many cores and special CPU or GPU instructions.
However, there are temporal limits. If the answer space is indeed that large, you simply cannot compute the results in a reasonable amount time.

Implementation of array with negative indices

I am making a game with a world that extends infinitely in every direction. This means that you can be at position X:50, Y:50 or X:-50, Y:-50. But... I can't really do that with a normal C# List...
All the ideas I've come up with seem to be too complicated/inefficient to work...
The easiest way to implement infinite grid is using a sparse matrix with a dictionary with an x,y pair as the key and the data you want to store as the values. This is fast, easy to implement, and memory friendly if your grid is sparse.
Another way is a linked grid (similar to linked list, but with pointers to 4 directions), or a tile-based approach to reduce the overhead of linked grid (a tile is a linked grid of NxN arrays). Implementation of tiles is quite complicated, but is a good tradeoff between memory and performance for very dense grids.
But my personal favorite approach is to use the even-odd transformation. So odd indices are positive, while even numbers are negative. To transform from virtual index to the physical index, you use the formula p = abs(v * 2) - (v > 0 ? 1 : 0) and to convert physical to virtual index you do v = (p % 2 == 1 ? +1 : -1) * ((2*p + 3) / 4). This relation arises because there is one to one and onto relation (bijection) between natural numbers and integers (0 <-> 0), (1 <-> 1), (2 <-> -1), (3 <-> 2), (4 <-> -2), (5 <-> 3), (6 <-> -3), .... This approach is fast, simple and elegant, but not very great memory wise when you have very sparse grid with items extremely far from the center line.
Unless you have a TON (yes, a TON of bits...) of cells, you can use dictionaries. Combine that with a System.Drawing.Point as the key, and you get a good thing going on:
Dictionary<Point,YourGridObject> myMap = new Dictionary<Point,YourGridObject>();
Edit: In addition to the dictionary, each cell can have a reference to it's adjacent cells, this way you can use the dictionary to directly go "somewhere", but then navigate with the adjacent. I used that way to implement an A* pathfinding algorithm in an hex grid.
Edit 2:
For example, if you then want to access a specific coordinate, you can simply
var myTile = myMap[new Point(25, -25)];
Then, you want to get the East tile, you can
var eastTile = myTile.East;
Your grid object could also implement an offset method so you could get the 'West 2, North 5' tile by
var otherTile = myTile.Offset(-2, 5);
How about using two List underneath for expansions in two different directions?
I'm not certain if this is more complicated than you want to deal with, but have you considered using polar coordinates instead of cartesian? There are no negative numbers in that coordinate system. I realize that the coversion is difficult at first, but once you wrap your head around it, it becomes second nature.
You could use Dictionary, which has all the capability of an array except with negative indexes obviously.
Computers cannot store infinite arrays.
There must be a boundary to your array, remind that somewhere in code you declared a specific size during initialization of your array.
Perhaps you resize it somewhere, but that still leaves an number range from 0..to.. max.
So what you should do, write a function that allows for relatively positioning in such a map. So you store your current map[x,y] as a position.
And your able to go up, by having a function that add/substracts from your current position relativly.
This keeps your code easier to understand too.
If your not dealing with game maps but number ranges, lets say vectors
you could create a list of n points, or a 2d dictionary.
I'm posting it here, cause your problem might lead people to writing wrong code.
Also adding for other people in situations where there is a border around a map (typical in games scenario, and image manipulation.
where your data goes from [-1..width+1] just dimension it as [0,width+2]
then loop trough it starting 'for (int x = 1; x < Width+1; x++)'

Game level read from file in XNA

I've been working on a tile based map engine for my game project in Xna C#. The system, like most others, uses a digit corresponding to a tile in a tileset mapped to a specific position on screen. This works fine, but requires every cell on screen to have a number manually entered. Instead, I've decided to have level layouts read from a .txt containing the number of each tile in the position it would be ingame, like so:
1111
0110
1001
1100
Where 1 is grass and 0 is dirt. Again, I'm aware this is a common technique. The code I have written can read each line and set the next position in the first column to the corresponding tile graphic. This is fine, but it does not help with the rest of the map. I've been searching and cannot find how you would split each number in a row into a separate number, so that the first line would read (0,0) = 1, (0,1) = 1, etc, so I can then match the coordinates to the x and y position on the map, and the value to the type of tile.
So what I need is the ability to assign a 2d array corresponding to the current position (how many characters left in the file, how many lines down in the .txt file), so I can just run two branched for loops (x and y) for every tile in the level ie:
for (x=0; x<levelwidth; x++)
{
for (y=0; y<levelheight; y++)
{
Row[x].Column[y].Tile = Convert.ToInt32(filepos[x,y]);
}
}
You don't want to use 2D arrays because of heavy performance issues.
Also, you probably want to use a separator between tile numbers, like this
1,1,1,1
1,0,1,1
for two reasons; 1 you can use more than 10 different tiles, and 2 you can then use String.Split() and Int.Parse() in order to get your tile IDs and build your map.
In order to use a 1D array, instead of doing myMap[x][y], you do myMap[y*mapWidth+x].
I switched to using XML so that I could more easily edit and read the file. That also gave me a great way of indicating the end of a row of tiles in my map as well as an easy way of identifying up front just how many columns/rows my map had prior to the reader loading it in the game.
The sample for the code can be found on my site in the "Looks Level to Me" sample and it may be that it will help get some ideas for how to change your current approach.
While the commas are the best approach you can also use .substring to take it apart if things are of fixed length.

Categories

Resources