Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Approximating a sphere in OpenGL

I am trying to approximate a sphere using the instructions at http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/sphere_cylinder/, but it doesn't look right at all. This is my code:

def draw_sphere(facets, radius=100):
    """approximate a sphere using a certain number of facets"""

    dtheta = 180.0 / facets
    dphi = 360.0 / facets

    global sphere_list
    sphere_list = glGenLists(2)
    glNewList(sphere_list, GL_COMPILE)

    glBegin(GL_QUADS)

    for theta in range(-90, 90, int(dtheta)):
        for phi in range(0, 360, int(dphi)):
            print theta, phi
            a1 = theta, phi
            a2 = theta + dtheta, phi
            a3 = theta + dtheta, phi + dphi
            a4 = theta, phi + dphi

            angles = [a1, a2, a3, a4]

            print 'angles: %s' % (angles)


            glColor4f(theta/360.,phi/360.,1,0.5)

            for angle in angles:
                x, y, z = angle_to_coords(angle[0], angle[1], radius)
                print 'coords: %s,%s,%s' % (x, y, z)
                glVertex3f(x, y, z)



    glEnd()

    glEndList()


def angle_to_coords(theta, phi, radius):  
    """return coordinates of point on sphere given angles and radius"""

    x = cos(theta) * cos(phi)
    y = cos(theta) * sin(phi)
    z = sin(theta)

    return x * radius, y * radius, z * radius

It seems that some of the quads aren't simple, i.e. the edges are crossing, but changing the order of the vertices doesn't seem to make any difference.

like image 772
eggbert Avatar asked Nov 30 '25 15:11

eggbert


1 Answers

I don't have a system here that can run Python and OpenGL together, but I can see a few issues anyway:

You're rounding dphi and dtheta in the range statements. This means that the facets will always start on a whole degree, but then when you add the unrounded delta values the far edge isn't guaranteed to do so. This is the probable cause of your overlaps.

It would be better to have your range values go from 0 .. facets-1 and then multiply those indices by 360 / facets (or 180 for the latitude lines) exactly. This would avoid the rounding errors, e.g.:

dtheta = 180.0 / facets
dphi = 360.0 / facets

for y in range(facets):
    theta = y * dtheta - 90
    for x in range(facets):
        phi = x * dphi
        ...

Also, are you converting to radians somewhere else? Python's default trig functions take radians rather than degrees.

like image 154
Alnitak Avatar answered Dec 03 '25 06:12

Alnitak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!