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]);
541 const int &dimension) {
542 for(
int i = 0; i < dimension; ++i)
543 out[i] = b[i] - a[i];
549 const std::vector<T> &b,
550 std::vector<T> &out) {
551 out.resize(a.size());
557 for(
int i = 0; i < dimension; ++i)
558 out[i] = b[i] + a[i];
564 const std::vector<T> &b,
565 std::vector<T> &out) {
566 out.resize(a.size());
567 return addVectors(a.data(), b.data(), out.data(), a.size());
572 const std::vector<std::vector<T>> &b,
573 std::vector<std::vector<T>> &out) {
574 out.resize(a.size());
575 for(
unsigned int i = 0; i < a.size(); ++i)
582 const std::vector<std::vector<std::vector<T>>> &a,
583 const std::vector<std::vector<std::vector<T>>> &b,
584 std::vector<std::vector<T>> &out) {
585 std::vector<std::vector<T>> a_flatten, b_flatten;
596 const int &dimension) {
597 for(
int i = 0; i < dimension; ++i)
598 out[i] = a[i] * factor;
605 std::vector<T> &out) {
606 out.resize(a.size());
607 return scaleVector(a.data(), factor, out.data(), a.size());
614 const int &dimension) {
617 if(dotProdBB > PREC_DBL) {
619 dotProdAB /= dotProdBB;
622 for(
int i = 0; i < dimension; ++i)
623 out[i] = b[i] * dotProdAB;
629 const std::vector<T> &b,
630 std::vector<T> &out) {
631 out.resize(a.size(), 0.0);
637 const std::vector<T> &b,
638 std::vector<T> &a_out,
639 std::vector<T> &b_out) {
648 std::vector<std::vector<T>> &out) {
649 out.resize(a.size());
651 for(
unsigned int i = 1; i < a.size(); ++i) {
652 std::vector<T> projecSum;
654 for(
unsigned int j = 1; j < i; ++j) {
655 std::vector<T> projecTemp, projecSumTemp;
657 addVectors(projecSum, projecTemp, projecSumTemp);
658 projecSum = projecSumTemp;
666 for(
unsigned int i = 0; i < a.size() - 1; ++i)
667 if(not(std::abs(a[i] - a[i + 1]) < PREC_DBL))
674 for(
unsigned int i = 0; i < a.size(); ++i)
675 if(not(std::abs(a[i]) < PREC_DBL))
682 std::vector<T> a_flatten;
689 const std::vector<std::vector<T>> &a, std::vector<T> &out) {
690 out.resize(a.size() * a[0].size());
691 for(
unsigned int i = 0; i < a.size(); ++i)
692 for(
unsigned int j = 0; j < a[0].size(); ++j)
693 out[i * a[0].size() + j] = a[i][j];
699 const std::vector<std::vector<std::vector<T>>> &a,
700 std::vector<std::vector<T>> &out) {
701 out.resize(a.size());
702 for(
unsigned int i = 0; i < a.size(); ++i)
709 std::vector<std::vector<T>> &out,
710 const int &no_columns) {
711 if(a.size() % no_columns != 0)
713 out.resize(a.size() / no_columns);
714 for(
unsigned int i = 0; i < out.size(); ++i) {
715 out[i].resize(no_columns);
716 for(
unsigned int j = 0; j < out[i].size(); ++j)
717 out[i][j] = a[i * no_columns + j];
724 const std::vector<std::vector<T>> &b,
725 std::vector<std::vector<T>> &out) {
726 out.resize(a.size(), std::vector<T>(b[0].size(), 0.0));
727 for(
unsigned int i = 0; i < out.size(); ++i)
728 for(
unsigned int j = 0; j < out[i].size(); ++j)
729 for(
unsigned int k = 0; k < a[i].size(); ++k)
730 out[i][j] += a[i][k] * b[k][j];
735 const std::vector<std::vector<T>> &b,
736 std::vector<std::vector<T>> &out) {
737 out.resize(a.size(), std::vector<T>(a[0].size()));
738 for(
unsigned int i = 0; i < out.size(); ++i)
739 for(
unsigned int j = 0; j < out[0].size(); ++j)
740 out[i][j] = b[i][j] - a[i][j];
745 const std::vector<std::vector<T>> &b,
746 std::vector<std::vector<T>> &out) {
747 out.resize(a.size(), std::vector<T>(a[0].size()));
748 for(
unsigned int i = 0; i < a.size(); ++i)
749 for(
unsigned int j = 0; j < a[0].size(); ++j)
750 out[i][j] = a[i][j] + b[i][j];
756 std::vector<std::vector<T>> &out) {
757 out.resize(a.size(), std::vector<T>(a[0].size()));
758 for(
unsigned int i = 0; i < out.size(); ++i)
759 for(
unsigned int j = 0; j < out[i].size(); ++j)
760 out[i][j] = a[i][j] * factor;
765 std::vector<std::vector<T>> &out) {
766 out.resize(a[0].size(), std::vector<T>(a.size()));
767 for(
unsigned int i = 0; i < a.size(); ++i)
768 for(
unsigned int j = 0; j < a[0].size(); ++j)
772#define GEOMETRY_SPECIALIZE(TYPE) \
773 template TYPE Geometry::angle<TYPE>( \
774 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
775 template TYPE Geometry::angle2D<TYPE>( \
776 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
777 template bool Geometry::areVectorsColinear<TYPE>( \
778 TYPE const *, TYPE const *, TYPE const *, TYPE const *, \
779 std::array<TYPE, 3> *, TYPE const *); \
780 template bool Geometry::isTriangleColinear2D<TYPE>( \
781 TYPE const *, TYPE const *, TYPE const *, TYPE const); \
782 template int Geometry::computeBarycentricCoordinates<TYPE>( \
783 TYPE const *, TYPE const *, TYPE const *, std::array<TYPE, 2> &, \
785 template int Geometry::computeBarycentricCoordinates<TYPE>( \
786 TYPE const *, TYPE const *, TYPE const *, TYPE const *, \
787 std::array<TYPE, 3> &); \
788 template bool Geometry::computeSegmentIntersection<TYPE>( \
789 TYPE const &, TYPE const &, TYPE const &, TYPE const &, TYPE const &, \
790 TYPE const &, TYPE const &, TYPE const &, TYPE &, TYPE &); \
791 template int Geometry::computeTriangleAngles<TYPE>( \
792 TYPE const *, TYPE const *, TYPE const *, std::array<TYPE, 3> &); \
793 template int Geometry::computeTriangleAngleFromSides<TYPE>( \
794 TYPE const, TYPE const, TYPE const, TYPE &); \
795 template int Geometry::computeTriangleArea<TYPE>( \
796 TYPE const *, TYPE const *, TYPE const *, TYPE &); \
797 template int Geometry::computeTriangleAreaFromSides<TYPE>( \
798 TYPE const, TYPE const, TYPE const, TYPE &); \
799 template int Geometry::crossProduct<TYPE>(TYPE const *, TYPE const *, \
800 TYPE const *, TYPE const *, \
801 std::array<TYPE, 3> &); \
802 template int Geometry::crossProduct<TYPE>( \
803 TYPE const *, TYPE const *, TYPE *); \
804 template TYPE Geometry::distance<TYPE>( \
805 TYPE const *, TYPE const *, int const &); \
806 template TYPE Geometry::distance<TYPE>( \
807 std::vector<TYPE> const &, std::vector<TYPE> const &); \
808 template TYPE Geometry::distanceFlatten<TYPE>( \
809 std::vector<std::vector<TYPE>> const &, \
810 std::vector<std::vector<TYPE>> const &); \
811 template TYPE Geometry::dotProduct<TYPE>( \
812 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
813 template TYPE Geometry::dotProduct<TYPE>( \
814 TYPE const *, TYPE const *, int const &); \
815 template TYPE Geometry::dotProduct<TYPE>( \
816 std::vector<TYPE> const &, std::vector<TYPE> const &); \
817 template TYPE Geometry::dotProductFlatten<TYPE>( \
818 std::vector<std::vector<TYPE>> const &, \
819 std::vector<std::vector<TYPE>> const &); \
820 template bool Geometry::isPointInTriangle<TYPE>( \
821 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
822 template bool Geometry::isPointOnSegment<TYPE>(TYPE const &, TYPE const &, \
823 TYPE const &, TYPE const &, \
824 TYPE const &, TYPE const &); \
825 template bool Geometry::isPointOnSegment<TYPE>( \
826 TYPE const *, TYPE const *, TYPE const *, int const &); \
827 template bool Geometry::isTriangleColinear<TYPE>( \
828 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
829 template TYPE Geometry::magnitude<TYPE>(TYPE const *, int const &); \
830 template TYPE Geometry::magnitude<TYPE>(std::vector<TYPE> const &); \
831 template TYPE Geometry::magnitudeFlatten<TYPE>( \
832 std::vector<std::vector<TYPE>> const &); \
833 template TYPE Geometry::magnitude<TYPE>(TYPE const *, TYPE const *); \
834 template int Geometry::subtractVectors<TYPE>( \
835 TYPE const *, TYPE const *, TYPE *, int const &); \
836 template int Geometry::subtractVectors<TYPE>(std::vector<TYPE> const &, \
837 std::vector<TYPE> const &, \
838 std::vector<TYPE> &); \
839 template int Geometry::addVectors<TYPE>( \
840 TYPE const *, TYPE const *, TYPE *, int const &); \
841 template int Geometry::addVectors<TYPE>(std::vector<TYPE> const &, \
842 std::vector<TYPE> const &, \
843 std::vector<TYPE> &); \
844 template int Geometry::multiAddVectors<TYPE>( \
845 std::vector<std::vector<TYPE>> const &, \
846 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
847 template int Geometry::multiAddVectorsFlatten<TYPE>( \
848 std::vector<std::vector<std::vector<TYPE>>> const &, \
849 std::vector<std::vector<std::vector<TYPE>>> const &, \
850 std::vector<std::vector<TYPE>> &); \
851 template int Geometry::scaleVector<TYPE>( \
852 TYPE const *, TYPE const, TYPE *, int const &); \
853 template int Geometry::scaleVector<TYPE>( \
854 std::vector<TYPE> const &, TYPE const, std::vector<TYPE> &); \
855 template int Geometry::vectorProjection<TYPE>( \
856 TYPE const *, TYPE const *, TYPE *, int const &); \
857 template int Geometry::vectorProjection<TYPE>(std::vector<TYPE> const &, \
858 std::vector<TYPE> const &, \
859 std::vector<TYPE> &); \
860 template void Geometry::addVectorsProjection<TYPE>( \
861 std::vector<TYPE> const &, std::vector<TYPE> const &, std::vector<TYPE> &, \
862 std::vector<TYPE> &); \
863 template void Geometry::gramSchmidt<TYPE>( \
864 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
865 template bool Geometry::isVectorUniform<TYPE>(std::vector<TYPE> const &); \
866 template bool Geometry::isVectorNull<TYPE>(std::vector<TYPE> const &); \
867 template bool Geometry::isVectorNullFlatten<TYPE>( \
868 std::vector<std::vector<TYPE>> const &); \
869 template int Geometry::flattenMultiDimensionalVector<TYPE>( \
870 std::vector<std::vector<TYPE>> const &, std::vector<TYPE> &); \
871 template int Geometry::multiFlattenMultiDimensionalVector<TYPE>( \
872 std::vector<std::vector<std::vector<TYPE>>> const &, \
873 std::vector<std::vector<TYPE>> &); \
874 template int Geometry::unflattenMultiDimensionalVector<TYPE>( \
875 std::vector<TYPE> const &, std::vector<std::vector<TYPE>> &, int const &); \
876 template void Geometry::matrixMultiplication<TYPE>( \
877 std::vector<std::vector<TYPE>> const &, \
878 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
879 template void Geometry::subtractMatrices<TYPE>( \
880 std::vector<std::vector<TYPE>> const &, \
881 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
882 template void Geometry::addMatrices<TYPE>( \
883 std::vector<std::vector<TYPE>> const &, \
884 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
885 template void Geometry::scaleMatrix<TYPE>( \
886 std::vector<std::vector<TYPE>> const &, TYPE const, \
887 std::vector<std::vector<TYPE>> &); \
888 template void Geometry::transposeMatrix<TYPE>( \
889 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)
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 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)
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)