2

I'm trying to implement depth ordering of surfaces and points but I'm unsure how to do it. I have a Point class which basically contains x,y,z coordinates and these are used to define the center point of circles, the ends of lines and the corners of surfaces (tris and quads) so we have:

class Point(object):
    def __init__(self, x, y z):
        self.x = x
        self.y = y
        self.z = z

class Circle(object):
    def __init__(self, center, radius):
        #center is a point
        self.point_array = [center]
        self.radius = radius

class Line(object):
    def __init__(self, pos1, pos2):
        #pos1, pos2 are points
        self.point_array = [pos1, pos2]

class Tri(object):
    def __init__(self, pos1, pos2, pos3):
        #pos's are Points
        self.point_array = [pos1, pos2, pos3]

class Quad(object):
    def __init__(self, pos1, pos2, pos3, pos4):
        #you get the idea by now...
        self.point_array = [point1, point2, point3, point4]

Now I'm culling the ones not visible and appending the objects to a list to the draw to the screen. What I need to do now is sort the list of objects by each objects lowest z-coordinate but I'm unsure how to go about this.

1
  • Are there Point objects in your list to sort, or only Quad, Tri, Line and Circle objects? Commented Apr 22, 2014 at 14:04

1 Answer 1

3

Create a sort function that extracts the lowest z coordinate per object:

def lowest_z(obj):
    return min(p.z for p in obj.point_array)

sorted(list_of_objects, key=lowest_z)

You can inline that function by using a lambda function, of course:

sorted(list_of_objects, key=lambda o: min(p.z for p in o.point_array))

This assumes there are no Point objects in the list your are sorting, only Quad, Tri, Line and Circle objects.

It could be helpful to add a method to your objects that returns the lowest z coordinate; that way you could adjust how that point is determined based on the type of object; that way your Cicle class, with only a radius and central point, can still calculate the minimum z based on that information:

class Shape(object):
    # subclasses must provide a point_array instance attribute
    @property
    def lowest_z(self):
        return min(p.z for p in self.point_array)

class Line(Shape):
    def __init__(self, pos1, pos2):
        #pos1, pos2 are points
        self.point_array = [pos1, pos2]

class Circle(Shape):
    def __init__(self, center, radius):
        #center is a point
        self.point_array = [center]
        self.radius = radius

    @property
    def lowest_z(self):
        return self.point_array[0].z - self.radius

# etc.

then sort by the point_array property:

sorted(list_of_objects, key=lambda o: o.lowest_z)

or, using operator.attrgetter():

from operator import attrgetter

sorted(list_of_objects, key=attrgetter('lowest_z'))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.