How to draw an icoSphere made of triangle_fans ?

edited February 2018 in Python Mode

Hi !

I'm trying to make an icoSphere using the beginShape() function.

I've managed to draw a sphere made of particles but don't know how to connect those particles using the TRIANGLE_FAN parameter.

More specifically, there are 2 key parts that I can't figure out (from line 57):

  • How many vertex() functions do I need to write within the double for loop ?
  • What should be the coordinates of those vertices ?

Any help would be much appreciated.


from toxi.physics import VerletPhysics    ### using VerletPhysics engine
from particle import Particle   ### simple class containing a particle object

def setup():
    global particules, physics, total
    size(1080, 800, P3D)

    cam = PeasyCam(this, 110)
    physics = VerletPhysics()

    r = 180   ### radius of the sphere
    total = 10  ### number of particles/points

    particules = [[[] for e in range(total +1)] for f in range(total+1)]    ### 2D array list storing the particles locations

    for e in range(0, total+1):
            lon = map(e, 0, total, 0, PI)
            for f in range(0, total+1):
                lat = map(f, 0, total , 0, TWO_PI)

                x = r * sin(lat) * cos(lon) 
                y = r * sin(lat) * sin (lon) 
                z = r * cos(lat)

                particules[e][f] = Particle(x, y, z) 

    for e in range(total+1):
        for f in range(total+1):
            p = particules[e][f]
            physics.addParticle(p)   ### adding the particles to the physics engine

def draw():
    global particules, physics

    for e in range(total+1):    ### displaying the particles
        for f in range(total+1):
            p = particules[e][f]

    for e in range(total):
        beginShape(TRIANGLE_FAN)  ### Trying to connect the particles with triangle fans
        for f in range(total+1):

            p = particules[e][f-1]            ### PART TO CORRECT #### vertices and their coordinates ####
            vertex(p.x(), p.y(), p.z())
            p2 = particules[e+1][f]        
            vertex(p2.x(), p2.y(), p2.z())      



  • edited February 2018

    The code above gives me this shape:

    As you can see the triangle fans and not completed and most of the points are connected to one pole.

    Any idea of what I should change in the following snippet ?

    for e in range(total):
            for f in range(total+1):
                p = particules[e][f-1]         ### PART TO CORRECT #### 
                vertex(p.x(), p.y(), p.z())
                p2 = particules[e+1][f]        
                vertex(p2.x(), p2.y(), p2.z())      
  • Please share your ideas, suggestions, code (even in Java)... anything !

  • I tried and I failed... Shouldn't you be using TRIANGLE_STRIPS btw?

    Check this post:

    My other lame suggestion:

    My attempt below but it has a bug.


    // IMPORTS:
    import peasy.PeasyCam;
    PeasyCam cam;
    int r=180;
    int sr=3;
    int total=10;
    PVector[][] vv=new PVector[total][total];
    void settings() {
      size(1080, 800, P3D);
    void setup() {
      textAlign(CENTER, CENTER);
      cam = new PeasyCam(this, 400);
      for (int e=0; e<total; e++) {
        float lon = map(e, 0, total, 0, TWO_PI);
        for (int f=0; f<total; f++) {
          float lat = map(f, 0, total, 0, PI);
          PVector p = new PVector( r * sin(lat) * cos(lon), 
            r * sin(lat) * sin (lon), 
            r * cos(lat));
    void draw() {
      for (float e=0; e<total/1.0; e++) {
        for (float f=0; f<total; f++) {
          fill(lerp(0, 255, e*1.0/total), lerp(0, 255, f*1.0/total), 25);
          if (f-1>0) {
            PVector p= vv[int(e)][int(f-1)%total];
            vertex(p.x, p.y, p.z);
          //if (e+1<total) {
          PVector q= vv[int(e+1)%total][int(f-0)%total];
          vertex(q.x, q.y, q.z);
        vertex(0, 0, -180);
  • You didn't need to start a new Question for this.

    You don't use all triangle fans, just the top and bottom rows where you have a central point at the pole. The rest is triangle strips.

    The sphere code in github does exactly this.

  • edited February 2018

    @kfrajer: Hey that's super nice of you to share your attempt ! I did use TRIANGLE_STRIPS at first but koogs suggested me to use TRIANGLE_FANS instead. I've now managed to draw a sphere made of TRIANGLE_STRIPS and where the top and bottom only are made of TRIANGLE_FANS.

    And thanks for the links, the icosahedron sketch is really interesting. I'm now wondering what are the difference between an icosphere and an icosahedron. Anyway I'll probably use a part of the code for my next attempt.

    @koogs: As I just mentionned, I could draw a sphere made of triangle strips, where tops and bottoms only are triangle fans. HOWEVER (and this has more to do with my other question about springs) when I connect the vertices by springs the whole sphere falls apart. This is partly because I've now different meshes:

    • 4 made of triangle fans for the poles (2 for each pole)
    • 2 made of triangle strips for the "body" of the sphere (front and back)

    I guess it'd be a better idea to draw a sphere based on a single mesh. Is that possible ? (with an icosahedron for instance ?)

    Also what "sphere code" are you refering to ? Would you mind sharing a link ?

    PS: This is what the same sphere looks like when I add springs to each vertices and tie the different meshes together:

  • processing sphere code. it's complicated but you can see from the comments it's three bits, the top, the middle and the bottom.

  • edited February 2018

    Do you think it's possible to draw a sphere with a single mesh ? (one single part, no top, middle or bottom)

  • Just brainstorming -- you might try basing your mesh algorithm on the points of a Fibonacci spiral. That walks a sphere from top to bottom as a spiral.

  • edited March 2018

    @jeremydouglass: That's a very interesting suggestion. I'll definitely look into it after I'm finished with my current polyhedron experiment. Thanks a lot !

  • I just wanted to share a much less cumbersome approach based on @jeremydouglass last suggestion. It's a 2 step process:

    • displaying points around a Fibonacci sphere
    • triangulating those points with the Hemesh library

      phi = (sqrt(5) + 1) / 2 - 1 #Golden Ratio
      angle = phi * 2 * PI #Golden Angle
      n_points, radius = 300, 200
      liste = []
      def setup():
          global triangles, render
          size(600, 600, P3D)
          render = WB_Render(this)
          for p in range(n_points):
              lon = angle * p
              lon /= 2 * PI; lon -= floor(lon); lon *= 2 * PI
              if lon > PI: lon -= 2 * PI 
              lat = asin(-1 + 2 * p / float(n_points))
              new_points = WB_Point(radius * cos(lat) * cos(lon), radius * cos(lat) * sin(lon), radius * sin(lat))
          triangulation = WB_Triangulate.alphaTriangulate3D(liste)
          triangles = triangulation.getAlphaTriangles(radius+1)
      def draw():
          translate(width/2, height/2)
          for i in range(0, len(triangles), 3):
              render.drawTriangle(liste[triangles[i]], liste[triangles[i+1]], liste[triangles[i+2]])

Sign In or Register to comment.