How to make a Struct that can be multipled using * - c#

XNA framework for .net has a really useful Object called vector2 that represents a 2d vector..You can multiply them by ints, floats and other Vector 2s
Eg.
Vector2 bloo = new Vector2(5, 5);
bloo *= 5;
bloo *= someotherVector2;
The only thing is that the X,Y information is stored as floats and in a lot of cases I want to simply store 2d info, or 2d coordinates as ints.
I'd like to make my own struct for this..
Heres what i have..
internal struct Coord
{
public int X { get; private set; }
public int Y { get; private set; }
public Coord(int x,int y)
{
X = x;
Y = y;
}
}
My question is how do I make it so my Coord struct can be multipled by ints or other Coords using * (Not a "Multiply" function call)

You can use operator overloading:
public static Coord operator*(Coord left, int right)
{
return new Coord(left.X * right, left.Y * right);
}
Just put the method into the Coord struct. You can do this with many operators like +,-,/ etc... and also with different parameters.

You need to overload the multiplication operator for you type.
// overload operator *
public static Coord operator *(Coord x, Coord y)
{
// Return a `Coord` that results from multiplying x with y
}

overload multiplication operator:
public static Coord operator* (Coord multiplyThis, Coord withThis) {
Coord result = multiply(multiplyThis, withThis); //...multiply the 2 Coords
return result;
}
public static Coord operator* (Coord multiplyThis, float withThis) {
Coord result = multiply(multiplyThis, withThis); //...multiply the Coord with the float
return result;
}

Related

Unsafe structs in C#

I wanted to try c#'s unsafe 'feature' by creating simple structs (Vector, Particle).
SITUATION
I have this 2 structs and want to inject position and velocity vectors into my Particle struct.
As a test I wanted to print out position's X value, but somehow I'm getting random values.
I have the following code here
Vector
public readonly struct Vector
{
public int X { get; }
public int Y { get; }
public Vector(int x, int y)
{
X = x;
Y = y;
}
}
Particle
public unsafe struct Particle
{
private Vector* mPosition;
private Vector* mVelocity;
public Particle(Vector position, Vector velocity = default)
{
mPosition = &position; // here is x 10
mVelocity = &velocity;
}
public int GetPosX()
{
return mPosition->X; // but here not
}
}
Program
public class Program
{
private static void Main(string[] args)
{
var pos = new Vector(10, 5);
var obj = new Particle(pos);
Console.WriteLine(obj.GetPosX()); // prints random value
}
}
PROBLEM
It prints a random value instead of 10.
class Program {
static void Main (string [ ] args) {
unsafe {
Vector pos = new Vector(10, 5);
Particle obj = new Particle(&pos);
// &pos is at position 0xabcdef00 here.
// obj.mPosition has a different value here. It points to a different address? Or am I misunderstanding something
Console.WriteLine(obj.GetPosX( ));
}
}
}
public struct Vector {
public int X;
public int Y;
public Vector (int x, int y) {
X = x;
Y = y;
}
}
public unsafe struct Particle {
private Vector* mPosition;
public Particle (Vector *position) {
mPosition = position; // here is x 10
}
public int GetPosX ( ) {
return mPosition->X; // still 10 here
}
}
This works for me.
Please ... do not ask me why it does. You will notice that I didn't change that much. Just calling Particle with *pos instead of pos. For some reason that fixes the problem. You have to wrap the code with unsafe then and change the constructor for Particle obviously.
I could speculate about why it works, but I'd rather not. Maybe the pointer changes when you pass pos as a parameter for some reason?
You could not take the ref with right value.
Create a variable like int posX = 10;
And you can take the reference with variable. You take the compile time reference and read the runtime reference.
Don't use pointers without fixed. C# stack performance ise very good. You dont need this.
Usually pointers use with linking (C/Cpp dynamic library linking etc). If you have large structs (30 bytes and greater) then you can use the ref parameter tag.

Overloading methods for different geomethrical figures areas

I need to overload a method for it to be able to calculate the area of a circle, square, rectangle, triangle and a trapezoid. I think I've got them all figured out but the circle seems to be a problem.
static void Pole(int x, double y = 3.14)
{
Console.WriteLine(x * x * y);
}
static int Pole(int x)
{
return x * x;
}
static int Pole(int x, int y)
{
return x * y;
}
static int Pole(int x, int y, int z = 2)
{
return x * y / z;
}
static int Pole(int x, int y, int v, int z = 2)
{
return (x + y) / z * v;
}
static void Main(string[] args)
{
int x = 2;
int y = 3.14;
Console.WriteLine(Pole(x, y));
Console.ReadKey();
I don't know what problem you're getting, but I can probably guess it's one of the following:
1) You're getting an error because one of your overload methods is returning void while the others are returning int (they all have to be the same)
or
2) What your Main method is calling is this method static int Pole(int x, int y) and not static void Pole(int x, double y = 3.14), which I'm assuming is the "Circle"; because you're passing in two ints instead of one int and one double.
Have you tried changing int to double for y in your Main method?
static void Main(string[] args)
{
int x = 2;
double y = 3.14;
Console.WriteLine(Pole(x, y));
Console.ReadKey();
}
also why dont you just pass in one parameter and have it multiply by 3.14 for the Pole overload method that's tasked with calculating the circle?
/// <summary>
/// Method to calculate a circle
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
static double Pole(int x)
{
return 3.14(x * x);
}
static void Main(string[] args)
{
int x = 2;
Console.WriteLine(Pole(x));
Console.ReadKey();
}
Another tip: add some notes in your code. You have 5 methods named Pole, one accepting one more int parameter than the last one and each of the 5 methods are calculating for a different shape.
Adding a summary to each method or just a simple comment will help you and anyone else trying to read your code, moving forward.
Important: Because these are overloads, you're going to need to change all your methods to return double instead of int just for the sake of the "Circle" Pole method. Having it as the only void method was probably causing the error for you to begin with.
This should be enough to get you started:
//Circle
static double Pole(int x, double y)
{
if(y != 3.14)
y = 3.14;
return y(x * x);
}
//Square
static double Pole(int x)
{
return x * x;
}
//Rectangle
static double Pole(int x, int y)
{
return x * y;
}
//Triangle
static double Pole(int x, int y, int z)
{
if(z != 2)
z = 2;
return x * y / z;
}
//Trapezoid
static double Pole(int x, int y, int v, int z)
{
if(z != 2)
z = 2;
return (x + y) / z * v;
}
static void Main(string[] args)
{
int x = 2;
double y = 3.14;
Console.WriteLine(Pole(x, y));
Console.ReadKey();
}

Multiply operator overloading on vector class in c#

I guess, it's a pretty basic problem, but I couldn't find an answer.
Program is made for learning purpose, I'd defined a vector class with multiplication operator like this:
public class vector
{
private int x;
private int y;
public vector(int x,int y)
{
this.x = x;
this.y = y;
}
public static vector operator *(vector w1, vector w2)
{
return int w1.x*w2.x + w1.y * w2.y;
}
}
The problem is that visual studio underlines the expression in return, how should I modify the definition of "*" operator to make it work ?
You defined your function to return a vector, however you are only returning an int.
public static vector operator *(vector w1, vector w2)
{
return int w1.x*w2.x + w1.y * w2.y;
}
should be
public static int operator *(vector w1, vector w2)
{
return int (w1.x*w2.x + w1.y * w2.y);
}
Or for example, if you wanted to return a vector for the addition operator, that would look like:
public static vector operator +(vector w1, vector w2)
{
return new vector (w1.x+w2.x, w1.y + w2.y);
}
You need to return a new instance of vector, try this:
public class vector
{
private int x;
private int y;
public vector(int x, int y)
{
this.x = x;
this.y = y;
}
public static vector operator *(vector w1, vector w2)
{
return new vector(w1.x* w2.x, w1.y * w2.y);
}
}

C# - Storing a struct inside a struct of same type

Ok,
It is not possible to store a struct instance inside a struct of the same type. So can anyone help me find a workaround please?
I need to store a vector3 inside a vector3 like this:
public struct Vector3{
float x,y,z;
Vector3 normalized;
}
Obviously, it creates an endless cycle as one would create a new one that creates a new one and so on...
So how would one do that? I would need my normalized to be a Vector3 since it needs to be recognized as such and cannot be any other naming.
Finally, I know this can be achieved with classes but I would not want.
Thanks
Well, a struct is a value type. Declaring a recursive struct would create an infinitely big struct! A workaround would be to declare it as class instead. But here I would simply declare Normalized as a property.
public struct Vector3 {
public Vector3(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}
public float X { get; private set; }
public float Y { get; private set; }
public float Z { get; private set; }
public float Length {
get { return (float)Math.Sqrt(X * X + Y * Y + Z * Z); }
}
Vector3 Normalized {
get {
float l = Length;
return new Vector3(X / l, Y / l, Z / l);
}
}
}
You cannot store a struct of type X inside a struct of type X. However, you probably don't want to do this anyway, because in general, structs (and classes, for that matter) should only store the data they need to be complete. Instead, you can have a function that builds and returns the 'normalized' version of the struct:
public struct Vector3
{
float x,y,z;
public Vector3 Normalized
{
get
{
... build the normalized struct and return it ...
}
}
}

Shortest path from random points on a coordinate plane

Considering the next things done
Class Point()
{
prop int X
prop int Y
//ByDefault it generates a Random value
Point()
{
GenerateRandom();
}
public void GenerateRandom()
{
//Code for generateRandom
}
}
Class Operations
{
public float Distance(Point A, Point B)
{
//Code for calculating distance
}
///Determinates the distance from i=0 to i=n of the array with a for sentence
public float AcumulatedDistance(Point[] PointsOrdered)
{
float ret=0;
for(i=0;i<n-1;i++)
ret += Distance(PointsOrdered[i], PointsOrdered[i+1]);
return ret;
}
}
What do you have to do to make (in Operations):
public Point[] ShortestPath(int initialIndex, Point[] myPoints)
Where myPoints has a set of points and I consider myPoints[initialindex] my StartPosition. And the array returned is the Points ordered to get the shortest path.
I can't seem to get how to apply Floyd–Warshall niether Dijkstra of if those apply.

Categories

Resources