Right now, if I want to tell if two vectors are the same, I need to do something like this:

`if ((V1 - V2).LengthSquared() == 0) { ... }`

While this works, it's inelegant and harder to read.

Same thing for basic == and != operators for quaternions.

• Gindipple

What you are doing there will not tell you if 2 vectors are the same.

You need to include the angles in the comparison.

Remember a vector is a length and an angle.

Picture 2 vectors pointing away from each other.

Include the dot product in your comparison.

And for Quaternions this gets way more complicated as there are several rotations that perform the same result. So there is no real is equal concept there.

Edited by Gindipple
• Galen

If the distance between two vectors is zero, then they are the same.

• Gindipple

Yup, was confused by how you were achieving distance there.

Also worth pointing out not a good idea to do == 0 in floating point world

Better to do an IsApproxCloseTo() with a default epsilon.

On Quanternions it really doesn't make sense though as 2 Quats can get you to the same rotation and yet be different.

I'd like to see the case for Quats if you have one.

Personally on vectors it seems more intuitive to use dot product and magnitude. Or even just use the cross product, A x A = Vector.Zero

• Galen

In my actual code, I use a threshold comparison like this:

`if ((V1 - V2).LengthSquared() <= 0.001) { ... }`

However, I still want equals (and not equals) comparisons because when a vector is literally a copy of another one, there won't be any floating point errors to worry about. The algorithm is simply like this (untested):

`public bool Equals(Vector V) {    if (V.X != this.X) return false;    if (V.Y != this.Y) return false;    if (V.Z != this.Z) return false;    if (V.W != this.W) return false;    return true;}`

I could be mistaken, but I believe all possible quaternions are unique, even if that one vector could beget the same output vector by an infinite number of quaternion rotations. So its comparison should be pretty much the same as for vectors.

• Gindipple

If an object is a copy of another then the way you are wanting to do it seems very wrong

I'm not really awake just yet, but have you considered that they are derived off of Object() and using gethashcode or whatever it is spelled.

If you copied something then you automatically know problematically that it's a copy.

Basically I think this whole idea is bad. And the irony here is I used this just last night:

` private void VerifyQuaternionEqual(Quaternion q2, Quaternion q3) { if (!q2.W.IsCloseToEqual(q3.W) || !q2.X.IsCloseToEqual(q3.X) || !q2.Y.IsCloseToEqual(q3.Y) || !q2.Z.IsCloseToEqual(q3.Z)) DebugDebugMsg("Fail! " + q2.ToString() + " " + q3.ToString()); }`

And I still say it's bad. It was in temp code. If this was in keepable run time code I'd do it differently.

I consider this to be similar to my request they add float extension to multiply a Vector() it's really not their place to add that, but it needs to exist somewhere for completeness. Ideally we will get libraries and that solves it.

• Galen

The Vector type is a "struct", not a class. The assignment operation creates a copy instead of a reference to it. Thus, in:

`Vector B = A;`

B and A have their own separate memory. It's not like with class instances (objects), where the assignment operator only creates a copy of the reference.

And just because you made a copy of a variable in one piece of code does not mean you know it in another piece.

Edited by Galen
• Galen

And I agree with your request to add an extension to make the following two equivalent:

`Vector B1 = A * 123;  // Valid nowVector B2 = 123 * A;  // Semantic error now`

I've had several occasions where I would have rather used the second form.

• Gindipple

Fair enough, without seeing the code and actual use case it's hard to say for sure, but something just feels wrong about it.

Maybe it's that it just feels like it should be a local method instead of embedded. Like one could ask why isn't there a RigidBody == operator?

As an aside you should be able to do if(A.ToString().Equals(B).ToString()) for your case.

But I'd opt for the method you made up there as an extension method over that.