I'm trying to convert a c# code into a matlab code. So in c# code I have a linklist where x,y coordinates are inserted. I'm using "Array.Resize(ref arr, 1);" to insert x,y value. So whenever I insert values old value goes to the bottom of the array. I'm also using resize method to shrink(or break) the array from certain indexes. How can I recreate this in matlab. I read about reshape method in matlab but I don't understand how to apply it. dlnode method in matlab only can take one value at a time.
Point[] arr = new Point[8];
for (int x= 0; x < arr.Length; x++)
{
Array.Resize<Point>(ref arr, 1);
arr[x].X = x; (x,y values will get from text boxes)
arr[x].Y= y;
}
Any help would be highly appreciated.
Is this what you want to do?
A = [x y]
B = [A ; B]
And by opposite:
A = B(:,1)
B = B(:,2:end)
Related
So i need to know how i can go about filling an area with randomly sized rectangles and squares - like this for instance:
I already have a partially working demo however it has alot of instances in where it will not work and ontop of this it requires alot of manual checks which isn't the easiest thing to program nor is it efficient.
Ontop of the challenge at hand i'd like to also avoid using methods that require checking collision such as using an attached RigidBody2D or a Ray cast as i'm working with ui and would like to simply generate a table of locations and sizes for easier access (however if this is unavoidable i understand and please do still share your answer if this is the case)
I was hoping to simulate it in the sense of a table where you can merge cells together but i'm uncertain how this is achievable - if at all.
Thankyou in advance! :)
Edit:
In relation to UnholySheep's comment i found this. The Kd-Tree looks promising but (correct me if i'm wrong) i don't believe it can be immplemented in csharp without programming out of scope and i think it literally draws squares as opposed to implements gameobjects or Rect objects with a size and position.
Furthermore there's this thread but again it mentions using a Kd-Tree or methods which i want to avoid or as Brian said using a merge method which i don't think is achieavable in unity without programming an entire table module which is out of scope again. Additionally someone mentioned using a spiral which albeit is an interesting approach it wouldn't result in the randomness i want to achieve.
To clarify i am looking for a fairly simple algorithm - i don't believe a Kd-tree fits this but for anyone else this may be an option as there are unity modules for this.
Your question is a challange, plus writing code that perfectly produces the image takes a lot of time and patience. But here I wrote code that puts a field of all kinds of letters in a 2D array. As long as this array is empty it will allow itself to fill them with random rectangles.
public enum squareType { none, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, Y, W, X, Z }
public squareType[,] cases = new squareType[4,4];
public void Start()
{
var lengthX = cases.GetLength(0);
var lengthY = cases.GetLength(1);
var index = 0;
for (var i = 0; i < lengthX; i++)
{
for (var j = 0; j < lengthY; j++)
{
if (cases[i,j] != squareType.none) continue;
var randomX = Random.Range(i, Mathf.Min(i+3, lengthX));
var randomY = Random.Range(j, Mathf.Min(j+3, lengthY));
var color = (squareType) Enum.ToObject(typeof(squareType), ++index);
for (var x = i; x <= randomX; x++)
{
for (var y = j; y <= randomY; y++) cases[x, y] = color;
}
}
}
// Debug table
for (var i = 0; i < lengthX; i++)
{
var xField = "";
for (var j = 0; j < lengthY; j++) xField += " | " + cases[i, j];
Debug.Log(xField);
}
}
Example Result 4x4:
Example Result 6x6:
is there any better (less complex) way to paste the smaller array[,] to the bigger array[,] than looping through them? My code:
private void PasteRoomIntoTheMap(GameObject[,] room, (int, int) positionOnTheMap)
{
(int, int) roomSize = (room.GetLength(0), room.GetLength(1));
int roomsXAxesDimention = 0;
int roomsYAxesDimention = 0;
for (int i = positionOnTheMap.Item1; i <= positionOnTheMap.Item1 + roomSize.Item1; i++)
{
for (int j = positionOnTheMap.Item2; j <= positionOnTheMap.Item2 + roomSize.Item2; j++)
{
Map[i, j] = room[roomsXAxesDimention, roomsYAxesDimention];
roomsYAxesDimention++;
}
roomsXAxesDimention++;
}
}
(I didn't run it yet. There might be some errors but I hope that you will understand this method)
The code that I would love to have:
Map [5...15, 2...5] = room[0...room.GetLength(0), 0...room.GetLength(1)]
Short answer: No
Longer answer:
Multidimensional arrays are really a wrapper around a 1D array, with some special code to handle indices etc. It does however lack some useful features.
You could perhaps improve your example code a bit by copying entire columns or rows using Array.Copy or blockCopy instead of processing item by item. This might help performance if you have very many items that need copying, but is unlikely to make any difference if the sizes are small.
You could probably provide the syntax you desire by creating something like a ArraySlice2D class that reference the original 2D array as well as the region you want to copy. But you probably need to either create your own wrapper to provide index operators, or create extension methods to do it. Perhaps something like
public class My2DArray<T>{
private T[,] array;
public ArraySlice2D<T> this[Range x, Range y]{
get => new ArraySlice2D<T>(array, x, y);
set {
// Copy values from value.RangeX/Y to x/y ranges
}
}
You might also consider writing your own 2D array class that wraps a 1D array. I find that this often makes interoperability easier since most systems can handle 1D arrays, but few handle multidimensional arrays without conversion.
I am not aware of any shortcut for that and there might be to many slightly distinct usecase so that the most apropriate solution would be to implement your own functionality.
It is advisable however to add a size check to your method so you dont end up indexing nonexisting areas of the big array:
private bool ReplaceWithSubArray(int[,] array, int[,] subarray, (int x,int y) indices)
{
if (array.GetLength(0) < subarray.GetLength(0) + indices.x ||
array.GetLength(1) < subarray.GetLength(1) + indices.y)
{
// 'array' to small
return false;
}
for (int x = 0; x <= subarray.GetLength(0); x++)
{
for (int y = 0; y <= subarray.GetLength(1); y++)
{
array[x + indices.x, y + indices.y] = subarray[x, y];
}
}
return true;
}
I'm attempting to make a board that allows movement based on input similar to chess using c# and visual studio. I'm not sure if this is the best way to go about it but I'm trying to use a 4x4 2d array to map out a grid with place values that can be modified. The focus of my question is how do I print a full grid out with a loop that follows the 4x4 graph build where not only row "a" and column "1" placeholders show array values. Also would it be wise to use a 2d array to map out a board with values on every space or would it be easier to manually make a board and assign values to each array withing the manually drawn board. This is a console project, I'm only looking for the basis of the code for now, and my overall goal is something similar to the board game risk. I should add I'm a bit new to programming and any advice on what i should use and shouldn't use throughout is helpful. I've marked off original code I planned on using where x and y would use loops to make "[]" to show a graph after realizing it wouldn't mark every placeholder of the 4x4 graph.
class game
{
int[,] board;
string y;
int x;
static void Main(string[] args)
{
//for (int y = 0; y < 6; y++)
{
// Console.Write("[]");
}
//for (int x = 0; x < 6; x++)
{
// Console.WriteLine("[]");
}
int[,,] map = new int[,,]{
{
{0,0}, {1,0}, {2,0}, {3,0},
{0,1}, {1,1}, {2,1}, {3,1}
}
};
foreach (var item in map)
{
Console.Write("[" + item.ToString() + "]");
}
Console.ReadKey();
}
}
I tried to make this as effecient as possible while writing this.
So something like this:
int[,,] map = new int[,,]{
{
{0,1,2,3},
{0,1,2,3},
{0,1,2,3},
{0,1,2,3}
}
};
int width = map.GetLength(0);
int height = map.GetLength(1);
for(int i=0;i < width;i++)
{
for(int j=0;j < height;j++)
{
Console.Write("[" + map[i,j] + "]");
}
Console.Write("\n");
}
The \n signifies a new line in C#. Everytime you drop finish an array in a dimension it prints a new line.
I prefered to use for instead of foreach because it is faster for such cases. Foreach is for objects, For is for more mathematical issues.
Of couse you can change it as you see fit.
I've got an
int[,] map = int[100, 100];
and a
String mapString;
mapString simply contains a large amount of numbers (there are no other chars than numbers).
I now want to assign the first value in the array(map[0,0]) with the first char of mapString, the second value(map[0,1]) with the second char of mapString and so on. I use the following code:
int currentposition = 0;
for (int x = 0; x < 100; x++)
{
for (int y = 0; y < 100; y++)
{
map[x, y] = ArrayTest.Properties
.Settings
.Default
.mapSaveSetting
.ElementAt(currentposition);
currentposition++;
}
}
Now what happens is almost what I wished for.
The problem is that it assigns two numbers to each value instead of one. Also i can't figure out what numbers he's using as they're not the ones in my mapSaveSetting, but I can deal with that for myself.
The only problem I really don't get is that each value contains two numbers after executing this for-loop. Why does it happen? ElementAt(int) only returns one char, right?
It really looks like a logical mistake to me but I can't find it. Please don't be offensive if I just made a dumb mistake in my way of thinking.
EDIT
As it seems to be unclear what is the problem now, I'll add an example.
map[0, 0] == 42
...could be an output. Even if the String would start with e.g. 4245634 it would not make sense, as ElementAt(int) should only return the 4, not 42, right?
You are assigning char to int.Since there is implicit conversation from char to int you are getting the Unicode code of the character (in your case characters representing numbers).To fix you issue you should convert character to int.
In your case as the all characters are numeric you can do as trick like this:
map[x, y] =
ArrayTest.Properties.Settings.Default.mapSaveSetting.ElementAt(currentposition) - 48;
This work because Unicode codes of symbols [0..9] sequential and equals to [48..57].
I think that your mistake is related to the ASCII value of the characters. You should know that each character has a related ASCII value, in particular 0 has an ASCII value of 48, 1 of 49 and so on (you could check an ASCII table to check this out).
So, to get the right value of the character, you should subtract the value of the char 0 from the one in the string, like in the following piece of code.
map[x, y] = ArrayTest.Properties.Settings.Default.mapSaveSetting.ElementAt(currentposition) - '0';
You are assigning a char value to an int. A char designs a Unicode code point, and it converts implicitly to int but not in the way you expect: it gives you the code point.
Example:
Console.WriteLine((int)'A'); // Will print 65
You're actually trying to convert a single digit represented as a string to an int. Use int.Parse for this.
Console.WriteLine(int.Parse("5")); // Will print 5
Another issue: you shouldn't use ElementAt on a string, since it will needlessly iterate over the whole string until the specified index, as string doesn't implement IList<char>.
You could use the indexer like that:
int currentposition = 0;
var setting = ArrayTest.Properties.Settings.Default.mapSaveSetting;
for (int x = 0; x < 100; x++)
{
for (int y = 0; y < 100; y++)
{
map[x, y] = int.Parse(setting[currentposition].ToString());
currentposition++;
}
}
But it's actually a waste to convert each char in there to a new string, so just use some basic math instead:
int currentposition = 0;
var setting = ArrayTest.Properties.Settings.Default.mapSaveSetting;
for (int x = 0; x < 100; x++)
{
for (int y = 0; y < 100; y++)
{
map[x, y] = setting[currentposition++] - '0';
}
}
This works as the code points for the digits are consecutive.
To elaborate just a little on previous answers: In C and C++, a char is a byte (for all intents and purposes), while in C# it's a "Unicode" character. C# however has the 'byte' type matching pretty much 1:1 to the lower-level languages 'char' type.
The question suggests this could be a part of the issue.
Additionally (performance consideration): It should be noted that in C#, an array is a "heavy" type, and a multi-dimensional array is really an array-of-arrays. Depending on usage patterns, it could be more efficient to use a single-dimension array and scale one of the indices by row/col-size manually. Something like:
type this[int x, int y] { get { /* scale one of x/y and read from 1-dimensional array */ } }
I have the following code snippet:
// Initialise rectangular matrix with [][] instead of [,]
double data[][] = new double[m];
for (int i = 0; i < m; i++)
data[i] = new double[n];
// Populate data[][] here...
// Code to run in parallel:
for (int i = 0; i < m; i++)
data[i] = Process(data[i]);
If this makes sense, I have a matrix of doubles. I need to apply a transformation to each individual row of the matrix. It is "embarrassingly parallel", as there is no connection for the data from one row to another.
If I do something like:
data.AsParallel().ForAll(row => { row = Process[row]; });
First of all, I don't know whether data.AsParallel() knows to only look at the first subscript, or if it will enumerate all m * n doubles. Secondly, since row is the element I'm enumerating over, I have no idea if I can change it like this - I suspect not.
So, with or without PLINQ, what is a good way to parallelise this loop in C#?
Here are two ways to do it:
data.AsParallel().ForAll(row =>
{
Process(row);
});
Parallel.For(0, data.Length, rowIndex =>
{
Process(data[rowIndex]);
});
In both cases, the one-dimensional array of doubles is passed by reference and modifying values in your Process method will modify the data array.