Azurewrath

Hi all,

I am trying this method, but with an arraylist that contains Vector3 data types, I don't know how to find a particular one.

I tried:

Console.WriteLine ( "IndexOf Vector3: {0}", a.IndexOf ( new Vector3 ( 0, 0, 1 ) ) );

But this returns -1, even though there is a Vector3 ( 0, 0, 1 ) in the arraylist.

Any idea on how to solve this





Thanks,
Aw


Re: Visual C# Language ArrayList.IndexOf

Nullable

Hey Aw,

You are creating a new object and passing it to the IndexOf.

IndexOf only returns the index of the existing object in that list.

For example..

Vector3 v = new Vector3();

ArrayList a = new ArrayList();

a.Add(v);

Now a.IndexOf(v) will return 0

If you want to compare the coordinates and tell if the Vector exists then consider using a Generic List<Vector3> and write an overload IndexOf(int x, int y, int z) which loops through the collection and find the matching vector index.

Cheers





Re: Visual C# Language ArrayList.IndexOf

Azurewrath

Thanks man. Now I know how to do it.

But there is no other way for this

Because I was expecting the compiler to use the Equals method and == operator I implemented to find the vector I want.





Thanks,
Aw




Re: Visual C# Language ArrayList.IndexOf

IsshouFuuraibou

Because array list is generalized it compares the reference rather than performing the .Equals operation. ArrayList can technically have any object in it of any type, because each object is independant of the other objects you can have two items in ArrayList with different types

ArrayList a = new ArrayList();
a.Add( 42 );
a.Add( "Something" );
a.Add( new Vector3( 0, 1, 0 ) );

now how do you suppose
a.IndexOf( new Vector3( 0, 1, 0 ) );
is going to work with 42 with the string "Something"
In order to be able to call .Equals on all items in the list, it has to be able to understand all types of objects. How are you going to compate Vector3( 0, 1, 0 ) to "Something"

So, obviously it defaults to the object.Equals method which compares reference (location in memory)
since you're declaring a new Vector3 to find the one inside the list, your memory locations aren't going to be the same.

So the way you can get explicit compares is to use something that is typed. Since we now have (2.0+) generic collections, we can just form a typed collection with List<Type>. This will function like an ArrayList but maintain it's type information, and coincidentally call comparison operators from said type.





Re: Visual C# Language ArrayList.IndexOf

Azurewrath

Thanks Eric. Now I understand. Actually I was using ArrayList just for practice. I tried List, and it still returned -1. But I have supplied new Vector3 (0,0,1) to IndexOf. Is this the way to go

Just to make sure I used v[2].Equals(new Vector3 (0,0,1)), and it returned true.

Do you know what I am doing wrong





Thanks again,
Aw




Re: Visual C# Language ArrayList.IndexOf

IsshouFuuraibou

What overloads for equals, ==, != do you have it may be something to do with List<Vector3> looking to call .Equals( object ) still rather than .Equals( Vector3 )





Re: Visual C# Language ArrayList.IndexOf

Azurewrath

Thanks man.

I have these:

public static bool operator == ( Vector3 v1, Vector3 v2 )

{

return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z;

}

public static bool operator != ( Vector3 v1, Vector3 v2 )

{

return !( v1 == v2 );

}

public bool Equals ( Vector3 that )

{

return this == that;

}


Could it be precision error in #1 x, y, z are floats.




Thanks,
Aw




Re: Visual C# Language ArrayList.IndexOf

IsshouFuuraibou

There is a possibility of percision errors with floats

try adding:

Code Block

public bool Equals ( object that )

{

if( that is Vector3 )

return this == (Vector3)that;

else
return false;

}







Re: Visual C# Language ArrayList.IndexOf

Peter Ritchie

Because array list is generalized it compares the reference rather than performing the .Equals operation.

ArrayList.IndexOf does use the Equals method to test for equality of elements in the list.

For example, the following will output "Equals was called":

Code Block

class Vector3

{

private float x, y, z;

public Vector3(float x, float y, float z)

{

this.x = x;

this.y = y;

this.z = z;

}

public override bool Equals(object obj)

{

Console.WriteLine("Equals was called");

Vector3 otherVector3 = obj as Vector3;

if (otherVector3 != null)

{

return otherVector3.x == x && otherVector3.y == y && otherVector3.z == z;

}

return base.Equals(obj);

}

}

System.Collections.ArrayList a = new System.Collections.ArrayList();

a.Add(new Vector3(1,2,3));

int i = a.IndexOf(new Vector3(1,2,3));

AW, can you verify your Equals method is being called If so, maybe if you post the contents we can offer some guidance. You might be running into a problem with floating-point "equality".




Re: Visual C# Language ArrayList.IndexOf

Azurewrath

Thanks again. I tried it and same result. Also tried this:

public static bool operator == ( Vector3 v1, Vector3 v2 )

{

return

Math.Abs(v1.x - v2.x) <= Double.Epsilon &&

Math.Abs(v1.y - v2.y) <= Double.Epsilon &&

Math.Abs(v1.z - v2.z) <= Double.Epsilon;

}


Same result: -1.





Thanks,
Aw




Re: Visual C# Language ArrayList.IndexOf

Peter Ritchie

What are the 6 values for each x,y,z






Re: Visual C# Language ArrayList.IndexOf

IsshouFuuraibou

Comparison agaisnt double.Epsilon is not a really useful thing. double can't represent anything between 0 and that number so it can't really be between zero and Epsilon.

try:

public static bool operator == ( Vector3 v1, Vector3 v2 )

{

return v1.x.Equals(v2.x) && y.Equals(v2.y) && v1.z.Equals(v2.z);

}


It seems odd but I have seen things where

f != float.NaN returning true when f is float.NaN

but when I use

!f.Equals(float.NaN)

it returns the correct boolean


Single.Equals(Single)
This method implements the System.IEquatable interface, and performs slightly better than Equals because it does not have to convert the obj parameter to an object.


not sure what == ends up using





Re: Visual C# Language ArrayList.IndexOf

Peter Ritchie

You should use float.IsNaN to test if a value is NaN.






Re: Visual C# Language ArrayList.IndexOf

Azurewrath

Thanks alot guys!

Basically I use 0, 0, 1 for x, y, z respectively for both v1 and v2. But one is List and the other is a single vector.




Thanks again,
Aw




Re: Visual C# Language ArrayList.IndexOf

Azurewrath

Hey Eric,

Tried your method and it worked! I can't believe this. So is this equals method uses a tolerance value





Thanks,
Aw