Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I need to sort a list of x,y points based on distance to a given x,y point. How to do this in C#?

I noticed that the C# standard IComparable interface based sort algorithm does not work because the CompareTo function compares one x,y point to another and there is no way to give access to the third point needed to calculate the distance.

Is there some other C# sorting library that can do this?

I also found this, but I'm not quite sure how it works:
C#
public Comparison<T> MakeComparison<T>(object extraParameter)
{
    return
        delegate(T x, T y)
        {
            // do comparison with x, y and extraParameter
        }
}
Posted
Updated 8-May-11 0:31am
v5

It's a bit simpler than that!
This example sorts a list of Points by looking only at the X distance:
        List<Point> p = new List<Point>();
        ... // Fill p with Points!
        p.Sort(new PointComparer());
        ...
public class PointComparer : IComparer<Point>
    {
    #region IComparer<Point> Members
    public int Compare(Point x, Point y)
        {
        return x.X - y.X;
        }
    #endregion
    }


[edit]Damnit! Caught by the HTML tags again! - OriginalGriff[/edit]

[edit2]"point" changed to "Point" :O - OriginalGriff[/edit2]
 
Share this answer
 
v3
Comments
yesotaso 8-May-11 6:52am    
My 5. If point is your custom type see my solution.
OriginalGriff 8-May-11 7:05am    
Oops! :O
ukram2 8-May-11 13:44pm    
This one seems to be right also. It's a bit funny that my solution worked without any interface definition...
Ok, found a solution that looks more or less ok to me. I used another class, point_sorter to hold the third point and defined a Comparison<T> Delegate compatible function there to compare the two points.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace point
{
    class point
    {
        public double x;
        public double y;
        public point(double px, double py)
        {
            x = px;
            y = py;
        }
    }
    class Program
    {
        class point_sorter
        {
            point p3;
            public point_sorter(point p_p3)
            {
                p3 = p_p3;
            }
            public int compare_points(point p1, point p2)
            {
                double distance_this = (p3.x - p1.x) * (p3.x - p1.x) + (p3.y - p1.y) * (p3.y - p1.y);
                double distance_other = (p3.x - p2.x) * (p3.x - p2.x) + (p3.y - p2.y) * (p3.y - p2.y);
                return distance_this.CompareTo(distance_other);
            }
        }
        static void Main(string[] args)
        {
            List<point> point_list = new List<point>();
            point_list.Add(new point(1, 2));
            point_list.Add(new point(3, 4));
            point_list.Add(new point(5, 5));
            point p3 = new point(6, 6);
            point_sorter ps = new point_sorter(p3);
            point_list.Sort(ps.compare_points);
        }
    }
}
 
Share this answer
 
Comments
lampiclobe 8-May-11 11:19am    
truly understanded question as well as answer. I voted 5.
Congratulations.
see if this alternate can help..

C#
class Program
   {
       public class User
       {
           public string Name;
           public int Age;

           public User(string name, int age)
           {
               this.Name = name;
               this.Age = age;
           }
       }

       static void Main(string[] args)
       {
           // array of custom type
           User[] users = new User[3] { new User("Betty", 23),  // name, age
                            new User("Susan", 20),
                            new User("Lisa", 25) };
           //The distance property
           int customVariable = 10;
           Array.Sort(users, delegate(User user1, User user2)
           {
               //the customVariable is accessable here
               int theCustomVariable = customVariable;
               //Write your logic here to compare it using customVariable
               return user1.Age.CompareTo(user2.Age);
           });
           // write array output
           foreach (User user in users) Console.Write(user.Name + user.Age + " ");
       }
   }

i'll for exact solution meanwhile :)

Thanks,
Hemant
 
Share this answer
 
An alternative if "point" is your custom type.
C#
public class point: IComparable<point>
{
    // do your stuff
    public int CompareTo(point obj)
    {
        // Replace X with your distance stuff (however you compute it).
        return this.X.CompareTo(obj.X);
    }
}</point>

This way you can call sort without any parameters.
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900