9static const float PREC_FLT{powf(10.0F, -FLT_DIG)};
10static const float PREC_FLT_1{powf(10.0F, -FLT_DIG + 1)};
21 double vecA[2] = {vA1[0] - vA0[0], vA1[1] - vA0[1]};
22 double vecB[2] = {vB1[0] - vB0[0], vB1[1] - vB0[1]};
23 return atan2(vecB[1], vecB[0]) - atan2(vecA[1], vecA[0]);
31 std::array<T, 3> *coefficients,
34 int aNullComponents = 0, bNullComponents = 0;
35 std::array<T, 3> a{}, b{};
36 for(
int i = 0; i < 3; i++) {
37 a[i] = vA1[i] - vA0[i];
38 if(fabs(a[i]) < PREC_FLT) {
41 b[i] = vB1[i] - vB0[i];
42 if(fabs(b[i]) < PREC_FLT) {
47 if((aNullComponents == 3) || (bNullComponents == 3)) {
52 if((aNullComponents > 1) || (bNullComponents > 1)) {
53 if(aNullComponents == bNullComponents) {
59 bool useDenominatorA =
false;
61 for(
int i = 0; i < 3; i++) {
66 useDenominatorA =
true;
72 int isNan = -1, maximizer = 0;
73 for(
int i = 0; i < 3; i++) {
75 if(fabs(a[i]) > PREC_FLT) {
81 if(fabs(b[i]) > PREC_FLT) {
89 maxDenominator = fabs(k[i]);
92 if(fabs(k[i]) > maxDenominator) {
93 maxDenominator = fabs(k[i]);
99 T colinearityThreshold;
101 colinearityThreshold = PREC_FLT;
103 colinearityThreshold = *tolerance;
112 if((fabs(1 - fabs(k[(maximizer + 1) % 3] / k[maximizer]))
113 < colinearityThreshold)
114 && (fabs(1 - fabs(k[(maximizer + 2) % 3] / k[maximizer]))
115 < colinearityThreshold)) {
119 if(fabs(1 - fabs(k[(isNan + 1) % 3] / k[(isNan + 2) % 3]))
120 < colinearityThreshold) {
124 k[0] = k[1] = k[2] = 0;
134 double ptA[2] = {pptA[0], pptA[1]}, ptB[2] = {pptB[0], pptB[1]},
135 ptC[2] = {pptC[0], pptC[1]};
136 return fabs(ptA[0] * (ptB[1] - ptC[1]) + ptB[0] * (ptC[1] - ptA[1])
137 + ptC[0] * (ptA[1] - ptB[1]))
145 std::array<T, 2> &baryCentrics,
146 const int &dimension) {
153 T maxDenominator = 0;
155 for(
int i = 0; i < dimension; i++) {
157 T denominator = fabs(p0[i] - p1[i]);
159 maxDenominator = denominator;
162 if(denominator > maxDenominator) {
163 maxDenominator = denominator;
169 baryCentrics[0] = p0[bestI] - p1[bestI];
170 baryCentrics[0] = (p[bestI] - p1[bestI]) / baryCentrics[0];
172 baryCentrics[1] = 1 - baryCentrics[0];
175 std::array<T, 3> test{};
176 for(
int i = 0; i < dimension; i++) {
177 test[i] = baryCentrics[0] * p0[i] + baryCentrics[1] * p1[i];
180 if((!((fabs(test[0] - p[0]) < PREC_FLT_1)
181 && (fabs(test[1] - p[1]) < PREC_FLT_1)))) {
182 for(
int i = 0; i < 2; i++) {
183 baryCentrics[i] = -baryCentrics[i];
194 std::array<T, 3> &baryCentrics) {
198 int bestI = 0, bestJ = 1;
199 T maxDenominator = 0;
201 for(
int i = 0; i < 2; i++) {
202 for(
int j = i + 1; j < 3; j++) {
205 = (p1[j] - p2[j]) * (p0[i] - p2[i]) + (p2[i] - p1[i]) * (p0[j] - p2[j]);
207 = (p1[j] - p2[j]) * (p0[i] - p2[i]) + (p2[i] - p1[i]) * (p0[j] - p2[j]);
209 T denominator = fabs(baryCentrics[0]);
211 if(fabs(baryCentrics[1]) < denominator) {
212 denominator = fabs(baryCentrics[1]);
215 if((i == 0) && (j == 1)) {
216 maxDenominator = denominator;
218 if(denominator > maxDenominator) {
219 maxDenominator = denominator;
227 baryCentrics[0] = (p1[bestJ] - p2[bestJ]) * (p0[bestI] - p2[bestI])
228 + (p2[bestI] - p1[bestI]) * (p0[bestJ] - p2[bestJ]);
230 baryCentrics[0] = ((p1[bestJ] - p2[bestJ]) * (p[bestI] - p2[bestI])
231 + (p2[bestI] - p1[bestI]) * (p[bestJ] - p2[bestJ]))
235 baryCentrics[1] = (p1[bestJ] - p2[bestJ]) * (p0[bestI] - p2[bestI])
236 + (p2[bestI] - p1[bestI]) * (p0[bestJ] - p2[bestJ]);
238 baryCentrics[1] = ((p2[bestJ] - p0[bestJ]) * (p[bestI] - p2[bestI])
239 + (p0[bestI] - p2[bestI]) * (p[bestJ] - p2[bestJ]))
242 baryCentrics[2] = 1 - baryCentrics[0] - baryCentrics[1];
259 T d = (xA - xB) * (yC - yD) - (yA - yB) * (xC - xD);
261 if(fabs(d) < PREC_DBL) {
265 x = ((xC - xD) * (xA * yB - yA * xB) - (xA - xB) * (xC * yD - yC * xD)) / d;
267 y = ((yC - yD) * (xA * yB - yA * xB) - (yA - yB) * (xC * yD - yC * xD)) / d;
269 if((x < std::min(xA, xB) - PREC_FLT) || (x > std::max(xA, xB) + PREC_FLT)) {
273 if((x < std::min(xC, xD) - PREC_FLT) || (x > std::max(xC, xD) + PREC_FLT)) {
286 std::array<T, 3> cross{};
301 double const s = (s0 + s1 + s2) / 2.0;
302 area = std::sqrt(s * (s - s0) * (s - s1) * (s - s2));
311 std::array<T, 3> &angles) {
313 angles[0] =
angle(p0, p1, p1, p2);
314 angles[1] =
angle(p1, p2, p2, p0);
315 angles[2] =
angle(p2, p0, p0, p1);
326 angle = std::acos((s0 * s0 + s1 * s1 - s2 * s2) / (2.0 * s0 * s1));
336 std::array<T, 3> &crossProduct) {
338 std::array<T, 3> a{}, b{};
340 for(
int i = 0; i < 3; i++) {
341 a[i] = vA1[i] - vA0[i];
342 b[i] = vB1[i] - vB0[i];
345 for(
int i = 0; i < 3; i++) {
347 = a[(i + 1) % 3] * b[(i + 2) % 3] - a[(i + 2) % 3] * b[(i + 1) % 3];
366 for(
int i = 0; i < dimension; i++) {
367 distance += (p0[i] - p1[i]) * (p0[i] - p1[i]);
375 return distance(p0.data(), p1.data(), p0.size());
380 const std::vector<std::vector<T>> &p1) {
381 std::vector<T> p0_flatten, p1_flatten;
384 return distance(p0_flatten, p1_flatten);
391 for(
int i = 0; i < 3; i++) {
392 dotProduct += (vA1[i] - vA0[i]) * (vB1[i] - vB0[i]);
401 for(
int i = 0; i < dimension; ++i)
408 return dotProduct(vA.data(), vB.data(), vA.size());
413 const std::vector<std::vector<T>> &vB) {
414 std::vector<T> vA_flatten, vB_flatten;
426 std::array<T, 3> barycentrics{};
430 for(
int i = 0; i < static_cast<int>(barycentrics.size()); i++) {
431 if(barycentrics[i] < -PREC_DBL) {
434 if(barycentrics[i] > 1 + PREC_DBL) {
444 const T &x,
const T &y,
const T &xA,
const T &yA,
const T &xB,
const T &yB) {
446 std::array<T, 2> pA{xA, yA}, pB{xB, yB}, p{x, y};
454 const int &dimension) {
456 std::array<T, 2> baryCentrics{};
461 ((baryCentrics[0] > -PREC_DBL) && (baryCentrics[0] < 1 + PREC_DBL))
462 && ((baryCentrics[1] > -PREC_DBL) && (baryCentrics[1] < 1 + PREC_DBL)));
469 const T *tolerance) {
471 bool maxDecision =
false;
472 T maxCoefficient = 0;
473 std::array<T, 3> coefficients{};
476 maxDecision = decision;
477 for(
int i = 0; i < 3; i++) {
479 maxCoefficient = fabs(coefficients[i]);
480 maxDecision = decision;
482 if(fabs(coefficients[i]) > maxCoefficient) {
483 maxCoefficient = fabs(coefficients[i]);
484 maxDecision = decision;
490 for(
int i = 0; i < 3; i++) {
491 if(fabs(coefficients[i]) > maxCoefficient) {
492 maxCoefficient = fabs(coefficients[i]);
493 maxDecision = decision;
498 for(
int i = 0; i < 3; i++) {
499 if(fabs(coefficients[i]) > maxCoefficient) {
500 maxCoefficient = fabs(coefficients[i]);
501 maxDecision = decision;
520 std::vector<T> v_flatten;
530 for(
int i = 0; i < 3; i++) {
531 mag += (o[i] - d[i]) * (o[i] - d[i]);
542 std::array<T, 3> ap{};
544 std::array<T, 3> normTriScaled{};
551 std::array<T, 3> ab{};
553 std::array<T, 3> ap{};
555 std::array<T, 3> abScaled{};
571 std::array<T, 3> ab{};
573 std::array<T, 3> ac{};
580 if(mag > powf(10, -FLT_DIG)) {
595 const int &dimension) {
596 for(
int i = 0; i < dimension; ++i)
597 out[i] = b[i] - a[i];
603 const std::vector<T> &b,
604 std::vector<T> &out) {
605 out.resize(a.size());
611 for(
int i = 0; i < dimension; ++i)
612 out[i] = b[i] + a[i];
618 const std::vector<T> &b,
619 std::vector<T> &out) {
620 out.resize(a.size());
621 return addVectors(a.data(), b.data(), out.data(), a.size());
626 const std::vector<std::vector<T>> &b,
627 std::vector<std::vector<T>> &out) {
628 out.resize(a.size());
629 for(
unsigned int i = 0; i < a.size(); ++i)
636 const std::vector<std::vector<std::vector<T>>> &a,
637 const std::vector<std::vector<std::vector<T>>> &b,
638 std::vector<std::vector<T>> &out) {
639 std::vector<std::vector<T>> a_flatten, b_flatten;
650 const int &dimension) {
651 for(
int i = 0; i < dimension; ++i)
652 out[i] = a[i] * factor;
659 std::vector<T> &out) {
660 out.resize(a.size());
661 return scaleVector(a.data(), factor, out.data(), a.size());
668 const int &dimension) {
671 if(dotProdBB > PREC_DBL) {
673 dotProdAB /= dotProdBB;
676 for(
int i = 0; i < dimension; ++i)
677 out[i] = b[i] * dotProdAB;
683 const std::vector<T> &b,
684 std::vector<T> &out) {
685 out.resize(a.size(), 0.0);
691 const std::vector<T> &b,
692 std::vector<T> &a_out,
693 std::vector<T> &b_out) {
702 std::vector<std::vector<T>> &out) {
703 out.resize(a.size());
705 for(
unsigned int i = 1; i < a.size(); ++i) {
706 std::vector<T> projecSum;
708 for(
unsigned int j = 1; j < i; ++j) {
709 std::vector<T> projecTemp, projecSumTemp;
711 addVectors(projecSum, projecTemp, projecSumTemp);
712 projecSum = projecSumTemp;
720 for(
unsigned int i = 0; i < a.size() - 1; ++i)
721 if(not(std::abs(a[i] - a[i + 1]) < PREC_DBL))
728 for(
unsigned int i = 0; i < a.size(); ++i)
729 if(not(std::abs(a[i]) < PREC_DBL))
736 std::vector<T> a_flatten;
743 const std::vector<std::vector<T>> &a, std::vector<T> &out) {
744 out.resize(a.size() * a[0].size());
745 for(
unsigned int i = 0; i < a.size(); ++i)
746 for(
unsigned int j = 0; j < a[0].size(); ++j)
747 out[i * a[0].size() + j] = a[i][j];
753 const std::vector<std::vector<std::vector<T>>> &a,
754 std::vector<std::vector<T>> &out) {
755 out.resize(a.size());
756 for(
unsigned int i = 0; i < a.size(); ++i)
763 std::vector<std::vector<T>> &out,
764 const int &no_columns) {
765 if(a.size() % no_columns != 0)
767 out.resize(a.size() / no_columns);
768 for(
unsigned int i = 0; i < out.size(); ++i) {
769 out[i].resize(no_columns);
770 for(
unsigned int j = 0; j < out[i].size(); ++j)
771 out[i][j] = a[i * no_columns + j];
778 const std::vector<std::vector<T>> &b,
779 std::vector<std::vector<T>> &out) {
780 out.resize(a.size(), std::vector<T>(b[0].size(), 0.0));
781 for(
unsigned int i = 0; i < out.size(); ++i)
782 for(
unsigned int j = 0; j < out[i].size(); ++j)
783 for(
unsigned int k = 0; k < a[i].size(); ++k)
784 out[i][j] += a[i][k] * b[k][j];
789 const std::vector<std::vector<T>> &b,
790 std::vector<std::vector<T>> &out) {
791 out.resize(a.size(), std::vector<T>(a[0].size()));
792 for(
unsigned int i = 0; i < out.size(); ++i)
793 for(
unsigned int j = 0; j < out[0].size(); ++j)
794 out[i][j] = b[i][j] - a[i][j];
799 const std::vector<std::vector<T>> &b,
800 std::vector<std::vector<T>> &out) {
801 out.resize(a.size(), std::vector<T>(a[0].size()));
802 for(
unsigned int i = 0; i < a.size(); ++i)
803 for(
unsigned int j = 0; j < a[0].size(); ++j)
804 out[i][j] = a[i][j] + b[i][j];
810 std::vector<std::vector<T>> &out) {
811 out.resize(a.size(), std::vector<T>(a[0].size()));
812 for(
unsigned int i = 0; i < out.size(); ++i)
813 for(
unsigned int j = 0; j < out[i].size(); ++j)
814 out[i][j] = a[i][j] * factor;
819 std::vector<std::vector<T>> &out) {
820 out.resize(a[0].size(), std::vector<T>(a.size()));
821 for(
unsigned int i = 0; i < a.size(); ++i)
822 for(
unsigned int j = 0; j < a[0].size(); ++j)
826#define GEOMETRY_SPECIALIZE(TYPE) \
827 template TYPE Geometry::angle<TYPE>( \
828 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
829 template TYPE Geometry::angle2D<TYPE>( \
830 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
831 template bool Geometry::areVectorsColinear<TYPE>( \
832 TYPE const *, TYPE const *, TYPE const *, TYPE const *, \
833 std::array<TYPE, 3> *, TYPE const *); \
834 template bool Geometry::isTriangleColinear2D<TYPE>( \
835 TYPE const *, TYPE const *, TYPE const *, TYPE const); \
836 template int Geometry::computeBarycentricCoordinates<TYPE>( \
837 TYPE const *, TYPE const *, TYPE const *, std::array<TYPE, 2> &, \
839 template int Geometry::computeBarycentricCoordinates<TYPE>( \
840 TYPE const *, TYPE const *, TYPE const *, TYPE const *, \
841 std::array<TYPE, 3> &); \
842 template bool Geometry::computeSegmentIntersection<TYPE>( \
843 TYPE const &, TYPE const &, TYPE const &, TYPE const &, TYPE const &, \
844 TYPE const &, TYPE const &, TYPE const &, TYPE &, TYPE &); \
845 template int Geometry::computeTriangleAngles<TYPE>( \
846 TYPE const *, TYPE const *, TYPE const *, std::array<TYPE, 3> &); \
847 template int Geometry::computeTriangleAngleFromSides<TYPE>( \
848 TYPE const, TYPE const, TYPE const, TYPE &); \
849 template int Geometry::computeTriangleArea<TYPE>( \
850 TYPE const *, TYPE const *, TYPE const *, TYPE &); \
851 template int Geometry::computeTriangleAreaFromSides<TYPE>( \
852 TYPE const, TYPE const, TYPE const, TYPE &); \
853 template int Geometry::crossProduct<TYPE>(TYPE const *, TYPE const *, \
854 TYPE const *, TYPE const *, \
855 std::array<TYPE, 3> &); \
856 template int Geometry::crossProduct<TYPE>( \
857 TYPE const *, TYPE const *, TYPE *); \
858 template TYPE Geometry::distance<TYPE>( \
859 TYPE const *, TYPE const *, int const &); \
860 template TYPE Geometry::distance<TYPE>( \
861 std::vector<TYPE> const &, std::vector<TYPE> const &); \
862 template TYPE Geometry::distanceFlatten<TYPE>( \
863 std::vector<std::vector<TYPE>> const &, \
864 std::vector<std::vector<TYPE>> const &); \
865 template TYPE Geometry::dotProduct<TYPE>( \
866 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
867 template TYPE Geometry::dotProduct<TYPE>( \
868 TYPE const *, TYPE const *, int const &); \
869 template TYPE Geometry::dotProduct<TYPE>( \
870 std::vector<TYPE> const &, std::vector<TYPE> const &); \
871 template TYPE Geometry::dotProductFlatten<TYPE>( \
872 std::vector<std::vector<TYPE>> const &, \
873 std::vector<std::vector<TYPE>> const &); \
874 template bool Geometry::isPointInTriangle<TYPE>( \
875 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
876 template bool Geometry::isPointOnSegment<TYPE>(TYPE const &, TYPE const &, \
877 TYPE const &, TYPE const &, \
878 TYPE const &, TYPE const &); \
879 template bool Geometry::isPointOnSegment<TYPE>( \
880 TYPE const *, TYPE const *, TYPE const *, int const &); \
881 template bool Geometry::isTriangleColinear<TYPE>( \
882 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
883 template TYPE Geometry::magnitude<TYPE>(TYPE const *, int const &); \
884 template TYPE Geometry::magnitude<TYPE>(std::vector<TYPE> const &); \
885 template TYPE Geometry::magnitudeFlatten<TYPE>( \
886 std::vector<std::vector<TYPE>> const &); \
887 template TYPE Geometry::magnitude<TYPE>(TYPE const *, TYPE const *); \
888 template void Geometry::projectOnTrianglePlane<TYPE>( \
889 TYPE const *, TYPE const *, TYPE const *, TYPE *); \
890 template void Geometry::projectOnEdge<TYPE>( \
891 TYPE const *, TYPE const *, TYPE const *, TYPE *); \
892 template void Geometry::computeTriangleNormal<TYPE>( \
893 TYPE const *, TYPE const *, TYPE const *, TYPE *); \
894 template int Geometry::subtractVectors<TYPE>( \
895 TYPE const *, TYPE const *, TYPE *, int const &); \
896 template int Geometry::subtractVectors<TYPE>(std::vector<TYPE> const &, \
897 std::vector<TYPE> const &, \
898 std::vector<TYPE> &); \
899 template int Geometry::addVectors<TYPE>( \
900 TYPE const *, TYPE const *, TYPE *, int const &); \
901 template int Geometry::addVectors<TYPE>(std::vector<TYPE> const &, \
902 std::vector<TYPE> const &, \
903 std::vector<TYPE> &); \
904 template int Geometry::multiAddVectors<TYPE>( \
905 std::vector<std::vector<TYPE>> const &, \
906 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
907 template int Geometry::multiAddVectorsFlatten<TYPE>( \
908 std::vector<std::vector<std::vector<TYPE>>> const &, \
909 std::vector<std::vector<std::vector<TYPE>>> const &, \
910 std::vector<std::vector<TYPE>> &); \
911 template int Geometry::scaleVector<TYPE>( \
912 TYPE const *, TYPE const, TYPE *, int const &); \
913 template int Geometry::scaleVector<TYPE>( \
914 std::vector<TYPE> const &, TYPE const, std::vector<TYPE> &); \
915 template int Geometry::vectorProjection<TYPE>( \
916 TYPE const *, TYPE const *, TYPE *, int const &); \
917 template int Geometry::vectorProjection<TYPE>(std::vector<TYPE> const &, \
918 std::vector<TYPE> const &, \
919 std::vector<TYPE> &); \
920 template void Geometry::addVectorsProjection<TYPE>( \
921 std::vector<TYPE> const &, std::vector<TYPE> const &, std::vector<TYPE> &, \
922 std::vector<TYPE> &); \
923 template void Geometry::gramSchmidt<TYPE>( \
924 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
925 template bool Geometry::isVectorUniform<TYPE>(std::vector<TYPE> const &); \
926 template bool Geometry::isVectorNull<TYPE>(std::vector<TYPE> const &); \
927 template bool Geometry::isVectorNullFlatten<TYPE>( \
928 std::vector<std::vector<TYPE>> const &); \
929 template int Geometry::flattenMultiDimensionalVector<TYPE>( \
930 std::vector<std::vector<TYPE>> const &, std::vector<TYPE> &); \
931 template int Geometry::multiFlattenMultiDimensionalVector<TYPE>( \
932 std::vector<std::vector<std::vector<TYPE>>> const &, \
933 std::vector<std::vector<TYPE>> &); \
934 template int Geometry::unflattenMultiDimensionalVector<TYPE>( \
935 std::vector<TYPE> const &, std::vector<std::vector<TYPE>> &, int const &); \
936 template void Geometry::matrixMultiplication<TYPE>( \
937 std::vector<std::vector<TYPE>> const &, \
938 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
939 template void Geometry::subtractMatrices<TYPE>( \
940 std::vector<std::vector<TYPE>> const &, \
941 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
942 template void Geometry::addMatrices<TYPE>( \
943 std::vector<std::vector<TYPE>> const &, \
944 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
945 template void Geometry::scaleMatrix<TYPE>( \
946 std::vector<std::vector<TYPE>> const &, TYPE const, \
947 std::vector<std::vector<TYPE>> &); \
948 template void Geometry::transposeMatrix<TYPE>( \
949 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &);
#define GEOMETRY_SPECIALIZE(TYPE)
int scaleVector(const T *a, const T factor, T *out, const int &dimension=3)
bool areVectorsColinear(const T *vA0, const T *vA1, const T *vB0, const T *vB1, std::array< T, 3 > *coefficients=nullptr, const T *tolerance=NULL)
int computeTriangleArea(const T *p0, const T *p1, const T *p2, T &area)
int addVectors(const T *a, const T *b, T *out, const int &dimension=3)
void projectOnEdge(const T *p, const T *a, const T *b, T *out)
Compute euclidean projection on a 3D segment.
T dotProductFlatten(const std::vector< std::vector< T > > &vA, const std::vector< std::vector< T > > &vB)
int multiFlattenMultiDimensionalVector(const std::vector< std::vector< std::vector< T > > > &a, std::vector< std::vector< T > > &out)
void subtractMatrices(const std::vector< std::vector< T > > &a, const std::vector< std::vector< T > > &b, std::vector< std::vector< T > > &out)
bool isTriangleColinear2D(const T *pptA, const T *pptB, const T *pptC, const T tolerance)
T dotProduct(const T *vA0, const T *vA1, const T *vB0, const T *vB1)
void matrixMultiplication(const std::vector< std::vector< T > > &a, const std::vector< std::vector< T > > &b, std::vector< std::vector< T > > &out)
bool isVectorNullFlatten(const std::vector< std::vector< T > > &a)
bool isPointOnSegment(const T &x, const T &y, const T &xA, const T &yA, const T &xB, const T &yB)
bool computeSegmentIntersection(const T &xA, const T &yA, const T &xB, const T &yB, const T &xC, const T &yC, const T &xD, const T &yD, T &x, T &y)
int computeBarycentricCoordinates(const T *p0, const T *p1, const T *p, std::array< T, 2 > &baryCentrics, const int &dimension=3)
void projectOnTrianglePlane(const T *p, const T *a, const T *normTri, T *out)
Compute euclidean projection in a triangle plane.
void addMatrices(const std::vector< std::vector< T > > &a, const std::vector< std::vector< T > > &b, std::vector< std::vector< T > > &out)
void gramSchmidt(const std::vector< std::vector< T > > &a, std::vector< std::vector< T > > &out)
void scaleMatrix(const std::vector< std::vector< T > > &a, const T factor, std::vector< std::vector< T > > &out)
int multiAddVectors(const std::vector< std::vector< T > > &a, const std::vector< std::vector< T > > &b, std::vector< std::vector< T > > &out)
int flattenMultiDimensionalVector(const std::vector< std::vector< T > > &a, std::vector< T > &out)
bool isVectorUniform(const std::vector< T > &a)
int subtractVectors(const T *a, const T *b, T *out, const int &dimension=3)
int computeTriangleAreaFromSides(const T s0, const T s1, const T s2, T &area)
T magnitudeFlatten(const std::vector< std::vector< T > > &v)
bool isVectorNull(const std::vector< T > &a)
void computeTriangleNormal(const T *a, const T *b, const T *c, T *out)
Compute normal vector to triangle.
T1 pow(const T1 val, const T2 n)
bool isTriangleColinear(const T *p0, const T *p1, const T *p2, const T *tolerance=nullptr)
T angle(const T *vA0, const T *vA1, const T *vB0, const T *vB1)
void addVectorsProjection(const std::vector< T > &a, const std::vector< T > &b, std::vector< T > &a_out, std::vector< T > &b_out)
int computeTriangleAngles(const T *p0, const T *p1, const T *p2, std::array< T, 3 > &angles)
int computeTriangleAngleFromSides(const T s0, const T s1, const T s2, T &angle)
int vectorProjection(const T *a, const T *b, T *out, const int &dimension=3)
int crossProduct(const T *vA0, const T *vA1, const T *vB0, const T *vB1, std::array< T, 3 > &crossProduct)
void transposeMatrix(const std::vector< std::vector< T > > &a, std::vector< std::vector< T > > &out)
int unflattenMultiDimensionalVector(const std::vector< T > &a, std::vector< std::vector< T > > &out, const int &no_columns=2)
T magnitude(const T *v, const int &dimension=3)
T distance(const T *p0, const T *p1, const int &dimension=3)
T angle2D(const T *vA0, const T *vA1, const T *vB0, const T *vB1)
T distanceFlatten(const std::vector< std::vector< T > > &p0, const std::vector< std::vector< T > > &p1)
int multiAddVectorsFlatten(const std::vector< std::vector< std::vector< T > > > &a, const std::vector< std::vector< std::vector< T > > > &b, std::vector< std::vector< T > > &out)
bool isPointInTriangle(const T *p0, const T *p1, const T *p2, const T *p)