Beispiel #1
0
def circle(a1=2., a2=0., a3=360., r=None, n=None, c=None, eltype='line2'):
    """A polygonal approximation of a circle or arc.

    All points generated by this function lie on a circle with unit radius at
    the origin in the x-y-plane.

    - `a1`: the angle enclosed between the start and end points of each line
      segment (dash angle).
    - `a2`: the angle enclosed between the start points of two subsequent line
      segments (module angle). If ``a2==0.0``, `a2` will be taken equal to `a1`.
    - `a3`: the total angle enclosed between the first point of the first
      segment and the end point of the last segment (arc angle).

    All angles are given in degrees and are measured in the direction from
    x- to y-axis. The first point of the first segment is always on the x-axis.

    The default values produce a full circle (approximately).
    If $a3 < 360$, the result is an arc.
    Large values of `a1` and `a2` result in polygons. Thus
    `circle(120.)` is an equilateral triangle and `circle(60.)`
    is regular hexagon.

    Remark that the default a2 == a1 produces a continuous line,
    while a2 > a1 results in a dashed line.

    Three optional arguments can be added to scale and position the circle
    in 3D space:

    - `r`: the radius of the circle
    - `n`: the normal on the plane of the circle
    - `c`: the center of the circle
    """
    if a2 == 0.0:
        a2 = a1
    ns = round(a3/a2)
    a1 *= pi/180.
    if eltype=='line2':
        F = Formex([[[1., 0., 0.], [cos(a1), sin(a1), 0.]]]).rosette(ns, a2, axis=2, point=[0., 0., 0.])
    elif eltype=='line3':
        F = Formex([[[1., 0., 0.], [cos(a1/2.), sin(a1/2.), 0.], [cos(a1), sin(a1), 0.]]], eltype=eltype).rosette(ns, a2, axis=2, point=[0., 0., 0.])
    if r is not None:
        F = F.scale(r)
    if n is not None:
        F = F.swapAxes(0, 2).rotate(rotMatrix(n))
    if c is not None:
        F = F.trl(c)
    return F
Beispiel #2
0
    def __init__(self,text,pos,gravity=None,size=18,width=None,font=None,lineskip=1.0,grid=None,texmode=4,**kargs):
        """Initialize the Text actor."""

        # split the string on newlines
        text = str(text).split('\n')

        # set pos and offset3d depending on pos type (2D vs 3D rendering)
        pos = at.checkArray(pos)
        if pos.shape[-1] == 2:
            rendertype = 2
            pos = [pos[0],pos[1],0.]
            offset3d = None
        else:
            rendertype = 1
            offset3d = Coords(pos)
            pos = [0.,0.,0.]
            if offset3d.ndim > 1:
                if offset3d.shape[0] != len(text[0]):
                    raise ValueError("Length of text(%s) and pos(%s) should match!" % (len(text),len(pos)))
                # Flag vertex offset to shader
                rendertype = -1

        # set the font characteristics
        if font is None:
            font = FontTexture.default(size)
        if isinstance(font,(str,unicode)):
            font = FontTexture(font,size)
        if width is None:
            #print("Font %s / %s" % (font.height,font.width))
            aspect = float(font.width) / font.height
            width = size * aspect
        self.width = width

        # set the alignment
        if gravity is None:
            gravity = 'E'
        alignment = ['0','0','0']
        if 'W' in gravity:
            alignment[0] = '+'
        elif 'E' in gravity:
            alignment[0] = '-'
        if 'S' in gravity:
            alignment[1] = '+'
        elif 'N' in gravity:
            alignment[1] = '-'
        alignment = ''.join(alignment)

        # record the lengths of the lines, join all characters
        # together, create texture coordinates for all characters
        # create a geometry grid for the longest line
        lt = [ len(t) for t in text ]
        text = ''.join(text)
        texcoords = font.texCoords(text)
        if grid is None:
            grid = Formex('4:0123').replic(max(lt))
        grid = grid.scale([width,size,0.])

        # create the actor for the first line
        l = lt[0]
        g = grid.select(range(l)).align(alignment,pos)
        Actor.__init__(self,g,rendertype=rendertype,texture=font,texmode=texmode,texcoords=texcoords[:l],opak=False,ontop=True,offset3d=offset3d,**kargs)

        for k in lt[1:]:
            # lower the canvas y-value
            pos[1] -= font.height * lineskip
            g = grid.select(range(k)).align(alignment,pos)
            C = Actor(g,rendertype=rendertype,texture=font,texmode=texmode,texcoords=texcoords[l:l+k],opak=False,ontop=True,offset3d=offset3d,**kargs)
            self.children.append(C)
            # do next line
            l += k