plaindev
plaindev

Reputation: 131

how do i transform between a static and a dynamic coordinate system

i have a setup like this:

enter image description here

2 coordinate systems. (x,y) is the main coordinate system and (x',y') is a coordinate system that lives inside (x,y). The system (x',y') is defined by the points x1 or x2 and if i move these 2 points around then (x',y') moves accordingly. The origin of (x',y') is defined as the middle of the vector going from x1 to x2, and the y' axis is the normal vector on x1->x2 going through the origin. If i have a point x3 defined in (x',y') and i move either of x1 or x2 to make the origin shift place, how do i then move x3 accordingly such that it maintains its position in the new (x',y') ? And how do i make a transformation which always converts a point in (x,y) to a point in (x',y') nomatter how x1 and x2 have been set?

I was thinking that if i had more points than just the one i am moving (x1 or x2) i guess i could try to estimate theta, tx, ty of the transformation

[x2']   [cos(theta) , sin(theta), tx][x2]
[y2'] = [-sin(theta), cos(theta), ty][y2]
[ 1 ]   [    0      ,      0    , 1 ][1 ]

and just apply that estimated transformation to x3 and i would be good...mmm but i think i would need 3 points in order to estimate theta, tx and ty right? I mean i could estimate using some least squares approach...but 3 unknowns requires 3 coordinate sets right?

I tried to implement this and calculate an example. I hope you understand the syntax. Its not really giving me what i expect:

import math
import numpy as np

x1=[ 0,10]
x2=[10,20]

rx = x2[0] - x1[0]
ry = x2[1] - x1[1]
rlen = math.sqrt(rx*rx+ry*ry)
c = rx / rlen
s = ry / rlen


dx = - ( x1[0] + x2[0] )/2 # changing the sign to be negative seems to 
dy = - ( x1[1] + x2[1] )/2 # rectify translation. Rotation still is wrong

M = np.array([[c, -s, 0],[s, c, 0],[dx, dy, 1]])
print( np.dot(x2 + [1],M) )
# Yields -> [ 15.92031022  -8.63603897   1.        ] and should yield [5,0,1]

Since I am trying to transform the x2 coordinate, should the result then not have the value 0 in the y-component since its located in the x-axis?

Ok, I tried doing the implementation for x3 from dynamic1 to dynamic2 which the check is that x3 should end up with the same coordinate in both d1 and d2. I did that as you suggested, but I do not get the same coordinate in both d1 and d2. Did i misunderstand something?

import math
import numpy as np

x1=[ 1,1]
x2=[ 7,9]

x3=[4,3]

rx = (x2[0] - x1[0])
ry = (x2[1] - x1[1])
rlen = math.sqrt( rx*rx + ry*ry )
c = rx / rlen
s = ry / rlen


dx =  ( x1[0] + x2[0] )/2
dy =  ( x1[1] + x2[1] )/2

M = np.array([[c, -s, 0],[s, c, 0],[-dx*c-dy*s, dx*s-dy*c, 1]])
Minv = np.array([[c, s, 0],[-s, c, 0],[dx, dy, 1]])


x1new=[ 1,1]
x2new=[ 17,4]

rxnew = (x2new[0] - x1new[0])
rynew = (x2new[1] - x1new[1])
rlennew = math.sqrt( rxnew*rxnew + rynew*rynew )
cnew = rxnew / rlennew
snew = rynew / rlennew


dxnew =  ( x1new[0] + x2new[0] )/2
dynew =  ( x1new[1] + x2new[1] )/2

Mnew = np.array([[cnew, -snew, 0],[snew, cnew, 0],[-dxnew*cnew-dynew*snew, dxnew*snew-dynew*cnew, 1]])
Mnewinv = np.array([[cnew, snew, 0],[-snew, cnew, 0],[dxnew, dynew, 1]])

M_dyn1_to_dyn2 = np.dot(Minv,Mnew)

print( np.dot(x3 + [1], M) )
print( np.dot(x3 + [1], M_dyn1_to_dyn2))
#yields these 2 outputs which should be the same:
[-1.6 -1.2  1. ]
[-3.53219692  8.29298408  1.        ]

Upvotes: 1

Views: 1098

Answers (2)

MBo
MBo

Reputation: 80187

Edit. Matrix correction.

To translate coordinates from static system to (x1,x2) defined one, you have to apply affine transformation. Matrix of this transformation M consists of shift matrix S and rotation about origin R.

Matrix M is combination of S and R:

      c            -s          0
M =   s             c          0
      -dx*c-dy*s   dx*s-dy*c   1

Here c and s are cosine and sine of rotation angle, their values are respectively x- and y- components of unit (normalized) vector x1x2.

rx = x2.x - x1.x
ry = x2.y - x1.y
len = Sqrt(rx*rx+ry*ry)
c = rx / Len
s = ry / Len

And shift components:

dx = (x1.x + x2.x)/2
dy = (x1.y + x2.y)/2

To translate (xx,yy) coordinates from static system to rotate one, we have to find

xx' = xx*c+yy*s-dx*c-dy*s =   c*(xx-dx) + s*(yy-dy)
yy' = -xx*s+yy*c+dx*s-dy*c = -s*(xx-dx) + c*(yy-dy)

Quick check:

X1 = (1,1)
X2 = (7,9) 
dx = 4
dy = 5
rx = 6
ry = 8
Len = 10
c = 0.6
s = 0.8

for point (4,5):
xx-dx = 0
yy-dy = 0
xx',yy' = (0, 0) - right

for point X2 =(7,9):
xx-dx = 3
yy-dy = 4
xx' = 0.6*3 + 0.8*4 = 5   -right
yy' = -0.8*3 + 0.6*4 = 0  -right

P.S. Note that matrix to transform dyn.coordinates to static ones is inverse of M and it is simpler:

       c   s   0
 M' =  -s  c   0
       dx  dy  1  

P.P.S. You need three pairs of corresponding points to define general affine transformations. It seems here you don't need scaling and sheer, so you may determine needed transform with your x1,x2 points

Upvotes: 1

keronconk
keronconk

Reputation: 359

I think you need double dimension array to save and set your value in that

the structure gonna be like this

    =============|========|========|
    index number |x       |y       |
    =============|========|========|
    first point  | [0][0] | [0][1] |    
    second point | [1][0] | [1][1] |                            
    third point  | [2][0] | [2][1] |                            
    =============|========|========|

I will use java in my answer

    //declare the double dimension array
    double matrix[][] = new double[3][2];

    //setting location first point, x
    matrix[0][0] = 1;
    //setting location first point, y
    matrix[0][1] = 1;

    //fill with your formula, i only give example
    //fill second point with first point and plus 1
    //setting location second point, x
    matrix[1][0] = matrix[0][0] + 1;
    //setting location second point, y
    matrix[1][1] = matrix[0][1] + 1;

    //fill with your formula, i only give example
    //fill third point with second point and plus 1
    //setting location third point, x
    matrix[2][0] = matrix[1][0] + 1;
    //setting location third point, y
    matrix[2][1] = matrix[1][1] + 1;

Upvotes: 0

Related Questions