Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2007
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2007

[Date Index] [Thread Index] [Author Index]

Search the Archive

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




  • Prev by Date: Re: Kernel and frontend crash with ANY Graphics3D objects
  • Next by Date: Slow Show/Graphics in v6.0
  • Previous by thread: Re: Problem using PrincipalComponents to rotate 3D model data
  • Next by thread: Re: ===$MaxMachineNumber}