Creating an ellipsoid from a sphere with a transformation function applied

I am trying to create an ellipsoid by starting from a unit sphere and then apply a translation function to it. To find this translation function I compute the eigenvalues and vectors of the target ellipsoid and find the transformation function from those.
Let's say want an ellipsoid at
center = {0, 1, -1/2};
with a sigma matrix of
sigma = {{5, 2, 3}, {2, 3, 2}, {3, 2, 5}};
I then compute the eigenvalues and eigenvectors
{vals, vecs} = Eigensystem[N[sigma]]
{{9.274917217635364`, 1.9999999999999998`,1.7250827823646235`},
{{-0.6446445102792164`, -0.41093419270454856`, -0.6446445102792161`},
{-0.7071067811865479`, 1.5095665054549714`*^-15, 0.707106781186547`},
{0.29057435428280454`, -0.9116650093462296`, 0.2905743542828069`}}}

From this I get the transformation function
Composition[TranslationTransform[center],
AffineTransform[Transpose[vecs]], ScalingTransform[Sqrt[vals]]]
TransformationFunction[
{{-1.9632486597196646, -1., 0.38164735045449655, 0.},
{-1.2514897593880865, 0., -1.1974027652159263, 1.},
{-1.9632486597196637, 1., 0.38164735045449966, -0.5},
{0., 0., 0., 1.}}
]
I am confident that the above is correct, as it works in other software. Note that the last row is {0,0,0,1} which is required by BRepBuilderAPI_GTransform. Also, the last column is the center of the ellipsoid.
The following is then the c++ code:
------------------
#include
#include
#include
#include
#include

int main()
{
gp_Pnt origin = gp_Pnt(
(Standard_Real) 0.,
(Standard_Real) 0.,
(Standard_Real) 0.
);
Standard_Real radius = 1;
TopoDS_Shape s1 = BRepPrimAPI_MakeSphere(origin, radius).Shape();
gp_Trsf trsf;
trsf.SetValues (
(Standard_Real) -1.96325,
(Standard_Real) -1,
(Standard_Real) 0.381647,
(Standard_Real) 0.,

(Standard_Real) -1.25149,
(Standard_Real) 0.,
(Standard_Real) -1.1974,
(Standard_Real) 1.,

(Standard_Real) -1.96325,
(Standard_Real) 1.,
(Standard_Real) 0.381647,
(Standard_Real) -0.5
);
gp_GTrsf gtrsf(trsf);
TopoDS_Shape s2 = BRepBuilderAPI_GTransform(s1, gtrsf, Standard_True).Shape();
BRepMesh_IncrementalMesh Mesh( s2, 0.001);
Mesh.Perform();
StlAPI_Writer stl_writer;
stl_writer.Write(s2, "ellipsoid.stl");
return 0;
}

----------------------
If you look at the resulting ellipsoid.stl you will see that the object is distorted. Does anyone have an idea what causes this?

I compile the above code with:

g++ -I ~/ooc/build/include/opencascade -L ~/ooc/build/lin64/gcc/lib PROGRAM_NAME.cpp -lTKBin -lTKBinL -lTKBinTObj -lTKBinXCAF -lTKBO -lTKBool -lTKBRep -lTKCAF -lTKCDF -lTKDCAF -lTKDraw -lTKernel -lTKFeat -lTKFillet -lTKG2d -lTKG3d -lTKGeomAlgo -lTKGeomBase -lTKHLR -lTKIGES -lTKLCAF -lTKMath -lTKMesh -lTKMeshVS -lTKOffset -lTKOpenGl -lTKPrim -lTKQADraw -lTKRWMesh -lTKService -lTKShHealing -lTKStd -lTKStdL -lTKSTEP209 -lTKSTEP -lTKSTEPAttr -lTKSTEPBase -lTKSTL -lTKTObj -lTKTObjDRAW -lTKTopAlgo -lTKTopTest -lTKV3d -lTKVCAF -lTKViewerTest -lTKVRML -lTKXCAF -lTKXDEDRAW -lTKXDEIGES -lTKXDESTEP -lTKXMesh -lTKXml -lTKXmlL -lTKXmlTObj -lTKXmlXCAF -lTKXSBase -lTKXSDRAW

Kirill Gavrilov's picture

If you look at the resulting ellipsoid.stl you will see that the object is distorted.

Probably you have forgotten attaching generated STL file.

Oliver R's picture

Here it is. It seems a non-uniform scaling of {{fx,0,0,0},{0,fy,0,0},{0,0,fz,0},{0,0,0,1}} is at least part of the issue.

Attachments: