Sorting an array of objects

I’m trying to port some Javascript code to Xojo (a 2D physics library). It’s proving a little tricky mainly because Javascript lets you do some funky stuff not easily doable in Xojo.

Anyway, I have a single dimensional array of Vertex objects (essentially Vectors with an x an y property) that I’m trying to do a clockwise sort on.

This is the Javascript code:

[code] Vertices.clockwiseSort = function(vertices) {
var centre = Vertices.mean(vertices);

    vertices.sort(function(vertexA, vertexB) {
        return Vector.angle(centre, vertexA) - Vector.angle(centre, vertexB);
    });

    return vertices;
};[/code]

so, centre is a Vector and the Vector.Angle method returns a Double.

If my Javascript is correct, I think this means that the code is comparing adjacent values in the array, finding the angle between them and then sorting the resultant array based on those values.

Is there any way in Xojo to do a complex sort where we can specify the sort criteria used to do the sort? Is this something I can use the SortWith() method for??

The arr.Sort( sortMethod ) will do the trick for you. See:

http://developer.xojo.com/arrays$Sort

I didn’t know that function had been added! Thanks.

Since you can only pass two parameters to the delegate (I need a third, the centre variable). What I did was make a global variable accessible to the delegate (csCentre) and implemented the following:

Sub ClockwiseSort(verts() as Vertex) csCentre = Vertices.Mean(verts) ' this will calculate the mean of the vertices verts.Sort(AddressOf CompareClockwiseSort) End Sub

[code]
Sub CompareClockwiseSort(vertexA as Vertex, vertexB as Vertex) as Integer
dim result as Double = Vector.Angle(csCentre, vertexA) - Vector.Angle(csCentre, vertexB)

if result > 0 then
return 1
elseif result < 0 then
return -1
else
return 0
end if
End Sub[/code]

Seems to work perfectly. Thanks!

Global variables should be avoided if possible. In this case, since the Centre is applicable to your Vertex class, can you make it a Shared Property instead? Or, perhaps better, another class called VertexSorter that implements these methods and calculates and holds the Centre.

This is more work, to be sure, but the benefits of encapsulating will make up for it.

[quote=248707:@Garry Pettet]I didn’t know that function had been added! Thanks.

Since you can only pass two parameters to the delegate (I need a third, the centre variable). What I did was make a global variable accessible to the delegate (csCentre) and implemented the following:

Sub ClockwiseSort(verts() as Vertex) csCentre = Vertices.Mean(verts) ' this will calculate the mean of the vertices verts.Sort(AddressOf CompareClockwiseSort) End Sub

[code]
Sub CompareClockwiseSort(vertexA as Vertex, vertexB as Vertex) as Integer
dim result as Double = Vector.Angle(csCentre, vertexA) - Vector.Angle(csCentre, vertexB)

if result > 0 then
return 1
elseif result < 0 then
return -1
else
return 0
end if
End Sub[/code]

Seems to work perfectly. Thanks![/quote]

For what it’s worth, the comparison function isn’t restricted to -1, 0, and 1. It’s simply negative, zero, and positive.