9static const float PREC_FLT{powf(10.0F, -FLT_DIG)};
10static const float PREC_FLT_1{powf(10.0F, -FLT_DIG + 1)};
24 std::array<T, 3> *coefficients,
27 int aNullComponents = 0, bNullComponents = 0;
28 std::array<T, 3> a{}, b{};
29 for(
int i = 0; i < 3; i++) {
30 a[i] = vA1[i] - vA0[i];
31 if(fabs(a[i]) < PREC_FLT) {
34 b[i] = vB1[i] - vB0[i];
35 if(fabs(b[i]) < PREC_FLT) {
40 if((aNullComponents == 3) || (bNullComponents == 3)) {
45 if((aNullComponents > 1) || (bNullComponents > 1)) {
46 if(aNullComponents == bNullComponents) {
52 bool useDenominatorA =
false;
54 for(
int i = 0; i < 3; i++) {
59 useDenominatorA =
true;
65 int isNan = -1, maximizer = 0;
66 for(
int i = 0; i < 3; i++) {
68 if(fabs(a[i]) > PREC_FLT) {
74 if(fabs(b[i]) > PREC_FLT) {
82 maxDenominator = fabs(k[i]);
85 if(fabs(k[i]) > maxDenominator) {
86 maxDenominator = fabs(k[i]);
92 T colinearityThreshold;
94 colinearityThreshold = PREC_FLT;
96 colinearityThreshold = *tolerance;
105 if((fabs(1 - fabs(k[(maximizer + 1) % 3] / k[maximizer]))
106 < colinearityThreshold)
107 && (fabs(1 - fabs(k[(maximizer + 2) % 3] / k[maximizer]))
108 < colinearityThreshold)) {
112 if(fabs(1 - fabs(k[(isNan + 1) % 3] / k[(isNan + 2) % 3]))
113 < colinearityThreshold) {
118 k[0] = k[1] = k[2] = 0;
127 std::array<T, 2> &baryCentrics,
128 const int &dimension) {
135 T maxDenominator = 0;
137 for(
int i = 0; i < dimension; i++) {
139 T denominator = fabs(p0[i] - p1[i]);
141 maxDenominator = denominator;
144 if(denominator > maxDenominator) {
145 maxDenominator = denominator;
151 baryCentrics[0] = p0[bestI] - p1[bestI];
152 baryCentrics[0] = (p[bestI] - p1[bestI]) / baryCentrics[0];
154 baryCentrics[1] = 1 - baryCentrics[0];
157 std::array<T, 3> test{};
158 for(
int i = 0; i < dimension; i++) {
159 test[i] = baryCentrics[0] * p0[i] + baryCentrics[1] * p1[i];
162 if((!((fabs(test[0] - p[0]) < PREC_FLT_1)
163 && (fabs(test[1] - p[1]) < PREC_FLT_1)))) {
164 for(
int i = 0; i < 2; i++) {
165 baryCentrics[i] = -baryCentrics[i];
176 std::array<T, 3> &baryCentrics) {
180 int bestI = 0, bestJ = 1;
181 T maxDenominator = 0;
183 for(
int i = 0; i < 2; i++) {
184 for(
int j = i + 1; j < 3; j++) {
187 = (p1[j] - p2[j]) * (p0[i] - p2[i]) + (p2[i] - p1[i]) * (p0[j] - p2[j]);
189 = (p1[j] - p2[j]) * (p0[i] - p2[i]) + (p2[i] - p1[i]) * (p0[j] - p2[j]);
191 T denominator = fabs(baryCentrics[0]);
193 if(fabs(baryCentrics[1]) < denominator) {
194 denominator = fabs(baryCentrics[1]);
197 if((i == 0) && (j == 1)) {
198 maxDenominator = denominator;
200 if(denominator > maxDenominator) {
201 maxDenominator = denominator;
209 baryCentrics[0] = (p1[bestJ] - p2[bestJ]) * (p0[bestI] - p2[bestI])
210 + (p2[bestI] - p1[bestI]) * (p0[bestJ] - p2[bestJ]);
212 baryCentrics[0] = ((p1[bestJ] - p2[bestJ]) * (p[bestI] - p2[bestI])
213 + (p2[bestI] - p1[bestI]) * (p[bestJ] - p2[bestJ]))
217 baryCentrics[1] = (p1[bestJ] - p2[bestJ]) * (p0[bestI] - p2[bestI])
218 + (p2[bestI] - p1[bestI]) * (p0[bestJ] - p2[bestJ]);
220 baryCentrics[1] = ((p2[bestJ] - p0[bestJ]) * (p[bestI] - p2[bestI])
221 + (p0[bestI] - p2[bestI]) * (p[bestJ] - p2[bestJ]))
224 baryCentrics[2] = 1 - baryCentrics[0] - baryCentrics[1];
241 T d = (xA - xB) * (yC - yD) - (yA - yB) * (xC - xD);
243 if(fabs(d) < PREC_DBL) {
247 x = ((xC - xD) * (xA * yB - yA * xB) - (xA - xB) * (xC * yD - yC * xD)) / d;
249 y = ((yC - yD) * (xA * yB - yA * xB) - (yA - yB) * (xC * yD - yC * xD)) / d;
251 if((x < std::min(xA, xB) - PREC_FLT) || (x > std::max(xA, xB) + PREC_FLT)) {
255 if((x < std::min(xC, xD) - PREC_FLT) || (x > std::max(xC, xD) + PREC_FLT)) {
268 std::array<T, 3> cross{};
283 double s = (s0 + s1 + s2) / 2.0;
284 area = std::sqrt(s * (s - s0) * (s - s1) * (s - s2));
293 std::array<T, 3> &angles) {
295 angles[0] =
angle(p0, p1, p1, p2);
296 angles[1] =
angle(p1, p2, p2, p0);
297 angles[2] =
angle(p2, p0, p0, p1);
308 angle = std::acos((s0 * s0 + s1 * s1 - s2 * s2) / (2.0 * s0 * s1));
318 std::array<T, 3> &crossProduct) {
320 std::array<T, 3> a{}, b{};
322 for(
int i = 0; i < 3; i++) {
323 a[i] = vA1[i] - vA0[i];
324 b[i] = vB1[i] - vB0[i];
327 for(
int i = 0; i < 3; i++) {
329 = a[(i + 1) % 3] * b[(i + 2) % 3] - a[(i + 2) % 3] * b[(i + 1) % 3];
348 for(
int i = 0; i < dimension; i++) {
349 distance += (p0[i] - p1[i]) * (p0[i] - p1[i]);
357 return distance(p0.data(), p1.data(), p0.size());
362 const std::vector<std::vector<T>> &p1) {
363 std::vector<T> p0_flatten, p1_flatten;
366 return distance(p0_flatten, p1_flatten);
373 for(
int i = 0; i < 3; i++) {
374 dotProduct += (vA1[i] - vA0[i]) * (vB1[i] - vB0[i]);
383 for(
int i = 0; i < dimension; ++i)
390 return dotProduct(vA.data(), vB.data(), vA.size());
395 const std::vector<std::vector<T>> &vB) {
396 std::vector<T> vA_flatten, vB_flatten;
408 std::array<T, 3> barycentrics{};
412 for(
int i = 0; i < static_cast<int>(barycentrics.size()); i++) {
413 if(barycentrics[i] < -PREC_DBL) {
416 if(barycentrics[i] > 1 + PREC_DBL) {
426 const T &x,
const T &y,
const T &xA,
const T &yA,
const T &xB,
const T &yB) {
428 std::array<T, 2> pA{xA, yA}, pB{xB, yB}, p{x, y};
436 const int &dimension) {
438 std::array<T, 2> baryCentrics{};
443 ((baryCentrics[0] > -PREC_DBL) && (baryCentrics[0] < 1 + PREC_DBL))
444 && ((baryCentrics[1] > -PREC_DBL) && (baryCentrics[1] < 1 + PREC_DBL)));
451 const T *tolerance) {
453 bool maxDecision =
false;
454 T maxCoefficient = 0;
455 std::array<T, 3> coefficients{};
458 maxDecision = decision;
459 for(
int i = 0; i < 3; i++) {
461 maxCoefficient = fabs(coefficients[i]);
462 maxDecision = decision;
464 if(fabs(coefficients[i]) > maxCoefficient) {
465 maxCoefficient = fabs(coefficients[i]);
466 maxDecision = decision;
472 for(
int i = 0; i < 3; i++) {
473 if(fabs(coefficients[i]) > maxCoefficient) {
474 maxCoefficient = fabs(coefficients[i]);
475 maxDecision = decision;
480 for(
int i = 0; i < 3; i++) {
481 if(fabs(coefficients[i]) > maxCoefficient) {
482 maxCoefficient = fabs(coefficients[i]);
483 maxDecision = decision;
502 std::vector<T> v_flatten;
512 for(
int i = 0; i < 3; i++) {
513 mag += (o[i] - d[i]) * (o[i] - d[i]);
523 const int &dimension) {
524 for(
int i = 0; i < dimension; ++i)
525 out[i] = b[i] - a[i];
531 const std::vector<T> &b,
532 std::vector<T> &out) {
533 out.resize(a.size());
539 for(
int i = 0; i < dimension; ++i)
540 out[i] = b[i] + a[i];
546 const std::vector<T> &b,
547 std::vector<T> &out) {
548 out.resize(a.size());
549 return addVectors(a.data(), b.data(), out.data(), a.size());
554 const std::vector<std::vector<T>> &b,
555 std::vector<std::vector<T>> &out) {
556 out.resize(a.size());
557 for(
unsigned int i = 0; i < a.size(); ++i)
564 const std::vector<std::vector<std::vector<T>>> &a,
565 const std::vector<std::vector<std::vector<T>>> &b,
566 std::vector<std::vector<T>> &out) {
567 std::vector<std::vector<T>> a_flatten, b_flatten;
578 const int &dimension) {
579 for(
int i = 0; i < dimension; ++i)
580 out[i] = a[i] * factor;
587 std::vector<T> &out) {
588 out.resize(a.size());
589 return scaleVector(a.data(), factor, out.data(), a.size());
596 const int &dimension) {
599 if(dotProdBB > PREC_DBL) {
601 dotProdAB /= dotProdBB;
604 for(
int i = 0; i < dimension; ++i)
605 out[i] = b[i] * dotProdAB;
611 const std::vector<T> &b,
612 std::vector<T> &out) {
613 out.resize(a.size(), 0.0);
619 const std::vector<T> &b,
620 std::vector<T> &a_out,
621 std::vector<T> &b_out) {
630 std::vector<std::vector<T>> &out) {
631 out.resize(a.size());
633 for(
unsigned int i = 1; i < a.size(); ++i) {
634 std::vector<T> projecSum;
636 for(
unsigned int j = 1; j < i; ++j) {
637 std::vector<T> projecTemp, projecSumTemp;
639 addVectors(projecSum, projecTemp, projecSumTemp);
640 projecSum = projecSumTemp;
648 for(
unsigned int i = 0; i < a.size() - 1; ++i)
649 if(not(std::abs(a[i] - a[i + 1]) < PREC_DBL))
656 for(
unsigned int i = 0; i < a.size(); ++i)
657 if(not(std::abs(a[i]) < PREC_DBL))
664 std::vector<T> a_flatten;
671 const std::vector<std::vector<T>> &a, std::vector<T> &out) {
672 out.resize(a.size() * a[0].size());
673 for(
unsigned int i = 0; i < a.size(); ++i)
674 for(
unsigned int j = 0; j < a[0].size(); ++j)
675 out[i * a[0].size() + j] = a[i][j];
681 const std::vector<std::vector<std::vector<T>>> &a,
682 std::vector<std::vector<T>> &out) {
683 out.resize(a.size());
684 for(
unsigned int i = 0; i < a.size(); ++i)
691 std::vector<std::vector<T>> &out,
692 const int &no_columns) {
693 if(a.size() % no_columns != 0)
695 out.resize(a.size() / no_columns);
696 for(
unsigned int i = 0; i < out.size(); ++i) {
697 out[i].resize(no_columns);
698 for(
unsigned int j = 0; j < out[i].size(); ++j)
699 out[i][j] = a[i * no_columns + j];
706 const std::vector<std::vector<T>> &b,
707 std::vector<std::vector<T>> &out) {
708 out.resize(a.size(), std::vector<T>(b[0].size(), 0.0));
709 for(
unsigned int i = 0; i < out.size(); ++i)
710 for(
unsigned int j = 0; j < out[i].size(); ++j)
711 for(
unsigned int k = 0; k < a[i].size(); ++k)
712 out[i][j] += a[i][k] * b[k][j];
717 const std::vector<std::vector<T>> &b,
718 std::vector<std::vector<T>> &out) {
719 out.resize(a.size(), std::vector<T>(a[0].size()));
720 for(
unsigned int i = 0; i < out.size(); ++i)
721 for(
unsigned int j = 0; j < out[0].size(); ++j)
722 out[i][j] = b[i][j] - a[i][j];
727 const std::vector<std::vector<T>> &b,
728 std::vector<std::vector<T>> &out) {
729 out.resize(a.size(), std::vector<T>(a[0].size()));
730 for(
unsigned int i = 0; i < a.size(); ++i)
731 for(
unsigned int j = 0; j < a[0].size(); ++j)
732 out[i][j] = a[i][j] + b[i][j];
738 std::vector<std::vector<T>> &out) {
739 out.resize(a.size(), std::vector<T>(a[0].size()));
740 for(
unsigned int i = 0; i < out.size(); ++i)
741 for(
unsigned int j = 0; j < out[i].size(); ++j)
742 out[i][j] = a[i][j] * factor;
747 std::vector<std::vector<T>> &out) {
748 out.resize(a[0].size(), std::vector<T>(a.size()));
749 for(
unsigned int i = 0; i < a.size(); ++i)
750 for(
unsigned int j = 0; j < a[0].size(); ++j)
754#define GEOMETRY_SPECIALIZE(TYPE) \
755 template TYPE Geometry::angle<TYPE>( \
756 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
757 template bool Geometry::areVectorsColinear<TYPE>( \
758 TYPE const *, TYPE const *, TYPE const *, TYPE const *, \
759 std::array<TYPE, 3> *, TYPE const *); \
760 template int Geometry::computeBarycentricCoordinates<TYPE>( \
761 TYPE const *, TYPE const *, TYPE const *, std::array<TYPE, 2> &, \
763 template int Geometry::computeBarycentricCoordinates<TYPE>( \
764 TYPE const *, TYPE const *, TYPE const *, TYPE const *, \
765 std::array<TYPE, 3> &); \
766 template bool Geometry::computeSegmentIntersection<TYPE>( \
767 TYPE const &, TYPE const &, TYPE const &, TYPE const &, TYPE const &, \
768 TYPE const &, TYPE const &, TYPE const &, TYPE &, TYPE &); \
769 template int Geometry::computeTriangleAngles<TYPE>( \
770 TYPE const *, TYPE const *, TYPE const *, std::array<TYPE, 3> &); \
771 template int Geometry::computeTriangleAngleFromSides<TYPE>( \
772 TYPE const, TYPE const, TYPE const, TYPE &); \
773 template int Geometry::computeTriangleArea<TYPE>( \
774 TYPE const *, TYPE const *, TYPE const *, TYPE &); \
775 template int Geometry::computeTriangleAreaFromSides<TYPE>( \
776 TYPE const, TYPE const, TYPE const, TYPE &); \
777 template int Geometry::crossProduct<TYPE>(TYPE const *, TYPE const *, \
778 TYPE const *, TYPE const *, \
779 std::array<TYPE, 3> &); \
780 template int Geometry::crossProduct<TYPE>( \
781 TYPE const *, TYPE const *, TYPE *); \
782 template TYPE Geometry::distance<TYPE>( \
783 TYPE const *, TYPE const *, int const &); \
784 template TYPE Geometry::distance<TYPE>( \
785 std::vector<TYPE> const &, std::vector<TYPE> const &); \
786 template TYPE Geometry::distanceFlatten<TYPE>( \
787 std::vector<std::vector<TYPE>> const &, \
788 std::vector<std::vector<TYPE>> const &); \
789 template TYPE Geometry::dotProduct<TYPE>( \
790 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
791 template TYPE Geometry::dotProduct<TYPE>( \
792 TYPE const *, TYPE const *, int const &); \
793 template TYPE Geometry::dotProduct<TYPE>( \
794 std::vector<TYPE> const &, std::vector<TYPE> const &); \
795 template TYPE Geometry::dotProductFlatten<TYPE>( \
796 std::vector<std::vector<TYPE>> const &, \
797 std::vector<std::vector<TYPE>> const &); \
798 template bool Geometry::isPointInTriangle<TYPE>( \
799 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
800 template bool Geometry::isPointOnSegment<TYPE>(TYPE const &, TYPE const &, \
801 TYPE const &, TYPE const &, \
802 TYPE const &, TYPE const &); \
803 template bool Geometry::isPointOnSegment<TYPE>( \
804 TYPE const *, TYPE const *, TYPE const *, int const &); \
805 template bool Geometry::isTriangleColinear<TYPE>( \
806 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
807 template TYPE Geometry::magnitude<TYPE>(TYPE const *, int const &); \
808 template TYPE Geometry::magnitude<TYPE>(std::vector<TYPE> const &); \
809 template TYPE Geometry::magnitudeFlatten<TYPE>( \
810 std::vector<std::vector<TYPE>> const &); \
811 template TYPE Geometry::magnitude<TYPE>(TYPE const *, TYPE const *); \
812 template int Geometry::subtractVectors<TYPE>( \
813 TYPE const *, TYPE const *, TYPE *, int const &); \
814 template int Geometry::subtractVectors<TYPE>(std::vector<TYPE> const &, \
815 std::vector<TYPE> const &, \
816 std::vector<TYPE> &); \
817 template int Geometry::addVectors<TYPE>( \
818 TYPE const *, TYPE const *, TYPE *, int const &); \
819 template int Geometry::addVectors<TYPE>(std::vector<TYPE> const &, \
820 std::vector<TYPE> const &, \
821 std::vector<TYPE> &); \
822 template int Geometry::multiAddVectors<TYPE>( \
823 std::vector<std::vector<TYPE>> const &, \
824 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
825 template int Geometry::multiAddVectorsFlatten<TYPE>( \
826 std::vector<std::vector<std::vector<TYPE>>> const &, \
827 std::vector<std::vector<std::vector<TYPE>>> const &, \
828 std::vector<std::vector<TYPE>> &); \
829 template int Geometry::scaleVector<TYPE>( \
830 TYPE const *, TYPE const, TYPE *, int const &); \
831 template int Geometry::scaleVector<TYPE>( \
832 std::vector<TYPE> const &, TYPE const, std::vector<TYPE> &); \
833 template int Geometry::vectorProjection<TYPE>( \
834 TYPE const *, TYPE const *, TYPE *, int const &); \
835 template int Geometry::vectorProjection<TYPE>(std::vector<TYPE> const &, \
836 std::vector<TYPE> const &, \
837 std::vector<TYPE> &); \
838 template void Geometry::addVectorsProjection<TYPE>( \
839 std::vector<TYPE> const &, std::vector<TYPE> const &, std::vector<TYPE> &, \
840 std::vector<TYPE> &); \
841 template void Geometry::gramSchmidt<TYPE>( \
842 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
843 template bool Geometry::isVectorUniform<TYPE>(std::vector<TYPE> const &); \
844 template bool Geometry::isVectorNull<TYPE>(std::vector<TYPE> const &); \
845 template bool Geometry::isVectorNullFlatten<TYPE>( \
846 std::vector<std::vector<TYPE>> const &); \
847 template int Geometry::flattenMultiDimensionalVector<TYPE>( \
848 std::vector<std::vector<TYPE>> const &, std::vector<TYPE> &); \
849 template int Geometry::multiFlattenMultiDimensionalVector<TYPE>( \
850 std::vector<std::vector<std::vector<TYPE>>> const &, \
851 std::vector<std::vector<TYPE>> &); \
852 template int Geometry::unflattenMultiDimensionalVector<TYPE>( \
853 std::vector<TYPE> const &, std::vector<std::vector<TYPE>> &, int const &); \
854 template void Geometry::matrixMultiplication<TYPE>( \
855 std::vector<std::vector<TYPE>> const &, \
856 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
857 template void Geometry::subtractMatrices<TYPE>( \
858 std::vector<std::vector<TYPE>> const &, \
859 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
860 template void Geometry::addMatrices<TYPE>( \
861 std::vector<std::vector<TYPE>> const &, \
862 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
863 template void Geometry::scaleMatrix<TYPE>( \
864 std::vector<std::vector<TYPE>> const &, TYPE const, \
865 std::vector<std::vector<TYPE>> &); \
866 template void Geometry::transposeMatrix<TYPE>( \
867 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)
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 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)