Sign in to follow this  
Spa8nky

[C#] How do I include other classes in an IComparer?

Recommended Posts

Spa8nky    230
If I would like to compare a list of quadrangles by draw depth then I'm currently using the following Comparer:

[code]

class SortDrawAscending : IComparer<Quadrangle>
{
static IComparer<Quadrangle> comparer = new SortDrawAscending();

public int Compare(Quadrangle a, Quadrangle b)
{
return Comparer<int>.Default.Compare(a.DrawDepth, b.DrawDepth);
}

public static IComparer<Quadrangle> Comparer
{
get { return comparer; }
}
}
[/code]

However, if I wish to sort each quadrangle by its distance from the camera then I would need to include the camera class in the comparer:

[code]

class SortDrawDistanceDescending : IComparer<Quadrangle>
{
static IComparer<Quadrangle> comparer = new SortDrawDistanceDescending();

public int Compare(Quadrangle a, Quadrangle b)
{
return Comparer<int>.Default.Compare(
Vector3.Dot(a.Position - camera.Position, camera.Forward),
Vector3.Dot(b.Position - camera.Position, camera.Forward)
);
}


public static IComparer<Quadrangle> Comparer
{
get { return comparer; }
}
}
[/code]

How can this be achieved so I can easily sort a list of quadrangles by their distance from the camera?

I'm currently using the following line to sort all the quadrangles:

[code]
Array.Sort(transparentQuadrangles, 0, numTransparentQuadrangles, SortDrawDistanceDescending.Comparer);
[/code]

If a more suitable method can be used to avoid recalculating the distance for each compare then that would be great also.

Share this post


Link to post
Share on other sites
SiCrane    11839
Well the obvious answer would be to give your class a constructor that accepts a camera and use new SortDrawDistanceDescending(camera) instead of a static property.

Share this post


Link to post
Share on other sites
Spa8nky    230
Wouldn't the comparer still be recalculating

[code]

Vector3.Dot(a.Position - camera.Position, camera.Forward)
Vector3.Dot(b.Position - camera.Position, camera.Forward)
[/code]

each time two quadrangles are compared though? How can I make sure the values are only calculated once per quadrangle per frame?

EDIT:

I created a property called DrawDepth and assigned it a value before hand:

[code]

// Calculate the quadrangles position from the camera
for (int i = 0; i < numTransparentQuadrangles; ++i)
{
transparentQuadrangles[i].DrawDepth = Vector3.Dot(transparentQuadrangles[i].Position - camera.Position, camera.Forward);
}
[/code]

Now the Comparer is as follows:

[code]

class SortDrawDistanceDescending : IComparer<Quadrangle>
{
static IComparer<Quadrangle> comparer = new SortDrawDistanceDescending();

public int Compare(Quadrangle a, Quadrangle b)
{
return Comparer<float>.Default.Compare(a.DrawDepth, b.DrawDepth);
}

public static IComparer<Quadrangle> Comparer
{
get { return comparer; }
}
}
[/code]

but this still sorts them in ascending order and not descending...

EDIT2:

[code]

class SortDrawDistanceDescending : IComparer<Quadrangle>
{
static IComparer<Quadrangle> comparer = new SortDrawDistanceDescending();

public int Compare(Quadrangle a, Quadrangle b)
{
if (a.DrawDepth < b.DrawDepth)
{
return 1;
}
else if (a.DrawDepth > b.DrawDepth)
{
return -1;
}
else
{
return 0;
}
}

public static IComparer<Quadrangle> Comparer
{
get { return comparer; }
}
}
[/code]

Problem solved.

Share this post


Link to post
Share on other sites
Gorg    248
Since you already have an ascending comparer, you can also just create a new comparer that inverts the comparison of an existing one.

[code]

public class ReverseOrderComparer<T> : IComparer<T>
{
public ReverseOrderComparer(IComparer<T> comparer)
{
this.comparer = comparer;
}

IComparer<T> comparer;
public int Compare(T x, T y)
{
return comparer.Compare(y, x);
}
}
[/code]

You use it like this:

[code]

List<int> i = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

i.Sort(new ReverseOrderComparer<int>(Comparer<int>.Default));

[/code]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this