0

I have a trajectory which contains several frames of some 3D data, which looks like the following (I am posting the whole frame for the sake of reproducibilty of my problem):

data1=   [[ 89.29,  57.35 , 107.81999 ],
[ 91.37   ,   60.39 , 109.119995],
[ 89.130005 , 61.289997 , 112.12999 ],
[ 89.45    ,  57.729996 ,113.509995],
[ 93.149994 , 58.199997 ,114.20999 ],
[ 92.03999  , 61.21     ,116.44    ],
[ 89.48999  , 58.71     ,117.979996],
[ 92.42     , 56.399998 ,118.84    ],
[ 94.25     , 59.14     ,120.73999 ],
[ 91.44     , 59.62     ,123.28999 ],
[ 91.25     , 55.739998 ,124.      ],
[ 94.95     , 55.829998 ,124.67    ],
[ 94.36     , 58.699997 ,127.079994],
[ 91.5      , 57.05     ,129.05    ],
[ 93.16     , 53.57     ,129.28    ],
[ 96.36     , 55.35     ,130.5     ],
[ 94.15     , 57.53     ,133.      ],
[ 92.24     , 54.42     ,134.18    ],
[ 95.479996 , 52.35     ,134.88    ],
[ 96.81     , 55.429996 ,136.77    ],
[ 93.509995 , 55.73     ,138.76    ],
[ 94.06999  , 51.98     ,139.5     ],
[ 97.63     , 52.929996 ,140.72    ],
[ 96.08     , 55.72     ,142.92    ],
[ 93.63999  , 53.269997 ,144.65    ],
[ 96.149994 , 50.45     ,144.79999 ],
[ 99.10999  , 52.1      ,146.4     ],
[ 97.369995 , 54.16     ,149.      ],
[ 94.2      , 55.65     ,150.56    ]] 

I want to fit the line to my data. After checking answers of previous question (1), I borrowed/wrote the following code :

def Range(data):
   x=[]
   y=[]
   for i in range(0, len(data.T)):
       x.append(np.mean(data.T[i])- np.std(data.T[i]))
       y.append(np.mean(data.T[i]) + np.std(data.T[i]))
   normx,normy=np.linalg.norm(x),np.linalg.norm(y)
   minimum=normx-(normx+normy)/2
   maximum=normy-(normx+normy)/2
   return(minimum,maximum)

def axis(data):
  minimum,maximum=Range(data)
  datamean = data.mean(axis=0)
  uu, dd, vv = np.linalg.svd(data - datamean)
  linepts = vv[0] * np.mgrid[minimum:maximum:2j][:, np.newaxis]
  linepts += datamean
  return(linepts)

The value of vv[0] turns out to be [ 0.15970461,-0.17264067,0.9719515 ], which looks perfect for my further usage. However, for following the data :

 data2=  [ 90.993996 , 62.075    ,108.487   ],
   [ 88.036995 , 59.8525   ,109.3855  ],
   [ 90.5945   , 57.614998 ,111.061005],
   [ 92.17     , 60.6205   ,112.681496],
   [ 88.934006 , 61.622    ,114.4255  ],
   [ 88.077995 , 57.929    ,115.34    ],
   [ 91.642    , 57.3      ,116.81049 ],
   [ 91.431496 , 60.4655   ,118.813   ],
   [ 88.269    , 59.22     ,120.685   ],
   [ 89.883995 , 55.7975   ,121.2585  ],
   [ 93.115    , 57.497    ,122.68849 ],
   [ 91.090004 , 59.724    ,125.11    ],
   [ 89.355    , 56.712498 ,126.7305  ],
   [ 92.6985   , 54.758    ,126.52    ],
   [ 94.4685   , 57.383    ,128.4515  ],
   [ 91.9065   , 57.297997 ,131.2145  ],
   [ 91.99349  , 53.578995 ,131.1695  ],
   [ 95.752495 , 53.376   , 132.0325  ],
   [ 95.24799  , 55.990997, 134.80699 ],
   [ 92.29199  , 54.0455  , 136.277   ],
   [ 94.5055   , 50.9205  , 136.68399 ],
   [ 97.5085   , 52.947   , 137.85399 ],
   [ 95.353    , 54.6695  , 140.651   ],
   [ 94.194496 , 51.2645  , 141.4345  ],
   [ 97.6015   , 49.722   , 141.7245  ],
   [ 99.26149  , 52.813496 ,143.35449 ],
   [ 96.79849  , 53.233498, 146.2645  ],
   [ 96.237    , 49.554  ,  146.97299 ]]

The value of vv[0] turns out to be [-0.18894662 , 0.24432637,-0.9511066 ], which is in opposite sign from my expected result. I am unsure why it would produce such a result. Could anyone help me sort out this issue?

1 Fitting a line in 3D

Grayrigel
  • 3,474
  • 5
  • 14
  • 32
  • There is no guarantee for the direction of the eigenvectors, you can use different OS, numpy package, etc and get different results. How do you decide if the direction of the eigenvector is the way you want it or not? – anishtain4 Aug 10 '18 at 15:48
  • @anishtain4 Yes, that is exactly what I want. – Grayrigel Aug 10 '18 at 18:08
  • My question was "HOW do you decide if the direction should be flipped?" – anishtain4 Aug 10 '18 at 18:34
  • @anishtain4 Sorry. I don't decide it. I depend on it. I am using the output vector of SVD for an angle calculation wrt z-axis. This inconsistency in sign creates fluctuation in my angles. – Grayrigel Aug 13 '18 at 08:42
  • Then I think the best you can do is to align the eigenvectors with a direction relative to your data – anishtain4 Aug 13 '18 at 13:59

1 Answers1

0

The first principal component is a direction. Think of it as a line of infinite length. It doesn't matter if you flip this line, the direction remains the same.

In other words: the algorithm does not consider the order of the points that the object has travelled to. So for the algorithm, the object flying backwards through the points is just as valid as flying forwards.

Marijn van Vliet
  • 5,239
  • 2
  • 33
  • 45
  • @Marjin I sort of understand your point. However, I am using the output vector of SVD for an angle calculation wrt z-axis. This inconsistency in sign creates fluctuation in my angles. These angles are obviously not wrong but is it any way I can restrict output to be all same sign? – Grayrigel Aug 10 '18 at 13:27