#include "VolSurfUser.hxx"
#include "InterpKernelAutoPtr.hxx"
#include "InterpolationUtils.hxx"
+#include "VectorUtils.hxx"
#include <cmath>
#include <limits>
matrix[11]=-p0[0]*matrix[8]-p0[1]*matrix[9]-p0[2]*matrix[10];
return true;
}
-}
+ template<int SPACEDIM>
+ void ComputeTriangleHeight(const double *PA, const double *PB, const double *PC, double *res)
+ {
+ double AB = getDistanceBtw2Pts<SPACEDIM>(PA,PB);
+ double BC = getDistanceBtw2Pts<SPACEDIM>(PB,PC);
+ double CA = getDistanceBtw2Pts<SPACEDIM>(PC,PA);
+ double perim( (AB+BC+CA)*0.5 );
+ double num( 2*sqrt(perim*(perim-AB)*(perim-BC)*(perim-CA)) );
+ res[0] = num/AB; res[1] = num/BC; res[2] = num/CA;
+ }
+}
double INTERPKERNEL_EXPORT DistanceFromPtToPolygonInSpaceDim3(const double *pt, const mcIdType *connOfPolygonBg, const mcIdType *connOfPolygonEnd, const double *coords);
bool ComputeRotTranslationMatrixToPut3PointsOnOXY(const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3, double *matrix);
+
+ template<int SPACEDIM>
+ void ComputeTriangleHeight(const double *PA, const double *PB, const double *PC, double *res);
}
#endif
#include "DiameterCalculator.hxx"
#include "OrientationInverter.hxx"
#include "InterpKernelAutoPtr.hxx"
+#include "VolSurfUser.cxx"
using namespace MEDCoupling;
return ret.retn();
}
+/*!
+ * This method for each cell in \a this the triangle height for each edge in a newly allocated/created array instance.
+ *
+ * \return DataArrayDouble * - a newly allocated instance with this->getNumberOfCells() tuples and 3 components storing for each cell in \a this the corresponding height.
+ * \throw If \a this is not a mesh containing only NORM_TRI3 cells.
+ * \throw If \a this is not properly allocated.
+ * \throw If spaceDimension is not in 2 or 3.
+ */
+MCAuto<DataArrayDouble> MEDCoupling1SGTUMesh::computeTriangleHeight() const
+{
+ checkConsistencyLight();
+ const INTERP_KERNEL::CellModel& cm(getCellModel());
+ if(cm.getEnum()!=INTERP_KERNEL::NORM_TRI3)
+ THROW_IK_EXCEPTION("MEDCoupling1SGTUMesh::computeTriangleHeight : this method can be applied only on TRI3 mesh !");
+ MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
+ mcIdType nbTri3( getNumberOfCells() );
+ const double *coordPtr( this->getCoords()->begin() );
+ const mcIdType *inConnPtr(getNodalConnectivity()->begin());
+ ret->alloc(nbTri3,3);
+ double *retPtr( ret->getPointer() );
+ switch( this->getSpaceDimension())
+ {
+ case 2:
+ {
+ constexpr unsigned SPACEDIM = 2;
+ for(mcIdType iCell = 0 ; iCell < nbTri3 ; ++iCell)
+ {
+ INTERP_KERNEL::ComputeTriangleHeight<SPACEDIM>(coordPtr + SPACEDIM*inConnPtr[3*iCell+0], coordPtr + SPACEDIM*inConnPtr[3*iCell+1], coordPtr + SPACEDIM*inConnPtr[3*iCell+2],retPtr+3*iCell);
+ }
+ break;
+ }
+ case 3:
+ {
+ constexpr unsigned SPACEDIM = 3;
+ for(mcIdType iCell = 0 ; iCell < nbTri3 ; ++iCell)
+ {
+ INTERP_KERNEL::ComputeTriangleHeight<SPACEDIM>(coordPtr + SPACEDIM*inConnPtr[3*iCell+0], coordPtr + SPACEDIM*inConnPtr[3*iCell+1], coordPtr + SPACEDIM*inConnPtr[3*iCell+2],retPtr+3*iCell);
+ }
+ break;
+ }
+ default:
+ THROW_IK_EXCEPTION("MEDCoupling1SGTUMesh::computeTriangleHeight : only spacedim in [2,3] supported !");
+ }
+ return ret;
+}
+
/*!
* This method starts from an unstructured mesh that hides in reality a cartesian mesh.
* If it is not the case, an exception will be thrown.
MEDCOUPLING_EXPORT MEDCoupling1GTUMesh *computeDualMesh() const;
MEDCOUPLING_EXPORT DataArrayIdType *sortHexa8EachOther();
MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *explodeEachHexa8To6Quad4() const;
+ MEDCOUPLING_EXPORT MCAuto<DataArrayDouble> computeTriangleHeight() const;
MEDCOUPLING_EXPORT MEDCouplingCMesh *structurizeMe(DataArrayIdType *& cellPerm, DataArrayIdType *& nodePerm, double eps=1e-12) const;
public://serialization
MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<mcIdType>& tinyInfo, std::vector<std::string>& littleStrings) const;
return ret;
}
-/*!
- * Computes the maximal value within every tuple of \a this array.
- * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
- * same number of tuples as \a this array and one component.
- * The caller is to delete this result array using decrRef() as it is no more
- * needed.
- * \throw If \a this is not allocated.
- * \sa DataArrayDouble::maxPerTupleWithCompoId
- */
-DataArrayDouble *DataArrayDouble::maxPerTuple() const
+DataArrayDouble *DataArrayDouble::operatePerTuple(std::function<double(const double *bg, const double *endd)> func) const
{
checkAllocated();
std::size_t nbOfComp(getNumberOfComponents());
const double *src=getConstPointer();
double *dest=ret->getPointer();
for(mcIdType i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
- *dest=*std::max_element(src,src+nbOfComp);
+ *dest=func(src,src+nbOfComp);
return ret.retn();
}
+/*!
+ * Computes the maximal value within every tuple of \a this array.
+ * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
+ * same number of tuples as \a this array and one component.
+ * The caller is to delete this result array using decrRef() as it is no more
+ * needed.
+ * \throw If \a this is not allocated.
+ * \sa DataArrayDouble::maxPerTupleWithCompoId, DataArrayDouble::minPerTuple
+ */
+DataArrayDouble *DataArrayDouble::maxPerTuple() const
+{
+ return this->operatePerTuple([](const double *bg, const double *endd) { return *std::max_element(bg,endd); });
+}
+
+/*!
+ * Computes the minimal value within every tuple of \a this array.
+ * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
+ * same number of tuples as \a this array and one component.
+ * The caller is to delete this result array using decrRef() as it is no more
+ * needed.
+ * \throw If \a this is not allocated.
+ * \sa DataArrayDouble::maxPerTuple
+ */
+DataArrayDouble *DataArrayDouble::minPerTuple() const
+{
+ return this->operatePerTuple([](const double *bg, const double *endd) { return *std::min_element(bg,endd); });
+}
+
/*!
* Computes the maximal value within every tuple of \a this array and it returns the first component
* id for each tuple that corresponds to the maximal value within the tuple.
#include <string>
#include <vector>
#include <iterator>
+#include <functional>
namespace MEDCoupling
{
DataArrayDouble *trace() const;
DataArrayDouble *deviator() const;
DataArrayDouble *magnitude() const;
+ DataArrayDouble *minPerTuple() const;
DataArrayDouble *maxPerTuple() const;
DataArrayDouble *maxPerTupleWithCompoId(DataArrayIdType* &compoIdOfMaxPerTuple) const;
DataArrayDouble *buildEuclidianDistanceDenseMatrix() const;
template<int SPACEDIM>
static void FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,mcIdType>& myTree, const double *pos, mcIdType nbOfTuples, double eps,
DataArrayIdType *c, DataArrayIdType *cI);
+ private:
+ DataArrayDouble *operatePerTuple(std::function<double(const double *bg, const double *endd)> func) const;
private:
~DataArrayDouble() { }
DataArrayDouble() { }
delta_Z.abs()
self.assertTrue(delta_Z.findIdsNotInRange(-1e-5,+1e-5).empty())
+ def testComputeTriangleHeight0(self):
+ arr = DataArrayDouble([0,1])
+ m = MEDCouplingCMesh() ; m.setCoords(arr,arr)
+ m = m.buildUnstructured() ; m.simplexize(0) ; m = MEDCoupling1SGTUMesh(m)
+ res = m.computeTriangleHeight()
+ expected = DataArrayDouble([(1.0, 1.0, sqrt(2)/2.0), (sqrt(2)/2.0, 1.0, 1.0)])
+ self.assertTrue( res.isEqual(expected,1e-12) )
+ m.changeSpaceDimension(3,100)
+ res2 = m.computeTriangleHeight()
+ self.assertTrue( res2.isEqual(expected,1e-12) )
+ expected2 = DataArrayDouble([sqrt(2)/2.0, sqrt(2)/2.0])
+ self.assertTrue( res2.minPerTuple().isEqual(expected2,1e-12) )
+
pass
if __name__ == '__main__':
%newobject MEDCoupling::MEDCoupling1SGTUMesh::buildSetInstanceFromThis;
%newobject MEDCoupling::MEDCoupling1SGTUMesh::computeDualMesh;
%newobject MEDCoupling::MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4;
+%newobject MEDCoupling::MEDCoupling1SGTUMesh::computeTriangleHeight;
%newobject MEDCoupling::MEDCoupling1SGTUMesh::sortHexa8EachOther;
%newobject MEDCoupling::MEDCoupling1SGTUMesh::Merge1SGTUMeshes;
%newobject MEDCoupling::MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords;
return ret;
}
+ DataArrayDouble *MEDCoupling1SGTUMesh::computeTriangleHeight() const
+ {
+ MCAuto<DataArrayDouble> ret = self->computeTriangleHeight();
+ return ret.retn();
+ }
+
static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(PyObject *li)
{
std::vector<const MEDCoupling::MEDCoupling1SGTUMesh *> tmp;
%newobject MEDCoupling::DataArrayDouble::deviator;
%newobject MEDCoupling::DataArrayDouble::magnitude;
%newobject MEDCoupling::DataArrayDouble::maxPerTuple;
+%newobject MEDCoupling::DataArrayDouble::minPerTuple;
%newobject MEDCoupling::DataArrayDouble::sumPerTuple;
%newobject MEDCoupling::DataArrayDouble::computeBBoxPerTuple;
%newobject MEDCoupling::DataArrayDouble::buildEuclidianDistanceDenseMatrix;
DataArrayDouble *deviator() const;
DataArrayDouble *magnitude() const;
DataArrayDouble *maxPerTuple() const;
+ DataArrayDouble *minPerTuple() const;
DataArrayDouble *sumPerTuple() const;
DataArrayDouble *buildEuclidianDistanceDenseMatrix() const;
DataArrayDouble *buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const;