Convert between 2 coordinate systems

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
Chris_G
Veteran
Posts: 2602
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Convert between 2 coordinate systems

Post by Chris_G »

Hi,
I have a point P(x,y,z).
I would like to get its coordinates expressed into another orthonormal coordinate system (a_point,v1,v2,v3)
Are there any buit-in functions for going back and forth between 2 coordinate systems ?
Thanks,
Chris
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Convert between 2 coordinate systems

Post by DeepSOIC »

Yes, Placement defines a coordinate system, and supports converting points to/from.
The only thing that seems to be missing is a constructor for placement that takes axis vectors as input. For that, in Lattice, I wrote up a routine. Feel free to reuse it.

Code: Select all

def makeOrientationFromLocalAxes(ZAx, XAx = None):
    '''
    makeOrientationFromLocalAxes(ZAx, XAx): constructs App.Rotation to get into 
    alignment with given local Z and X axes. Z axis is followed strictly; X axis
    is a guide and can be not strictly perpendicular to Z axis; it will be 
    corrected and modified

    '''    
    if XAx is None:
        XAx = App.Vector(0,0,1) #Why Z? Because I prefer local X axis to be aligned so that local XZ plane is parallel to global Z axis.
    #First, compute all three axes.
    ZAx.normalize() #just to be sure; it's important to have the matrix normalized
    YAx = ZAx.cross(XAx) # construct Y axis
    ParaConfusion = 1e-9
    if YAx.Length < ParaConfusion*10.0:
        #failed, try some other X axis direction hint
        XAx = App.Vector(0,0,1)
        YAx = ZAx.cross(XAx)
        if YAx.Length < ParaConfusion*10.0:
            #failed again. Now, we can tell, that local Z axis is along global
            # Z axis
            XAx = App.Vector(1,0,0)
            YAx = ZAx.cross(XAx)
        
    YAx.normalize()
    XAx = YAx.cross(ZAx) # force X perpendicular
    
    #hacky way of constucting rotation to a local coordinate system: 
    # make matrix,
    m = App.Matrix()
    m.A = list(XAx)+[0.0]+list(YAx)+[0.0]+list(ZAx)+[0.0]+[0.0]*3+[1.0]
    m.transpose() # local axes vectors are columns of matrix, but we put them in as rwos, because it is convenient, and then transpose it.
    # make placement out of matrix,
    tmpplm = App.Placement(m)
    # and extract rotation from placement. 
    ori = tmpplm.Rotation
    return ori

def makeOrientationFromLocalAxesUni(priorityString, XAx = None, YAx = None, ZAx = None):
    '''
    makeOrientationFromLocalAxesUni(priorityString, XAx = None, YAx = None, ZAx = None): 
    constructs App.Rotation to get into alignment with given local axes. 
    Priority string is a string like "ZXY", which defines how axes are made 
    perpendicular. For example, "ZXY" means that Z is followed strictly, X is 
    made to be perpendicular to Z, and Y is completely ignored (a new one will 
    be computed from X and Z). The strict axis must be specified, all other are 
    optional.
    '''
    # see Lattice (lattice2GeomUtils.py) for actual code, it's quite long
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Convert between 2 coordinate systems

Post by DeepSOIC »

You can also use App.Matrix if you are dealing with left-handed coordinate systems (these are not covered by placements)
User avatar
Chris_G
Veteran
Posts: 2602
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Convert between 2 coordinate systems

Post by Chris_G »

Thanks DeepSOIC,
I'll have a look at that and hope I will understand :lol:
Post Reply