20 #include "gsl/gsl_linalg.h" 28 ASSERT(B->size1 ==A->size2);
31 res = gsl_matrix_alloc(A->size1,B->size2);
35 ASSERT(res->size1 == A->size1 &&
36 res->size2 == B->size2);
40 for(
unsigned int ui=0; ui<A->size1; ui++)
42 for(
unsigned int uj=0;uj<B->size2; uj++)
46 for(
unsigned int uk=0;uk<B->size1; uk++)
48 cuml+= gsl_matrix_get(A,ui,uk)
49 *gsl_matrix_get(B,uk,uj);
52 gsl_matrix_set(res, ui,uj,cuml);
61 auto w = gsl_vector_alloc(m->size2);
62 auto s = gsl_vector_alloc(m->size2);
64 auto v = gsl_matrix_alloc(m->size2,m->size2);
66 auto m2 = gsl_matrix_alloc(m->size1,m->size2);
67 gsl_matrix_memcpy(m2,m);
68 if(gsl_linalg_SV_decomp(m2,v,s,w))
78 for(
auto ui=0;ui<s->size; ui++)
80 if(gsl_vector_get(s,ui) > tolerance)
96 auto w = gsl_vector_alloc(m->size2);
97 auto s = gsl_vector_alloc(m->size2);
99 auto v = gsl_matrix_alloc(m->size2,m->size2);
101 if(gsl_linalg_SV_decomp(m,v,s,w))
110 if(gsl_linalg_SV_solve(m, v, s, b, x))
134 float dot1 = (pB-pA).dotProd(vC - pA);
135 float dot2= (pA - pB).dotProd(vD - pB);
138 if(dot1 ==0.0f || dot2 == 0.0f)
142 if(( dot1 < 0.0f && dot2 > 0.0f) || (dot1 > 0.0f && dot2 < 0.0f) )
145 if( dot1 < 0.0f && dot2 <0.0f )
148 if(dot1 > 0.0f && dot2 > 0.0f )
183 float baryCentricCoord[3];
184 for(
size_t ui=0; ui<3;ui++)
188 mid = (pTri[(ui+1)%3] -pTri[ui])*0.5f + pTri[ui];
190 tmp = (pTri[(ui+2)%3]-mid);
192 baryCentricCoord[ui] = tmp.
dotProd(p -mid)/(tmp.
mag());
196 for(
size_t ui=0;ui<3;ui++)
198 insideTri&= (0.0f <=baryCentricCoord[ui] &&
199 baryCentricCoord[ui] <=1.0f);
214 float minV=std::numeric_limits<float>::max();
216 for(
size_t ui=0;ui<3;ui++)
218 if( bestDist[ui] < minV)
231 return bestDist[offset];
233 return -bestDist[offset];
238 temp = (p-fA).dotProd(normal);
241 ASSERT(sqrt(fA.
sqrDist(p)) >= fabs(temp) - sqrt(std::numeric_limits<float>::epsilon()));
242 ASSERT(sqrt(fB.
sqrDist(p)) >= fabs(temp) - sqrt(std::numeric_limits<float>::epsilon()));
243 ASSERT(sqrt(fC.
sqrDist(p)) >= fabs(temp) - sqrt(std::numeric_limits<float>::epsilon()));
258 return (ptArray[0]*(ptArray[4]*ptArray[8]
259 - ptArray[7]*ptArray[5])
260 - ptArray[1]*(ptArray[3]*ptArray[8]
261 - ptArray[6]*ptArray[5])
262 + ptArray[2]*(ptArray[3]*ptArray[7]
263 - ptArray[4]*ptArray[6]));
274 for(
size_t ui=0; ui<3;ui++)
278 mid = (pTri[(ui+1)%3] -pTri[ui])*0.5f + pTri[ui];
280 tmp = (pTri[(ui+2)%3]-mid);
282 if(tmp.
mag() < sqrt(std::numeric_limits<float>::epsilon()))
302 simplexA[0] = (double)( (planarPts[0])[0] - (planarPts[1])[0] );
303 simplexA[1] = (double)( (planarPts[1])[0] - (planarPts[2])[0] );
304 simplexA[2] = (double)( (planarPts[2])[0] - (apex)[0] );
306 simplexA[3] = (double)( (planarPts[0])[1] - (planarPts[1])[1] );
307 simplexA[4] = (double)( (planarPts[1])[1] - (planarPts[2])[1] );
308 simplexA[5] = (double)( (planarPts[2])[1] - (apex)[1] );
310 simplexA[6] = (double)( (planarPts[0])[2] - (planarPts[1])[2] );
311 simplexA[7] = (double)( (planarPts[1])[2] - (planarPts[2])[2] );
312 simplexA[8] = (double)( (planarPts[2])[2] - (apex)[2] );
314 return 1.0/6.0 * (fabs(
det3by3(simplexA)));
318 bool runMiscMathsTests()
320 for(
auto ui=1;ui<10;ui++)
323 m= gsl_matrix_alloc(ui,ui);
325 gsl_matrix_set_identity(m);
332 auto *m = gsl_matrix_alloc(2,2);
333 gsl_matrix_set_zero(m);
335 gsl_matrix_set(m,1,1,0.5);
float sqrDist(const Point3D &pt) const
Returns the square of distance to another Point3D.
float signedDistanceToFacet(const Point3D &fA, const Point3D &fB, const Point3D &fC, const Point3D &normal, const Point3D &p)
Find the distance between a point, and a triangular facet – may be positive or negative.
double pyramidVol(const Point3D *planarPts, const Point3D &apex)
Point3D crossProd(const Point3D &pt) const
Calculate the cross product of this and another point.
void gsl_matrix_mult(const gsl_matrix *A, const gsl_matrix *B, gsl_matrix *&res, bool alloc=false)
bool solveLeastSquares(gsl_matrix *m, gsl_vector *b, gsl_vector *&x)
Use an SVD based least-squares solver to solve Mx=b (for x).
float distanceToSegment(const Point3D &fA, const Point3D &fB, const Point3D &p)
float sqrMag() const
Returns magnitude^2, taking this as a position vector.
A 3D point data class storage.
float mag() const
Magnitude of position vector.
double det3by3(const double *ptArray)
unsigned int estimateRank(const gsl_matrix *m, float tolerance=sqrt(std::numeric_limits< float >::epsilon()))
Estimate the rank of the given matrix.
bool triIsDegenerate(const Point3D &fA, const Point3D &fB, const Point3D &fC)
float dotProd(const Point3D &pt) const
Calculate the dot product of this and another point.
float distanceToFacet(const Point3D &fA, const Point3D &fB, const Point3D &fC, const Point3D &normal, const Point3D &p)
unsigned int vectorPointDir(const Point3D &pA, const Point3D &pB, const Point3D &vC, const Point3D &vD)
Check which way vectors attached to two 3D points "point",.