Skip to content

support for axis rotation #64

@neurochen

Description

@neurochen

Thanks for the amazing work on FigureFirst! I am wondering if it's possible to add support for rotation of axis. The original package gives rise to an error if the axis contains a rotation transform. I made some changes to handle the rotation parameter, but the SVG output is not as expected. So, it seemed that there are some other code change requirements somewhere else.

Note that the matrix transform implementation also doesn't work if we modify the matrix using the rotation matrix directly.

Please see below for amendments in svg_to_axes.py

def parse_transform(transform_str):
    """convert transforms into transformation matrix"""
    #print transform_str
    import re
    # regex for extracting numbers from transform string
    scanfloat =  r"[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?"
    tr = None;tr_pos = None
    mt = None;mt_pos = None
    sc = None;sc_pos = None
    rt = None;rt_pos = None
    ##################
    if 'translate' in transform_str:
        translate_str = re.findall(r'translate\(.*?\)',transform_str)[0]
        txy = re.findall(scanfloat,translate_str)
        if type(txy) is list and len(txy) == 2:
            tx,ty = txy
        else: # deal with rare situation of exact resizing
            tx = txy[0]
            ty = txy[0]
        tr = np.array([[1.,0,float(tx)],
                       [0,1.,float(ty)],
                       [0,0,1.        ]])
        tr_pos = transform_str.find('translate')
    ##################
    if 'scale' in transform_str:
        translate_str = re.findall(r'scale\(.*?\)',transform_str)[0]
        sx,sy = re.findall(scanfloat,translate_str)
        sc = np.array([[float(sx),0,         0],
                       [0,        float(sy), 0],
                       [0,        0,        1.]])
        sc_pos = transform_str.find('scale')
    ##################
    if 'matrix' in transform_str:
        matrix_str = re.findall(r'matrix\(.*?\)',transform_str)[0]
        a,b,c,d,e,f = re.findall(scanfloat,matrix_str)
        a,b,c,d,e,f = [float(s) for s in [a,b,c,d,e,f]]
        mt = np.array([[a,c,e],
                       [b,d,f],
                       [0,0,1.]])
        mt_pos = transform_str.find('matrix')
    ##################
    if 'rotate' in transform_str:
        rotation_str = re.findall(r'rotate\(.*?\)',transform_str)[0]
        theta = re.findall(scanfloat,rotation_str)
        theta = -int(theta[0])/180*np.pi
        cos, sin = np.cos(theta), np.sin(theta)
        rt = np.array([[cos, -sin, 0],
                       [sin,  cos, 0],
                       [  0,    0, 1.]])
        rt_pos = transform_str.find('rotate')
    ##################
    tr_pos = {False:tr_pos,True:0}[tr_pos is None]
    mt_pos = {False:mt_pos,True:0}[mt_pos is None]
    sc_pos = {False:sc_pos,True:0}[sc_pos is None]
    rt_pos = {False:rt_pos,True:0}[rt_pos is None]
    s = [tr_pos,mt_pos,sc_pos,rt_pos]
    def take0(x):
        return x[0]
    trnsfrms = [mtrx for pos,mtrx in sorted(zip(s,[tr,mt,sc,rt]),key =take0)]
    trnsfrms = [m for m in trnsfrms if not(m is None)]
    from numpy import dot
    from functools import reduce
    if len(trnsfrms) >= 1:
        mtrx = reduce(lambda x,y:dot(x,y.T),trnsfrms)
    return mtrx

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions