Multiply operator overloading on vector class in c# - 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);
}
}

Related

In Unity can I make the instantiate function accept custom coordinates instead of Vector3 or Transform?

I want to instantiate GameObjects(specifically hexagonal tiles) at the hexagonalCoodinates(hexcoordinates).
For this I wrote a custom coordinate system.
But I found out that unity doesn't accept anything other than Vector3 or transform.
How do I make it do that?
Or is there a easier way to do this?
This is the method to generate the gameObjects
private void TouchCell(Vector3 point)//This method instantiates cubes
{
point = transform.InverseTransformPoint(point);
HexCoordinates coordinates = HexCoordinates.FromPosition(point);
Instantiate(cubes, coordinates, Quaternion.identity);//<-The coordinate variable here is a hex coordinate.
Debug.Log("Touched at:" + coordinates);
}
And This is the Hex coordinate generator:
public struct HexCoordinates
{
public int X { get; private set; }
public int Z { get; private set; }
public int Y { get
{
return -X - Z;
} }
public HexCoordinates(int x,int z)
{
X = x;
Z = z;
}
public static HexCoordinates FromOffsetCoordinates(int x,int z)
{
return new HexCoordinates(x-z/2, z);
}
public override string ToString()
{
return "("+X.ToString()+","+Y.ToString()+","+Z.ToString()+")";
}
public string ToStringOnSeperateLines()
{
return X.ToString() + "\n" +Y.ToString()+ "\n" + Z.ToString();
}
public static HexCoordinates FromPosition(Vector3 point)//This converts the Vector3 to Hex coords
{
float x = point.x / (HexMetrics.InnerRadius * 2f);
float y = -x;
float offset = point.z / (HexMetrics.OuterRadius * 3f);
x -= offset;
y -= offset;
int iX = Mathf.RoundToInt(x);
int iY = Mathf.RoundToInt(y);
int iZ = Mathf.RoundToInt(-x - y);
if (iX + iY + iZ != 0)
{
float dX = Mathf.Abs(x-iX);
float dY = Mathf.Abs(y - iY);
float dZ = Mathf.Abs(-x-y-iZ);
if(dX>dY&&dX>dZ)
{
iX = -iY - iZ;
}
else if(dZ>dY)
{
iZ = -iX - iY;
}
}
return new HexCoordinates(iX,iZ);
}
}
Just convert from your HexCoordinates to Vector3 using any way:
create method for HexCoordinates, something like public Vector3 ToVector3() {...}
create implicit operator for implicit cast to Vector3
public struct HexCoordinates
{
public int X { get; private set; }
public int Z { get; private set; }
public int Y => -X - Z;
public HexCoordinates(int x,int z)
{
X = x;
Z = z;
}
...
public static implicit operator Vector3(HexCoordinates coords)
{
Vector3 result = // convert to Vector3
// Vector3 result = ToVector3() -- or like this for code reuse
return result;
}
public Vector3 ToVector3()
{
Vector3 result = //convert to Vector3
return result;
}
}
And then you can extend Unity's Object class and add overloading for Instantiate() method that will accept HexCoordinates, convert to Vector3 and call Instantiate()
public static class ObjectExtension
{
public static void Instantiate(this Object obj, Object origin, HexCoordinates coords, Quaternion q)
{
Vector3 position = coords.ToVector3();
obj.Instantiate(origin, position, q);
}
}
Also if you create implicit cast for your HexCoordinates to Vector3 you don't need to create overloading for Instantiate() method because converting will be implicitly
You are using using catlike coding's code. (This would have been helpful to mention in the question ;) ). In part 3 of the tutorial featuring this hex coordinate system, you can see how they would do something like below, accessing a hex inside of an array by calculating an index:
public HexCell GetCell (Vector3 position) {
position = transform.InverseTransformPoint(position);
HexCoordinates coordinates = HexCoordinates.FromPosition(position);
int index = coordinates.X + coordinates.Z * width + coordinates.Z / 2;
return cells[index];
}
So, since a HexCell has a transform.position, you can use that to get its center (making sure you don't access out of bounds):
private void TouchCell(Vector3 point)
{
point = transform.InverseTransformPoint(point);
HexCoordinates coordinates = HexCoordinates.FromPosition(point);
int index = coordinates.X + coordinates.Z * width + coordinates.Z / 2;
if (index >=0 && index < cells.Length)
{
Vector3 worldPos = cells[index].transform.position;
Instantiate(cubes, worldPos, Quaternion.identity);
Debug.Log("Touched at:" + coordinates);
}
}
Better yet, it may be worthwhile to make a method to retrieve this index, for the sake of code reuse:
private bool IsValidCellIndex(Vector3 point, out int index)
{
point = transform.InverseTransformPoint(point);
HexCoordinates coordinates = HexCoordinates.FromPosition(point);
index = coordinates.X + coordinates.Z * width + coordinates.Z / 2;
return index >=0 && index < cells.Length;
}
private void TouchCell(Vector3 point)
{
if (IsValidCellIndex(point, out int index))
{
Vector3 worldPos = cells[index].transform.position;
Instantiate(cubes, worldPos, Quaternion.identity);
Debug.Log("Touched at:" + worldPos);
}
}
Or, just use GetCell as the tutorial does :)

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();
}

How to copy fields from one structure to another

I have several input structures which I need to convert to some other structure so I can pass it to my method.
struct Source1
{
public float x1;
public float x2;
public float x3;
}
struct Source2
{
public float x1;
public float x3;
public float x2;
public float x4;
}
struct Target
{
public float x1;
public float x2;
public float x3;
}
I am sure that source structure has required field (type and name is what matters) but that field's offset is unknown. Also source structure might contain some extra fields that I don't need.
How do I copy required fields from source structure to target structure. I need to do it as fast as possible.
In C there is a very simple recipe for that kind of problems.
#define COPY(x, y) \
{\
x.x1 = y.x1;\
x.x2 = y.x2;\
x.x3 = y.x3;\
}
I was thinking about getting a collection of fields and then get field's value using its name as a key but it looks like slow solution to me.
Have a squiz at https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/how-to-implement-user-defined-conversions-between-structs .
It details the use of implicit operators which are one approach to consider.
Some example code:
using System;
namespace Test
{
struct Source1
{
public float x1;
public float x2;
public float x3;
public static implicit operator Target(Source1 value)
{
return new Target() { x1 = value.x1, x2 = value.x2, x3 = value.x3 };
}
}
struct Target
{
public float x1;
public float x2;
public float x3;
}
public class Program
{
static void Main(string[] args)
{
var source = new Source1() { x1 = 1, x2 = 2, x3 = 3 };
Target target = source;
Console.WriteLine(target.x2);
Console.ReadLine();
}
}
}
Another alternative is using AutoMapper. Performance will be slower though.
Look at this explicit cast
This is the source struct.
public struct Source
{
public int X1;
public int X2;
}
This is the target.
public struct Target
{
public int Y1;
public int Y2;
public int Y3;
public static explicit operator Target(Source source)
{
return new Target
{
Y1 = source.X1,
Y2 = source.X2,
Y3 = 0
};
}
}
Converting phase :
static void Main(string[] args)
{
var source = new Source {X1 = 1, X2 = 2};
var target = (Target) source;
Console.WriteLine("Y1:{0} ,Y2{1} ,Y3:{2} ",target.Y1,target.Y2,target.Y3);
Console.Read();
}

How to make a Struct that can be multipled using *

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;
}

C# PointF Subtract?

Was a bit shocked to discover that System.Drawing.PointF appears to have operators for subtracting sizes but not other PointFs. So I'm trying to write my own PointF class, but it needs to be able to have System.Drawing.Points automatically converted to it, or it really doesn't add any convenience. So I wrote these constructors:
public PointF(float x = 0, float y = 0)
{
this.x = x;
this.y = y;
}
public PointF(System.Drawing.PointF p) : this(p.X, p.Y) { }
public PointF(System.Drawing.Point p) : this(p.X, p.Y) { }
But I'm still getting this error:
cannot convert from 'System.Drawing.Point' to 'my_namespace.PointF'
(I have a function that accepts a my_namespace.PointF but I'm passing in a System.Drawing.Point).
Shouldn't the 3rd constructor kick in and auto-convert it?
Do you have an implicit conversion defined in your my_namespace.PointF class? It won't automatically convert otherwise.
public PointF(float x = 0, float y = 0)
{
this.x = x;
this.y = y;
}
public PointF(System.Drawing.PointF p) : this(p.X, p.Y) { }
public PointF(System.Drawing.Point p) : this(p.X, p.Y) { }
//add this:
public static implicit operator PointF(System.Drawing.Point pt)
{ return new PointF(pt); }
Have you considered the option of writing an 'extension method' instead of rolling out your own class ?
You can't have operator overloading per se via extn. methods (proposed in next revision of the framework).. but you should be able to use a synonymous method called Add() for + and get by.
This compiles for me:
class PointF {
float x; float y;
public PointF(float x, float y)
{
this.x = x;
this.y = y;
}
public PointF(System.Drawing.PointF p) : this(p.X, p.Y) { }
public PointF(System.Drawing.Point p) : this(p.X, p.Y) { }
public static implicit operator PointF(System.Drawing.Point pt) { return new PointF(pt); }
public static implicit operator PointF(System.Drawing.PointF pt) { return new PointF(pt); }
}
//....
static void test(pointf.PointF p) {
}
//....
test(new System.Drawing.PointF(1, 1));

Categories

Resources