Wed, 01/29/2020 - 09:43
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
Wed, 01/29/2020 - 10:49
Probably you have forgotten attaching generated STL file.
Wed, 01/29/2020 - 11:00
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.