Re: Problem using PrincipalComponents to rotate 3D model data
- To: mathgroup at smc.vnet.net
- Subject: [mg80907] Re: Problem using PrincipalComponents to rotate 3D model data
- From: Yaroslav Bulatov <yaroslavvb at gmail.com>
- Date: Wed, 5 Sep 2007 02:54:03 -0400 (EDT)
- References: <fbj2t7$nk0$1@smc.vnet.net><fbjcv6$6cl$1@smc.vnet.net>
I have ran across this problem before. As the previous poster points out, there's inherent ambiguity in the direction of principle components, which are eigenvectors of the covariance matrix. An ad hoc solution is to use singular vectors instead of eigenvectors. It's ad hoc because the documentation doesn't say specify how SingularValueDecomposition selects the direction of singular vectors when there's ambiguity. However, it seems to be more stable, and from simulation below you can see that eigenvectors (black) flip back and forth as data is rotated, while singular vectors (red) stay in one place sample[\[Theta]_] := Module[{}, covmat = SetPrecision[ RotationMatrix[-\[Theta], {1, 1, 1}].DiagonalMatrix[{10, 5, 1}].RotationMatrix[\[Theta], {1, 1, 1}], 10]; RandomReal[MultinormalDistribution[{0, 0, 0}, covmat], 150] ]; chart[\[Theta]_] := Module[{}, points = sample[\[Theta]]; covmat = Transpose[points].points; eves = Eigenvectors[covmat]; g1 = Graphics3D[(Point[#] & /@ points), PlotRange -> 5]; g2 = Graphics3D[(Line[{{0, 0, 0}, 5 #}] & /@ eves)]; svd = SingularValueDecomposition[covmat]; sves = Transpose[svd[[1]]]; g3 = Graphics3D[{Red, (Line[{{0, 0, 0}, 3 #}] & /@ sves)}]; Show[g1, g2, g3] ]; Manipulate[chart[\[Theta]], {\[Theta], 0, Pi/2}] To apply this method you could try the code below SingularComponents[m_?MatrixQ] := Module[{covmat}, covmat = Transpose[m].m; sves = Transpose[SingularValueDecomposition[covmat][[1]]]; sves.# & /@ m ] model = Import["ExampleData/spikey.stl"] RotatedModel = Graphics3D[{EdgeForm[], Polygon[Partition[ SingularComponents[Flatten[model[[1, 2, 1]], 1]], 3]]}, Boxed -> False]; Note that this won't resolve jittering when the covariance matrix has degenerate eigenvalues. That happens when any linear combination of two principal components is itself a principal component. In that case, there's an extra level of ambiguity, and you'd need to add extra information to make the problem of finding principal axes well-posed On Sep 4, 3:44 am, Antti Penttil=E4 wrote: > Will, > > Principal components, or the principal vectors can be reversed > (mirrored) and still be valid principal vectors. If (j,k,l) are the > principal vectors, then (-j,-k,-l) or any other combination is also > possible. > > Antti > > will wrote: > > Dear Math Forum, > > > I am using PrincipalComponents[] (in Mathematica 6) to perform a rotati= on operation on some 3D data (effectively to align my data so that the maxi= mum length of my models runs down the x axis,the maximum width down the y a= xis, and height max on the z axis). > > However, i have noticed that mathematica repeatedly reverses the normal= (flips inside out) of and/or mirrors my models. I find this very odd, and = was wondering if anyone else had encountered this problem? it seems to happ= en consistently with certain models, but i cannot see what is different in = these models to those (few) that work as they should. if this problem is to= do with my data, > > can anyone think of a way to rotate the models not using > > PrincipalComponents[]. > > > below is the code i have been using on STL (3D points and surface polyg= on data). > > > Needs["MultivariateStatistics`"]; > > > 3Dmodel = Import["3Dmodel.stl"]; > > > Rotated3Dmodel = > > Graphics3D[{EdgeForm[], > > Polygon[Partition[ > > PrincipalComponents[Flatten[3Dmodel[[1, 2, 1]], 1]], 3]]}, > > Boxed -> False]; > > > Export["Rotated3Dmodel.stl", Rotated3Dmodel]; > > > thank you, > > > William