-//================================================================================
-/*!
- * \brief Subdivides a triangle until it reaches a certain size (recursive function)
- */
-//================================================================================
-void HexoticPlugin_Hexotic::subdivideTriangle( const gp_Pnt& p1,
- const gp_Pnt& p2,
- const gp_Pnt& p3,
- const double& theSize,
- std::vector<Control_Pnt>& thePoints)
-{
- // Size threshold to stop subdividing
- // This value ensures that two control points are distant no more than 2*theSize
- // as shown below
- //
- // The greater distance D of the mass center M to each Edge is 1/3 * Median
- // and Median < sqrt(3/4) * a where a is the greater side (by using Apollonius' thorem).
- // So D < 1/3 * sqrt(3/4) * a and if a < sqrt(3) * S then D < S/2
- // and the distance between two mass centers of two neighbouring triangles
- // sharing an edge is < 2 * 1/2 * S = S
- // If the traingles share a Vertex and no Edge the distance of the mass centers
- // to the Vertices is 2*D < S so the mass centers are distant of less than 2*S
-
- double threshold = sqrt( 3. ) * theSize;
-
- if ( (p1.Distance(p2) > threshold ||
- p2.Distance(p3) > threshold ||
- p3.Distance(p1) > threshold))
- {
- std::vector<gp_Pnt> midPoints = computePointsForSplitting(p1, p2, p3);
-
- subdivideTriangle( midPoints[0], midPoints[1], midPoints[2], theSize, thePoints );
- subdivideTriangle( midPoints[0], p2, midPoints[1], theSize, thePoints );
- subdivideTriangle( midPoints[2], midPoints[1], p3, theSize, thePoints );
- subdivideTriangle( p1, midPoints[0], midPoints[2], theSize, thePoints );
- }
- else
- {
- double x = (p1.X() + p2.X() + p3.X()) / 3 ;
- double y = (p1.Y() + p2.Y() + p3.Y()) / 3 ;
- double z = (p1.Z() + p2.Z() + p3.Z()) / 3 ;
-
- Control_Pnt massCenter( x ,y ,z, theSize );
- thePoints.push_back( massCenter );
- }
-}
-
-//================================================================================
-/*!
- * \brief Returns the appropriate points for splitting a triangle
- * \brief the tangency points of the incircle are used in order to have mostly
- * \brief well-shaped sub-triangles
- */
-//================================================================================
-std::vector<gp_Pnt> HexoticPlugin_Hexotic::computePointsForSplitting( const gp_Pnt& p1,
- const gp_Pnt& p2,
- const gp_Pnt& p3 )
-{
- std::vector<gp_Pnt> midPoints;
- //Change coordinates
- gp_Trsf Trsf_1; // Identity transformation
- gp_Ax3 reference_system(gp::Origin(), gp::DZ(), gp::DX()); // OXY
-
- gp_Vec Vx(p1, p3);
- gp_Vec Vaux(p1, p2);
- gp_Dir Dx(Vx);
- gp_Dir Daux(Vaux);
- gp_Dir Dz = Dx.Crossed(Daux);
- gp_Ax3 current_system(p1, Dz, Dx);
-
- Trsf_1.SetTransformation( reference_system, current_system );
-
- gp_Pnt A = p1.Transformed(Trsf_1);
- gp_Pnt B = p2.Transformed(Trsf_1);
- gp_Pnt C = p3.Transformed(Trsf_1);
-
- double a = B.Distance(C) ;
- double b = A.Distance(C) ;
- double c = B.Distance(A) ;
-
- // Incenter coordinates
- // see http://mathworld.wolfram.com/Incenter.html
- double Xi = ( b*B.X() + c*C.X() ) / ( a + b + c );
- double Yi = ( b*B.Y() ) / ( a + b + c );
- gp_Pnt Center(Xi, Yi, 0);
-
- // Calculate the tangency points of the incircle
- gp_Pnt T1 = tangencyPoint( A, B, Center);
- gp_Pnt T2 = tangencyPoint( B, C, Center);
- gp_Pnt T3 = tangencyPoint( C, A, Center);
-
- gp_Pnt p1_2 = T1.Transformed(Trsf_1.Inverted());
- gp_Pnt p2_3 = T2.Transformed(Trsf_1.Inverted());
- gp_Pnt p3_1 = T3.Transformed(Trsf_1.Inverted());