Access 2d array with point in wpf C# - c#

I have a 2d array of a class. The size of array is very large (around 3000*3000) and accessing the array with ordinary row and column method is taking very much time. For this purpose, I want to use pointers to access the array.
Following is my array code:
Class definition:
Class BoxData
{
Size _bound;
bool _isFilled=false;
Color _color=Colors.White;
public Size Bounds
{
get
{
return _bound;
}
set
{
_bound=value;
}
}
public bool IsFilled
{
get
{
return _isFilled;
}
set
{
_isFilled=value;
}
}
public Color FillColor
{
get
{
return _color;
}
set
{
_color=value;
}
}
}
Class used as array in application:
BoxData[,] boxData=new BoxData[3000,3000];
I want to access boxData with pointers.
Thanks

Try a jagged array instead of a multi dimensional one, they are faster in Microsoft's CLR implementation
BoxData[][] boxData=new BoxData[3000][];
for (int i=0; i<3000; i++)
boxData[i] = new BoxData[3000];

Maybe you could use a struct instead of a class for BoxData ?
Struct is a value type: as you declare your array, everything will be populated already.
You will not longer use a loop to create new BoxData() instances.
var x = new BoxData[3000,3000]; // Populated array of BoxData
Because of struct vs class restrictions, you will have to remove initializers this way...
struct BoxData
{
Size _bound;
bool _isFilled; // = false;
Color _color; // = Color.White;
public Size Bounds
{
get
{
return _bound;
}
set
{
_bound = value;
}
}
public bool IsFilled
{
get
{
return _isFilled;
}
set
{
_isFilled = value;
}
}
public Color FillColor
{
get
{
return _color;
}
set
{
_color = value;
}
}
}
...and initialize your default values using a loop will be much more faster.
for (int j = 0; j < 3000; j++)
for (int i = 0; i < 3000; i++)
x[i, j].FillColor = Color.White;

Related

Three dimensional circular buffer

I'm looking for an implementation of a three dimensional circular buffer in C# .NET that allows me to extract slices of the buffer.
I tried the multidimensional array but it doesn't allow me to get a specific slice of the buffer.
I also tried to implement a version using jagged array, but i have find some problems in understanding how to initialzie the matrix, and also in slice extraction.
Thanks for the help.
[EDIT 1]
The buffer will be used to store data from reltime sensors, it will be fixed in width height and the depth (time which be the circular part) will be defined by the user.
The slices i need will be a fixed size matrix (width and heigh with the data of a given time).
[EDIT 2]
The only implementation that i could implement that works. With the jagged array i'm still stuck at the declaration (i find it chaotic)
public class CircularBufferMatrix<T>
{
private readonly T[,,] _buffer;
public CircularBufferMatrix(int width, int height, int depth)
{
Width = width;
Height = height;
Depth = depth;
_buffer = new T[width, height, depth];
}
public T this[int x, int y, int z]
{
set { _buffer[x, y, z%Depth] = value; }
get { return _buffer[x, y, z%Depth]; }
}
#region Getters
public int Width { get; }
public int Height { get; }
public int Depth { get; }
#endregion
}
I would split these in two classes. You want something like a CircularBuffer class, which handles the reading and writing. The other could be an implementation of the 2D array you want to store. The reason of splitting these, is because you want to Read/write frames separately.
For example:
Circular buffer implementation:
public class CircularBuffer<T>
{
private T[] _buffer;
private int IncRollover(int value)
{
value++;
if (value >= _buffer.Length)
value = 0;
return value;
}
public CircularBuffer(int count)
{
_buffer = new T[count];
}
public bool Write(T element)
{
// if the writeindex (after increasing) equals the readindex, the buffer is full
var newWriteIndex = IncRollover(WriteIndex);
if (newWriteIndex == ReadIndex)
return false;
_buffer[WriteIndex] = element;
WriteIndex = newWriteIndex;
return true;
}
public bool TryRead(out T element)
{
if (ReadIndex == WriteIndex)
{
element = default(T);
return false;
}
element = _buffer[ReadIndex];
ReadIndex = IncRollover(ReadIndex);
return true;
}
public IEnumerable<T> ReadAll()
{
T element;
while (TryRead(out element))
yield return element;
}
public int ReadIndex { get; private set; }
public int WriteIndex { get; private set; }
}
This will take care of reading and writing induvidual 'frames'/slices. You can expand this class if you like to read on Index.
note: The write will return false if the buffer is full
This could be an implementation of the 2d buffers stored within the Circular buffer:
public class MyWhateverBuffer<T>
{
private CircularBuffer<T[,]> _buffer;
public int Width { get; private set; }
public int Height { get; private set; }
public int Depth { get; private set; }
public MyWhateverBuffer(int width, int height, int depth)
{
Width = width;
Height = height;
Depth = depth;
_buffer = new CircularBuffer<T[,]>(depth);
}
public T[,] New()
{
return new T[Width, Height];
}
public bool Add(T[,] buffer)
{
return _buffer.Write(buffer);
}
public bool TryRead(out T[,] buffer)
{
return _buffer.TryRead(out buffer);
}
public IEnumerable<T[,]> ReadAll()
{
return _buffer.ReadAll();
}
}
This class can be used like:
MyWhateverBuffer<double> myBuffer = new MyWhateverBuffer<double>(100, 100, 100);
var oneSlice = myBuffer.New();
oneSlice[10, 10] = 3.5;
oneSlice[50, 10] = 23.5;
oneSlice[10, 20] = 43.5;
myBuffer.Add(oneSlice);
var anotherSlice = myBuffer.New();
anotherSlice[10, 10] = 13.5;
anotherSlice[50, 10] = 23.5;
anotherSlice[10, 20] = 43.5;
var result = myBuffer.Add(anotherSlice);
if(!result)
{
// the buffer was full..
}
// Read the results from the buffer.
foreach(var slice in myBuffer.ReadAll())
{
Trace.WriteLine(slice[10, 10]);
}
You should always check if the buffer could be added. You don't want to lose info.
Side note:
The most profit gains with a Circular buffer is declaring the elements ones. Like big arrays will be reused every time.
If I understand your requirements correctly, you want a circular buffer consisting of items that are two dimensional arrays of data and the data from one item is never repeated in other items. C# doesn't have a cicular buffer type but you can always create one yourself:-
public class CircularBuffer <T> // make it generic
{
public class Iterator
{
public void MoveForward ();
public void MoveBackward ();
public T Item { get { } };
CicrcularBuffer <T> m_container;
LinkedListNode <T> m_current_item;
}
public void Add (T item);
public Iterator GetIterator ();
LinkedList<T> m_data;
}
Then create a class to contain your data:-
public class SensorData
{
// contains the two dimension data
}
And use it like:-
var buffer = new CircularBuffer <SensorData> ();
var iterator = buffer.GetIterator ();
var item = iterator.Item;
iterator.MoveForward ();
Obviously, there's a lot to be filled in but it should get you started.

Unity3d: Write a generic color changing class

I wrote this little Unity3D class to fade an array of UI.Image in or out by reducing or increasing the alpha value of their color property.
Then I wanted to use it for an array of materials on meshrenderers but realized that materials and UI.Image, though they both have a color property which can be changed, are totally different classes and you access their color properties differently so I cannot use this class for them both.
I tried making a list of just the colors to be changed, but in unity a Color is a struct and cannot be passed by reference.
Do you have any idea how to make this class generic so it can change the color property on several different classes? I sort of wrote myself into a corner here, I'd rather not just copy the class and change it for meshrenderer.material, that would be ugly
public class FadeThingInOut : MonoBehaviour
{
//public Setting fields
public Image[] ThingsToFade;
public bool Visible = true;
public float FadeTime = 1f;
//private fields
Color[] InColour;
Color[] OutColor;
void Start()
{
if (Visible)
{
SetColours(ref InColour, ref OutColor,0f);
}
else
{
SetColours(ref OutColor,ref InColour,1f);
}
}
void SetColours(ref Color[] one,ref Color[] two,float other)
{
one = new Color[ThingsToFade.Length];
two = new Color[ThingsToFade.Length];
for (int i = 0; i < ThingsToFade.Length; i++)
{
one[i] = ThingsToFade[i].color;
two[i] = Tools.colorfromalpha(one[i], other);
}
}
public void Fade(bool inout)
{
if (inout && !Visible)
{
StartCoroutine(FadeLerp(OutColor,InColour,inout));
}
else if (!inout && Visible)
{
StartCoroutine(FadeLerp(InColour, OutColor, inout));
}
}
IEnumerator FadeLerp(Color[] from, Color[] to,bool endstate)
{
float nowtime = 0f;
while (nowtime < FadeTime)
{
nowtime += Time.deltaTime;
float ratio = nowtime / FadeTime;
for (int i = 0; i < ThingsToFade.Length; i++)
{
ThingsToFade[i].color = Color.Lerp(from[i], to[i], ratio);
yield return null;
}
}
for (int i = 0; i < ThingsToFade.Length; i++)
{
ThingsToFade[i].color = to[i];
}
Visible = endstate;
}
}
UPDATE
Heres what I ended up doing.
I keep an array of the components and then cast them to one of three types that I am dealing with. There is a series of if statements to deal with the different classes differntly.
I'm still interested in a more elegant solution that may use some aspects of .net or C# that I'm not familiar with though
public class FadeThingInOut : MonoBehaviour
{
//public Setting fields
public Component[] ThingsToFade;
public bool Visible = true;
public float FadeTime = 1f;
public float Max = 1f;
//private fields
Color[] InColour;
Color[] OutColor;
void Start()
{
if (Visible)
{
SetColours(ref InColour, ref OutColor,0f);
}
else
{
SetColours(ref OutColor, ref InColour, Max);
}
}
void SetColours(ref Color[] one,ref Color[] two,float other)
{
one = new Color[ThingsToFade.Length];
two = new Color[ThingsToFade.Length];
for (int i = 0; i < ThingsToFade.Length; i++)
{
one[i] = GetColour(i);
two[i] = Tools.colorfromalpha(one[i], other);
}
}
public void Fade(bool inout)
{
if (inout && !Visible)
{
StartCoroutine(FadeLerp(OutColor,InColour,inout));
}
else if (!inout && Visible)
{
StartCoroutine(FadeLerp(InColour, OutColor, inout));
}
}
Color GetColour(int index)
{
if(ThingsToFade[index].GetType() == typeof(MeshRenderer))
{
return (ThingsToFade[index] as MeshRenderer ).material.color;
}
else if (ThingsToFade[index].GetType() == typeof(Image))
{
return (ThingsToFade[index] as Image).color;
}
else if (ThingsToFade[index].GetType() == typeof(RawImage))
{
return (ThingsToFade[index] as RawImage).material.color;
}
return Color.black;
}
void SetColour(int index,Color col)
{
if (ThingsToFade[index].GetType() == typeof(MeshRenderer))
{
(ThingsToFade[index] as MeshRenderer).material.color = col;
return;
}
else if (ThingsToFade[index].GetType() == typeof(Image))
{
(ThingsToFade[index] as Image).color = col;
return;
}
else if (ThingsToFade[index].GetType() == typeof(RawImage))
{
(ThingsToFade[index] as RawImage).material.color = col;
return;
}
}
IEnumerator FadeLerp(Color[] from, Color[] to,bool endstate)
{
float nowtime = 0f;
while (nowtime < FadeTime)
{
nowtime += Time.deltaTime;
float ratio = nowtime / FadeTime;
for (int i = 0; i < ThingsToFade.Length; i++)
{
SetColour(i, Color.Lerp(from[i], to[i], ratio));
yield return null;
}
}
for (int i = 0; i < ThingsToFade.Length; i++)
{
SetColour(i, to[i]);
}
Visible = endstate;
}
}
This isn't super ideal but you can do it this way.
public interface ISetColor
{
public Color color { get; set; }
}
public class ImageSetColor : MonoBehaviour, ISetColor
{
public Image m_Image
public Color color { get {return m_Image.color;} set { m_Image.color = value}
}
public class MaterialSetColor : MonoBehaviour, ISetColor
{
public Material m_Material
public Color color { get {return m_Material.color;} set { m_Material.color = value}
}
Then instead of an Image array you can do an array of public MonoBehaviour[] ThingsToFade then anytime you use ThingsToFade you need to cast it to an ISetColor.
Then any component you want to be able to set colors with will need to create a class that inherits from MonoBehaviour and implements the ISetColor interface
This isn't the easiest solution to use in Unity but it should work
You should not write a class. You should write an extension method. Because structs are immutable though, you cannot change their value, so you should write a static function that has as an argument a reference to color, by using the "ref" keyword. Using structs as mutable objects is not recommended most of the time, but it's the best option here.
I wrote this little Unity3D class to fade an array of UI.Image in or
out by reducing or increasing the alpha value of their color property.
I dont see why to overcomplicate everything.
Edit: This will fade by adjusting the alpha directly, using floats instead of color swapping. Faster, cheaper, shorter.
IEnumerator FadeLerp(float _from, float _to, bool endstate)
{
float nowtime = 0f;
while (nowtime < FadeTime)
{
nowtime += Time.deltaTime;
float ratio = nowtime / FadeTime;
for (int i = 0; i < ThingsToFade.Length; i++)
{
Color _color = ThingsToFade[i].color;
_color.a = Mathf.Lerp(_from, _to, ratio);
ThingsToFade[i].color = _color;
yield return null;
}
}
for (int i = 0; i < ThingsToFade.Length; i++)
{
ThingsToFade[i].renderer.enabled = endstate;
}
}
use color.lerp function.
it will fade the color nicely, and if you know how to use the lerp, with a counter and with an array, there should not be a problem :)
if tomorrow you are still stucked i'll write the lerping function for you, but keep trying :)
It will be a sweet experience if you do it on your own :D

Associated Properties: How to Avoid an Infinite Loop

I have a Cube class. The cube can be constrained so that the width=height=length. I've coded this functionality but as you can see, my code results in a circular/infinite loop - the width sets the height which sets the width which sets the height and so on.
How can I make my Cube class constrained and avoid this infinite loop? Is my only solution to use a boolean variable propagate (see below)?
public class Cube {
public bool isConstrained {get; set;} // if constrained then width=height=length
// Causes a circular problem. How can I avoid this? Maybe create a variable private bool propagate = false; ??
public double width
{
get { return width; }
set
{
width = value;
if (isConstrained)
{
height = value;
length = value;
}
}
}
public double height
{
get { return height; }
set
{
height = value;
if (isConstrained)
{
width = value;
length = value;
}
}
}
public double length
{
get { return length; }
set
{
length = value;
if (isConstrained)
{
height = value;
width = value;
}
}
}
}
My only solution is this:
private bool propagate = true;
public double length
{
get { return length; }
set
{
length = value;
if (isConstrained && propagate)
{
propagate = false;
height = value;
width = value;
propagate = true;
}
}
}
Currently even just your getters will give a stack overflow - you don't have any fields backing your data, because you're not using automatically-implemented properties. Additionally, your properties don't have conventional names, which is definitely worth fixing.
You should just use private fields to back the properties, and set those accordingly within your property setters. That way no property will call another, and all will be well... except for the design being a bit troublesome to start with. (When changing one property changes another, that can be surprising.)
So something like:
private int width;
private int height;
private int length;
private bool constrained;
...
public int Width
{
get { return width; }
set
{
width = value;
if (constrained)
{
height = value;
length = value;
}
}
}
Shouldn't a cube always have the length, width, and height be the same? You could use a single private variable to hold the length, width, and height, and then when setting any of those Properties, assign that value to the private variable. Return the value of that same variable in the get Properties for width/height/length.

Converting C++ pointer struct to C#

I have 2 structs in C language:
struct CSquare
{
char Side;
int Row;
int Col;
};
struct CSide
{
char m_Side;
char m_Blocks[3][3];
CSquare *m_Moves;
};
and C++ code:
int Count = 0;
int Flag = 0;
if (m_Down->m_Blocks[0][1] == *m_Down)
{
Count++;
Flag |= 2;
// type of m_Down is CSide
}
I'm trying to convert they to C#:
public class Square
{
public char Side { get; set; }
public int Row { get; set; }
public int Col { get; set; }
}
public class CubeSide
{
private char Side { get; set; }
private char[,] _block = new char[3, 3];
private Square[] moves;
public char[,] Block
{
get { return _block; }
set { _block = value; }
}
internal Square[] Moves
{
get { return moves; }
set { moves = value; }
}
}
But I don't know how to convert line:
if (m_Down->m_Blocks[0][1] == *m_Down)
to C#?
How can I convert this line to C#?
this line make no sense, i guess it's always evaluate to false.
What you can do is to set a breakpoint on that line and perform a quick watch, evaluate *m_Down to make sure there's no overload operator.
Then, evaluate the condition. Depending on your type of project, put some printf("inside the if")/printf("inside the else"), messagebox or write it in a file. If the condition is evaluate to true, print the value of m_Down->m_BLocks[0][1] and *m_Down...
Make sure you first understand the logic behind this line. Once you understand it, it will be easy to write it in c#
PS: in C#, use Byte instead of Char

Is this efficient use of the is and as operator in a DrawableGameComponent?

I'm learning to use the as operator, and my goal was to create an option window (non windows form) that can:
Have options added to it (for flexibility, in case I want to use if statements to add menu items)
Be able to display text, textures, or a class (using the classes draw function)
Be controlled through the host GameState
I still haven't added the options for indicating an item is selected, my apologies for not posting a complete work. I also have not sorted the code into regions yet. Sorry again!
Is my code (particularly the draw function) properly using the is and as operators properly, from a performance and readability (non spaghetti code) standpoint?
public class OptionWindow : DrawableGameComponent
{
public Dictionary<int, Option> options;
int selectedOption;
bool windowLoops;
Rectangle drawRectangle;
int spacer;
int totalItemHeight;
SpriteFont sf;
SpriteBatch sb;
public Rectangle DrawRectangle
{
get { return drawRectangle; }
set { drawRectangle = value; }
}
public int SelectedOption
{
get { return selectedOption; }
set
{
if (windowLoops)
{
if (selectedOption >= options.Count())
selectedOption = 0;
if (selectedOption < 0)
selectedOption = options.Count() - 1;
}
else
{
if (selectedOption >= options.Count())
selectedOption = options.Count() - 1;
if (selectedOption < 0)
selectedOption = 0;
}
}
}
public OptionWindow(Game game, bool windowLoops, SpriteFont sf, Rectangle drawRectangle)
: base(game)
{
options = new Dictionary<int, Option>();
this.windowLoops = windowLoops;
this.sf = sf;
DrawRectangle = new Rectangle(drawRectangle.X, drawRectangle.Y, drawRectangle.Width, drawRectangle.Height);
}
public void Add(object option, bool selectable, bool defaultSelection, int height)
{
options.Add(options.Count(), new Option(selectable, option, height));
if (defaultSelection)
SelectedOption = options.Count() - 1;
UpdatePositions();
}
public void UpdatePositions()
{
UpdateTotalItemHeight();
if (options.Count() - 1 != 0)
spacer = (drawRectangle.Height - totalItemHeight) / (options.Count() - 1);
for (int i = 0; i < options.Count(); i++)
{
if (i == 0)
options[i].Position = new Vector2(drawRectangle.X, drawRectangle.Y);
else
{
options[i].Position = new Vector2(
drawRectangle.X,
options[i - 1].Position.Y + options[i - 1].Height + spacer);
}
}
}
public void UpdateTotalItemHeight()
{
totalItemHeight = 0;
for (int i = 0; i < options.Count(); i++)
{
totalItemHeight += options[i].Height;
}
}
protected override void LoadContent()
{
sb = new SpriteBatch(GraphicsDevice);
base.LoadContent();
}
public override void Draw(GameTime gameTime)
{
for (int i = 0; i < options.Count(); i++)
{
if (options[i].OptionObject is string)
sb.DrawString(sf, options[i].OptionObject as string, options[i].Position, Color.White);
if (options[i].OptionObject is Texture2D)
sb.Draw(options[i].OptionObject as Texture2D,
new Rectangle(
(int)options[i].Position.X,
(int)options[i].Position.Y,
options[i].Height,
(options[i].Height / (options[i].OptionObject as Texture2D).Height) * (options[i].OptionObject as Texture2D).Width),
Color.White);
if (options[i].OptionObject is DisplayObject)
(options[i].OptionObject as DisplayObject).Draw(gameTime);
}
base.Draw(gameTime);
}
}
public class Option
{
bool selectable;
object optionObject;
int height;
Vector2 position;
public bool Selectable
{
get { return selectable; }
set { selectable = value; }
}
public object OptionObject
{
get { return optionObject; }
set { optionObject = value; }
}
public int Height
{
get { return height; }
set { height = value; }
}
public Vector2 Position
{
get { return position; }
set { position = value; }
}
public Option(bool selectable, object option, int height)
{
Selectable = selectable;
OptionObject = option;
Height = height;
}
}
It is never adviseable to use is and then as. The usual way to go would be to either of the following:
just use is (if you just want to know the type without subsequent casting)
assign the result of as to a variable and check whether that variable is (not) null
The code analysis tool FxCop helps you find any spots in your code that use is and then as and warns you because of performance concerns.
Note however that a better approach altogether might be to declare your OptionObject property as some abstract class with a Draw method. You could then derive a subclass for strings, one for Texture2D instances and another one for DisplayObject instances and just call Draw in your OptionWindow.Draw method. This would leave the decision which actual drawing operations to execute up to built-in polymorphism features of the framework.

Categories

Resources