Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Arrow or cone with cggit

Help
2013-08-03
2013-08-04
  • Uwe Fechner
    Uwe Fechner
    2013-08-03

    Hello,

    how can I create an arrow or a cone with cggit?

    I know how to create CCylinder and Sphere objects, but
    I could not find a way to create 3d arrow or cone yet.

    I think that a Polyhedron might be a way to go, but
    there is no example how to create a Polyhedron in the
    documentation.

    http://cgkit.sourceforge.net/doc2/polyhedron.html

    Any idea?

    Best regards:

    Uwe Fechner

     
  • Uwe Fechner
    Uwe Fechner
    2013-08-04

    Ok, I found a work-around:

    from cgkit.all import *
    import OpenGL.GLUT as glut
    from math import pi
    SCALE = 25          # meters per tick mark 
    
    Globals(
        background = (0.7, 0.8, 1.0),
        resolution = (768, 768)
    )
    
    TargetCamera(
        pos    = (20 * SCALE, 15 * SCALE, 15 * SCALE) , # default view
        target = (0 * SCALE, 0 * SCALE, 5 * SCALE)
    )
    
    GLPointLight(
        pos       = (3 * SCALE, -1 * SCALE, 2 * SCALE),
        diffuse   = (0.7, 0.7, 0.7)
    )
    
    GLPointLight(
        pos       = (20 * SCALE, 15 * SCALE, 15 * SCALE),
        diffuse   = (0.7, 0.7, 0.7)
    )
    
    GLPointLight(
        pos       = (-5 * SCALE, 3 * SCALE, 0 * SCALE),
        diffuse   = (0.7, 0.7, 0.7)
    )
    
    # First, some useful functions
    def rx(ang):
        return mat3(1).rotate(ang, (1,0,0))
    def ry(ang):
        return mat3(1).rotate(ang, (0,1,0))
    def rz(ang):
        return mat3(1).rotate(ang, (0,0,1))
    
    # Define materials
    matRed     = GLMaterial(name="Red",     diffuse=(1,0,0))
    matGreen   = GLMaterial(name="Green",   diffuse=(0,1,0))
    matBlue    = GLMaterial(name="Blue",    diffuse=(0.2,0.2,1))
    matGray    = GLMaterial(name="Gray",    diffuse=(0.5,0.5,0.5))
    
    def createCoordinateSystem(points = 10, length = 10):
        # create origin
        Sphere(radius = 0.1 * SCALE, pos = (0, 0, 0),  material  = matGray)
        # create x-axes in red
        if points > 0:
            for x in range(points + 2):
                if x - 1 != 0:
                    Sphere(radius = 0.1 * SCALE, pos = ((x - 1) * SCALE, 0, 0),  material  = matRed)
        if points == 0:                
            points = lenght
        CCylinder(length = (points + 2.0) * SCALE, radius = 0.05 * SCALE,  
                  rot = ry(pi / 2.0), 
                  pos = vec3((points / 2.0) * SCALE, 0, 0),
                  material  = matRed  )
        # create arrow at the top
        for i in range(10):
            CCylinder(length = 0.07 * SCALE, radius = 0.018 * (10 - i) * SCALE, scale = (1, 1, 0.5 + i / 18.0),
                      pos = vec3((points + 1 + 0.07 * i) * SCALE, 0, 0),
                      rot = ry(pi / 2.0), material  = matRed  )       
        glut.glutInit()
        drawText(((points + 2.25) * SCALE, 0, 0), "x", font = glut.GLUT_BITMAP_HELVETICA_18, color=(0, 0, 0))  
        #create y-axes in green
        if points > 0:
            for y in range(2 * points + 1):
                if y - points != 0:
                    Sphere(radius = 0.1 * SCALE, pos = (0, (y - points) * SCALE, 0),  material  = matGreen)
        if points == 0:                
            points = lenght
        CCylinder(length = (2 * points + 2.0) * SCALE, radius = 0.05 * SCALE, rot=rx(pi/2.0), material = matGreen)
        # create arrow at the top
        for i in range(10):
            CCylinder(length = 0.07 * SCALE, radius = 0.018 * (10 - i) * SCALE, scale = (1, 1, 0.5 + i / 18.0),
                      pos = vec3(0, (points + 1 + 0.07 * i) * SCALE, 0),
                      rot = rx(pi / 2.0), material  = matGreen)        
        drawText((0, (points + 2.0) * SCALE, - 0.25 * SCALE), "y", font = glut.GLUT_BITMAP_HELVETICA_18, color=(0, 0, 0))                  
        # create z-axes in blue
        if points > 0:
            for z in range(points + 2):
                if z - 1 != 0:
                    Sphere(radius = 0.1 * SCALE, pos = (0, 0, (z - 1) * SCALE),  material  = matBlue)
        if points == 0:                
            points = lenght
        CCylinder(length = (points + 2.0) * SCALE, radius = 0.05 * SCALE, 
                  pos = vec3(0, 0, (points / 2.0) * SCALE), 
                  rot = rz(pi / 2.0), material  = matBlue)
        # create arrow at the top
        for i in range(10):
            CCylinder(length = 0.07 * SCALE, radius = 0.018 * (10 - i) * SCALE, scale = (1, 1, 0.5 + i / 18.0),
                      pos = vec3(0, 0, (points + 1 + 0.07 * i) * SCALE), material  = matBlue)                         
        # write the name of the axis
        drawText((0, -0.12 * SCALE, (points + 2.0) * SCALE), "z", font = glut.GLUT_BITMAP_HELVETICA_18, color=(0, 0, 0))
    
    createCoordinateSystem(8)
    

    But this is not very elegant or efficient. I still would be pleased for any hint to draw a cone correctly (for OpenGL and as rendered output).

    Best regards:

    Uwe Fechner

     
  • Matthias Baas
    Matthias Baas
    2013-08-04

    The verts argument of the Polyhedron is just a list of vertices where a vertex is given by a 3-tuple of floats or a vec3. polys is a list of polygons where each polygon is a list of vertex loops (defined by indices into the vertex list). The first loop is the actual polygon, additional loops define holes.

    If you only need it for rendering, you could use the RiuArrow function inside the riutil module. This one uses a cylinder and a paraboloid.