41 Rx[1][1] = cosf(theta_rad);
42 Rx[1][2] = sinf(theta_rad);
44 Rx[2][1] = -sinf(theta_rad);
45 Rx[2][2] = cosf(theta_rad);
55 Ry[0][0] = cosf(theta_rad);
57 Ry[0][2] = -sinf(theta_rad);
61 Ry[2][0] = sinf(theta_rad);
63 Ry[2][2] = cosf(theta_rad);
73 Rz[0][0] = cosf(theta_rad);
74 Rz[0][1] = sinf(theta_rad);
76 Rz[1][0] = -sinf(theta_rad);
77 Rz[1][1] = cosf(theta_rad);
95 R[0][0] = 2.0f * (Q->
w * Q->
w + Q->
z * Q->
z) - 1.0f;
96 R[0][1] = 2.0f * (Q->
z * Q->
y - Q->
w * Q->
x);
97 R[0][2] = 2.0f * (Q->
z * Q->
x + Q->
w * Q->
y);
98 R[1][0] = 2.0f * (Q->
z * Q->
y + Q->
w * Q->
x);
99 R[1][1] = 2.0f * (Q->
w * Q->
w + Q->
y * Q->
y) - 1.0f;
100 R[1][2] = 2.0f * (Q->
y * Q->
x - Q->
w * Q->
z);
101 R[2][0] = 2.0f * (Q->
z * Q->
x - Q->
w * Q->
y);
102 R[2][1] = 2.0f * (Q->
y * Q->
x + Q->
w * Q->
z);
103 R[2][2] = 2.0f * (Q->
w * Q->
w + Q->
x * Q->
x) - 1.0f;
113 Q->
w = sqrtf(
SAF_MAX( 0.0f, 1.0f + R[0][0] + R[1][1] + R[2][2] ) ) / 2.0f;
114 Q->
z = sqrtf(
SAF_MAX( 0.0f, 1.0f + R[0][0] - R[1][1] - R[2][2] ) ) / 2.0f;
115 Q->
y = sqrtf(
SAF_MAX( 0.0f, 1.0f - R[0][0] + R[1][1] - R[2][2] ) ) / 2.0f;
116 Q->
x = sqrtf(
SAF_MAX( 0.0f, 1.0f - R[0][0] - R[1][1] + R[2][2] ) ) / 2.0f;
117 Q->
z = copysignf( Q->
z, R[2][1] - R[1][2] );
118 Q->
y = copysignf( Q->
y, R[0][2] - R[2][0] );
119 Q->
x = copysignf( Q->
x, R[1][0] - R[0][1] );
133 float cy, sy, cr, sr, cp, sp;
135 cy = sy = cr = sr = cp = sp = 0.0f;
140 cy = cosf((degreesFlag ? alpha*
SAF_PI/180.0f : alpha) * 0.5f);
141 sy = sinf((degreesFlag ? alpha*
SAF_PI/180.0f : alpha) * 0.5f);
142 cp = cosf((degreesFlag ? beta*
SAF_PI/180.0f : beta) * 0.5f);
143 sp = sinf((degreesFlag ? beta*
SAF_PI/180.0f : beta) * 0.5f);
144 cr = cosf((degreesFlag ? gamma*
SAF_PI/180.0f : gamma) * 0.5f);
145 sr = sinf((degreesFlag ? gamma*
SAF_PI/180.0f : gamma) * 0.5f);
148 cy = cosf((degreesFlag ? gamma*
SAF_PI/180.0f : gamma) * 0.5f);
149 sy = sinf((degreesFlag ? gamma*
SAF_PI/180.0f : gamma) * 0.5f);
150 cp = cosf((degreesFlag ? beta*
SAF_PI/180.0f : beta) * 0.5f);
151 sp = sinf((degreesFlag ? beta*
SAF_PI/180.0f : beta) * 0.5f);
152 cr = cosf((degreesFlag ? alpha*
SAF_PI/180.0f : alpha) * 0.5f);
153 sr = sinf((degreesFlag ? alpha*
SAF_PI/180.0f : alpha) * 0.5f);
156 Q->
w = cy * cr * cp + sy * sr * sp;
157 Q->
x = cy * sr * cp - sy * cr * sp;
158 Q->
y = cy * cr * sp + sy * sr * cp;
159 Q->
z = sy * cr * cp - cy * sr * sp;
173 float sinr_cosp, cosr_cosp, sinp, siny_cosp, cosy_cosp;
175 sinr_cosp = 2.0f * (Q->
w * Q->
x + Q->
y * Q->
z);
176 cosr_cosp = 1.0f - 2.0f * (Q->
x * Q->
x + Q->
y * Q->
y);
177 sinp = 2.0f * (Q->
w * Q->
y - Q->
z * Q->
x);
178 siny_cosp = 2.0f * (Q->
w * Q->
z + Q->
x * Q->
y);
179 cosy_cosp = 1.0f - 2.0f * (Q->
y * Q->
y + Q->
z * Q->
z);
185 (*gamma) = atan2f(sinr_cosp, cosr_cosp);
187 if (fabsf(sinp) >= 1.0f)
188 (*beta) = copysignf(
SAF_PI / 2.0f, sinp);
190 (*beta) = asinf(sinp);
192 (*alpha) = atan2f(siny_cosp, cosy_cosp);
196 (*alpha) = atan2f(sinr_cosp, cosr_cosp);
198 if (fabs(sinp) >= 1.0f)
199 (*beta) = copysignf(
SAF_PI / 2.0f, sinp);
201 (*beta) = asinf(sinp);
203 (*gamma) = atan2f(siny_cosp, cosy_cosp);
207 (*alpha) *= 180.0f/
SAF_PI;
209 (*gamma) *= 180.0f/
SAF_PI;
223 float R1[3][3], R2[3][3], R3[3][3], Rtmp[3][3];
227 getRz(degreesFlag ? alpha*
SAF_PI/180.0f : alpha, R1);
228 getRy(degreesFlag ? beta*
SAF_PI/180.0f : beta, R2);
229 getRz(degreesFlag ? gamma*
SAF_PI/180.0f : gamma, R3);
232 getRz(degreesFlag ? alpha*
SAF_PI/180.0f : alpha, R1);
233 getRx(degreesFlag ? beta*
SAF_PI/180.0f : beta, R2);
234 getRz(degreesFlag ? gamma*
SAF_PI/180.0f : gamma, R3);
237 getRz(degreesFlag ? alpha*
SAF_PI/180.0f : alpha, R1);
238 getRy(degreesFlag ? beta*
SAF_PI/180.0f : beta, R2);
239 getRx(degreesFlag ? gamma*
SAF_PI/180.0f : gamma, R3);
242 getRx(degreesFlag ? alpha*
SAF_PI/180.0f : alpha, R1);
243 getRy(degreesFlag ? beta*
SAF_PI/180.0f : beta, R2);
244 getRz(degreesFlag ? gamma*
SAF_PI/180.0f : gamma, R3);
247 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 3, 3, 3, 1.0f,
251 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 3, 3, 3, 1.0f,
253 (
float*)Rtmp, 3, 0.0f,
262 int rollPitchYawFLAG,
274 int anglesInDegreesFLAG,
280 if(anglesInDegreesFLAG){
281 for(i=0; i<nDirs; i++){
282 tmp_rad[0] = sph[i*3] *
SAF_PI/180.0f;
283 tmp_rad[1] = sph[i*3+1] *
SAF_PI/180.0f;
284 cart[i*3] = sph[i*3+2] * cosf(tmp_rad[1]) * cosf(tmp_rad[0]);
285 cart[i*3+1] = sph[i*3+2] * cosf(tmp_rad[1]) * sinf(tmp_rad[0]);
286 cart[i*3+2] = sph[i*3+2] * sinf(tmp_rad[1]);
290 for(i=0; i<nDirs; i++){
291 cart[i*3] = sph[i*3+2] * cosf(sph[i*3+1]) * cosf(sph[i*3]);
292 cart[i*3+1] = sph[i*3+2] * cosf(sph[i*3+1]) * sinf(sph[i*3]);
293 cart[i*3+2] = sph[i*3+2] * sinf(sph[i*3+1]);
300 int anglesInDegreesFLAG,
306 for(i=0; i<nDirs; i++){
307 hypotxy = sqrtf(cart[i*3]*cart[i*3] + cart[i*3+1]*cart[i*3+1]);
308 sph[i*3] = atan2f(cart[i*3+1], cart[i*3]);
309 sph[i*3+1] = atan2f(cart[i*3+2], hypotxy);
314 if(anglesInDegreesFLAG){
315 for(i=0; i<nDirs; i++){
316 sph[i*3] *= (180.0f/
SAF_PI);
317 sph[i*3+1] *= (180.0f/
SAF_PI);
326 int anglesInDegreesFLAG,
333 if(anglesInDegreesFLAG){
334 for(i=0; i<nDirs; i++){
335 tmp_rad[0] = dirs[i*2] *
SAF_PI/180.0f;
336 tmp_rad[1] = dirs[i*2+1] *
SAF_PI/180.0f;
337 dirs_xyz[i*3] = cosf(tmp_rad[1]) * cosf(tmp_rad[0]);
338 dirs_xyz[i*3+1] = cosf(tmp_rad[1]) * sinf(tmp_rad[0]);
339 dirs_xyz[i*3+2] = sinf(tmp_rad[1]);
343 for(i=0; i<nDirs; i++){
344 dirs_xyz[i*3] = cosf(dirs[i*2+1]) * cosf(dirs[i*2]);
345 dirs_xyz[i*3+1] = cosf(dirs[i*2+1]) * sinf(dirs[i*2]);
346 dirs_xyz[i*3+2] = sinf(dirs[i*2+1]);
355 int anglesInDegreesFLAG,
361 for(i=0; i<nDirs; i++){
362 dirs[i*2] = atan2f(dirs_xyz[i*3+1], dirs_xyz[i*3]);
363 dirs[i*2+1] = atan2f(dirs_xyz[i*3+2], sqrtf(dirs_xyz[i*3]*dirs_xyz[i*3] + dirs_xyz[i*3+1]*dirs_xyz[i*3+1]));
367 if(anglesInDegreesFLAG)
368 for(i=0; i<nDirs*2; i++)
369 dirs[i] *= (180.0f/
SAF_PI);
381 if(dirsIncl!=dirsElev)
382 cblas_scopy(nDirs*2, dirsElev, 1, dirsIncl, 1);
384 for (i=0; i<nDirs; i++)
385 dirsIncl[i*2+1] = 90.f - dirsElev[i*2+1];
388 for (i=0; i<nDirs; i++)
389 dirsIncl[i*2+1] =
SAF_PI/2.f - dirsElev[i*2+1];
402 if(dirsIncl!=dirsElev)
403 cblas_scopy(nDirs*2, dirsIncl, 1, dirsElev, 1);
405 for (i=0; i<nDirs; i++)
406 dirsElev[i*2+1] = 90.f - dirsIncl[i*2+1];
409 for (i=0; i<nDirs; i++)
410 dirsElev[i*2+1] =
SAF_PI/2.f - dirsIncl[i*2+1];
419 return sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
431 for(i=0; i<lenV; i++)
446 MMT =
malloc1d(lenX*lenX*
sizeof(
float));
447 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasTrans, lenX, lenX, lenY, 1.0f,
452 for(i=0; i<lenX; i++)
453 res += MMT[i*lenX+i];
465 c[0] = a[1]*b[2]-a[2]*b[1];
466 c[1] = a[2]*b[0]-a[0]*b[2];
467 c[2] = a[0]*b[1]-a[1]*b[0];
477 float a[3], b[3], cross_a_ab[3];
478 a[0] = v1[0] - v2[0];
479 a[1] = v1[1] - v2[1];
480 a[2] = v1[2] - v2[2];
481 b[0] = point[0] - v2[0];
482 b[1] = point[1] - v2[1];
483 b[2] = point[2] - v2[2];
494#if defined(SAF_USE_APPLE_ACCELERATE) && 0
496 vDSP_distancesq((
const float*)point_a, 1, (
const float*)point_b, 1, &sqdist, 3);
497 return sqrtf(sqdist);
500 a_b[0] = point_a[0] - point_b[0];
501 a_b[1] = point_a[1] - point_b[1];
502 a_b[2] = point_a[2] - point_b[2];
514 const float* vertices,
525 for(i = 0; i < nVert; i++) {
526 ch_vertices[i].z = (CH_FLOAT)vertices[i*3+2];
527 ch_vertices[i].x = (CH_FLOAT)vertices[i*3];
528 ch_vertices[i].y = (CH_FLOAT)vertices[i*3+1];
532 saf_assert(*faces == NULL,
"nFaces not known yet, and so shouldn't be pre-allocated...");
552 ch_points =
malloc1d(nPoints*nd*
sizeof(CH_FLOAT));
553 for(i = 0; i < nPoints; i++) {
555 ch_points[i*nd+j] = (CH_FLOAT)points[i*nd+j];
559 saf_assert(*faces == NULL,
"nFaces not known yet, and so shouldn't be pre-allocated...");
575 int i, j, k, nHullFaces, maxW_idx, nVisible;
577 CH_FLOAT w0, w_optimal, w_optimal2;
578 CH_FLOAT* projpoints, *cf, *df, *p0, *p, *visible;
581 projpoints =
malloc1d(nPoints*(nd+1)*
sizeof(CH_FLOAT));
582 for(i = 0; i < nPoints; i++) {
583 projpoints[i*(nd+1)+nd] = 0.0;
585 projpoints[i*(nd+1)+j] = (CH_FLOAT)points[i*nd+j] + 0.0000001*(CH_FLOAT)rand()/(CH_FLOAT)RAND_MAX;
586 projpoints[i*(nd+1)+nd] += (projpoints[i*(nd+1)+j]*projpoints[i*(nd+1)+j]);
596 if(
sizeof(CH_FLOAT)==
sizeof(
double))
597 maxW_idx = (int)cblas_idamax(nPoints, (
double*)&projpoints[nd], nd+1);
599 maxW_idx = (int)cblas_isamax(nPoints, (
float*)&projpoints[nd], nd+1);
600 w0 = projpoints[maxW_idx*(nd+1)+nd];
603 p0[j] = projpoints[maxW_idx*(nd+1)+j];
609 w_optimal += (2.0*pow(p0[j], 2.0));
610 w_optimal = w0-w_optimal;
614 w_optimal2=w_optimal-1000.0*fabs(w_optimal);
617 p =
calloc1d((nd+1),
sizeof(CH_FLOAT));
621 visible =
malloc1d(nHullFaces*
sizeof(CH_FLOAT));
622 if(
sizeof(CH_FLOAT)==
sizeof(
double)){
623 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nHullFaces, 1, nd+1, 1.0,
626 (
double*)visible, 1);
629 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nHullFaces, 1, nd+1, 1.0f,
635 for(j=0; j<nHullFaces; j++){
644 (*DT) =
malloc1d(nVisible*(nd+1)*
sizeof(
int));
645 for(i=0, j=0; i<nHullFaces; i++){
647 for(k=0; k<nd+1; k++)
648 (*DT)[j*(nd+1)+k] = hullfaces[i*(nd+1)+k];
667 const float* dirs_deg,
679 vertices_tmp =
malloc1d(nDirs*3*
sizeof(
float));
680 for(i = 0; i < nDirs; i++) {
681 vertices_tmp[i*3+2] = sinf(dirs_deg[i*2+1]*
SAF_PI/180.0f);
682 rcoselev = cosf(dirs_deg[i*2+1]*
SAF_PI/180.0f);
683 vertices_tmp[i*3] = rcoselev * cosf(dirs_deg[i*2+0]*
SAF_PI/180.0f);
684 vertices_tmp[i*3+1] = rcoselev * sinf(dirs_deg[i*2+0]*
SAF_PI/180.0f);
689 convhull3d(vertices_tmp, nDirs, faces, nFaces);
693 memcpy(vertices, vertices_tmp, nDirs*3*
sizeof(
float));
710 float r_12[3], r_13[3], r_normal[3];
714 voronoi->
nVert = nFaces;
722 for(n = 0; n<nFaces; n++){
723 r_12[0] = vertices[faces[n*3+1]*3] - vertices[faces[n*3]*3];
724 r_12[1] = vertices[faces[n*3+1]*3+1] - vertices[faces[n*3]*3+1];
725 r_12[2] = vertices[faces[n*3+1]*3+2] - vertices[faces[n*3]*3+2];
726 r_13[0] = vertices[faces[n*3+2]*3] - vertices[faces[n*3]*3];
727 r_13[1] = vertices[faces[n*3+2]*3+1] - vertices[faces[n*3]*3+1];
728 r_13[2] = vertices[faces[n*3+2]*3+2] - vertices[faces[n*3]*3+2];
733 memcpy(voronoi->
vert[n], r_normal, 3*
sizeof(
float));
739 for(n = 0; n<voronoi->
nVert; n++){
740 if (duplicates[n] == 0 ){
741 for (m = 0; m<voronoi->
nVert; m++){
743 if (fabsf(voronoi->
vert[n][0] - voronoi->
vert[m][0]) < 1.0e-5f &&
744 fabsf(voronoi->
vert[n][1] - voronoi->
vert[m][1]) < 1.0e-5f &&
745 fabsf(voronoi->
vert[n][2] - voronoi->
vert[m][2]) < 1.0e-5f ){
754 int i, j, k, l, nFaceIdx, currentfaceIdx, currentvertIdx, currentvert, nSorted;
756 int* faceIdx, *sorted, *tempfacelist;
765 for (n = 0; n<voronoi->
nFaces; n++){
767 for(m=0; m<voronoi->
nVert; m++)
768 if(faces[m*3+0]==n || faces[m*3+1]==n || faces[m*3+2]==n)
770 faceIdx =
realloc1d(faceIdx, nFaceIdx*
sizeof(
int));
774 for(m=0; m<voronoi->
nVert; m++){
775 if(faces[m*3+0]==n || faces[m*3+1]==n || faces[m*3+2]==n){
788 currentfaceIdx = faceIdx[k];
789 memcpy(currentface, &faces[currentfaceIdx*3], 3*
sizeof(
int));
794 if(currentface[j] != n){
800 currentvert = currentface[currentvertIdx];
804 sorted =
realloc1d(sorted, nSorted*
sizeof(
int));
805 sorted[0] = faceIdx[k];
809 tempfacelist =
realloc1d(tempfacelist, (nFaceIdx-1)*
sizeof(
int));
811 for(i=0; i<nFaceIdx; i++){
812 if(faceIdx[i]!=currentfaceIdx){
813 tempfacelist[l] = faceIdx[i];
819 for (l = 0; l<nFaceIdx-1; l++){
820 currentfaceIdx = tempfacelist[l];
821 memcpy(currentface, &faces[currentfaceIdx*3], 3*
sizeof(
int));
824 if (currentface[0] == currentvert || currentface[1] == currentvert || currentface[2] == currentvert){
827 sorted =
realloc1d(sorted, nSorted*
sizeof(
int));
828 sorted[nSorted-1] = currentfaceIdx;
831 if (nSorted == nFaceIdx){
838 if(currentface[j] != n && currentface[j] != currentvert)
840 currentvert = currentface[currentvertIdx];
847 for (i=0; i<nSorted; i++)
848 if (duplicates[sorted[i]] != 0)
849 sorted[i] = duplicates[sorted[i]];
856 unique_i(sorted, nSorted, NULL, &uniqueIDs, &nUnique);
857 sorti(uniqueIDs, uniqueIDs, NULL, nUnique, 0);
861 for(i=0; i<nUnique; i++)
862 voronoi->
faces[n][i] = sorted[uniqueIDs[i]];
882 int i, m, n, N_poly, tmp_i;
884 float tmp, r_21_norm, r_23_norm;
886 float r_01[3], r_02[3], r_2x1[3], r_21[3], r_03[3], r_2x3[3], r_23[3];
890 for(m=0; m<voronoi->
nFaces; m++){
892 face =
realloc1d(face, N_poly*
sizeof(
int));
893 theta =
realloc1d(theta, N_poly*
sizeof(
float));
894 memcpy(face, voronoi->
faces[m], N_poly*
sizeof(
int));
896 for(n=0; n<N_poly; n++){
898 memcpy(r_01, voronoi->
vert[face[0]], 3*
sizeof(
float));
899 memcpy(r_02, voronoi->
vert[face[1]], 3*
sizeof(
float));
908 memcpy(r_03, voronoi->
vert[face[2]], 3*
sizeof(
float));
924 theta[n] = acosf(tmp);
928 for(i=1; i<N_poly; i++)
930 face[N_poly-1] = tmp_i;
935 for(i=0; i<N_poly; i++)
937 areas[m] = tmp - ((float)N_poly-2.0f)*
SAF_PI;
953 float* vertices, *areas;
958 vertices =
malloc1d(nDirs*3*
sizeof(
float));
959 sphDelaunay(dirs_deg, nDirs, &faces, &nFaces, vertices);
962 sphVoronoi(faces, nFaces, vertices, nDirs, &voronoi);
971 memset(weights, 0, nDirs*nDirs*
sizeof(
float));
972 for(i=0; i<nDirs; i++)
973 weights[i*nDirs+i] = areas[i];
976 memcpy(weights, areas, nDirs*
sizeof(
float));
982 for(i=0; i<voronoi.
nFaces; i++)
983 free(voronoi.
faces[i]);
void convhull_3d_build(ch_vertex *const in_vertices, const int nVert, int **out_faces, CH_FLOAT **out_cf, CH_FLOAT **out_df, int *nOut_faces)
Builds the 3-D convexhull using the quickhull algorithm [1].
void convhull_nd_build(CH_FLOAT *const in_vertices, const int nVert, const int d, int **out_faces, CH_FLOAT **out_cf, CH_FLOAT **out_df, int *nOut_faces)
Builds the N-D convexhull using the quickhull algorithm [1].
#define saf_print_error(message)
Macro to print a error message along with the filename and line number.
#define saf_assert(x, message)
Macro to make an assertion, along with a string explaining its purpose.
#define SAF_PI
pi constant (single precision)
void euler2rotationMatrix(float alpha, float beta, float gamma, int degreesFlag, EULER_ROTATION_CONVENTIONS convention, float R[3][3])
Constructs a 3x3 rotation matrix from the Euler angles.
void quaternion2rotationMatrix(quaternion_data *Q, float R[3][3])
Constructs a 3x3 rotation matrix based on a quaternion.
EULER_ROTATION_CONVENTIONS
Available euler2rotationMatrix() conventions.
#define SAF_MAX(a, b)
Returns the maximum of the two values.
void convhull3d(const float *vertices, const int nVert, int **faces, int *nFaces)
Builds the convex hull of an arrangement of vertices in 3-dimensional space.
void sphVoronoiAreas(voronoi_data *voronoi, float *areas)
Computes the areas of a Voronoi diagram on the unit sphere [sum(areas)=4pi].
void euler2Quaternion(float alpha, float beta, float gamma, int degreesFlag, EULER_ROTATION_CONVENTIONS convention, quaternion_data *Q)
Converts Euler angles to a quaternion.
void unique_i(int *input, int nInputs, int **uniqueVals, int **uniqueInds, int *nUnique)
Finds the unique values (and their indices) of the input vector.
void getVoronoiWeights(float *dirs_deg, int nDirs, int diagFLAG, float *weights)
Computes the integration weights, based on the areas of each face of the corresponding Voronoi diagra...
void quaternion2euler(quaternion_data *Q, int degreesFlag, EULER_ROTATION_CONVENTIONS convention, float *alpha, float *beta, float *gamma)
Converts a quaternion to Euler angles.
void sphIncl2Elev(float *dirsIncl, int nDirs, int degreesFlag, float *dirsElev)
Converts spherical coordinates of unit length from inclination to elevation.
void crossProduct3(float a[3], float b[3], float c[3])
Cross product between two 3-element floating point vectors (c = a x b)
void sph2cart(float *sph, int nDirs, int anglesInDegreesFLAG, float *cart)
Converts spherical coordinates to Cartesian coordinates.
void rotationMatrix2quaternion(float R[3][3], quaternion_data *Q)
Calculates the quaternion corresponding to a 3x3 rotation matrix.
void sphElev2incl(float *dirsElev, int nDirs, int degreesFlag, float *dirsIncl)
Converts spherical coordinates of unit length from elevation to inclination.
float getDistBetweenPointAndLine(float point[3], float v1[3], float v2[3])
Returns the distance between a "point" and an infinite line described by the two points "v1" and "v2"...
float Frob_norm(float *M, int lenX, int lenY)
Returns the Frobenius Norm of a matrix M, of dimensions: lenX x lenY.
void sphVoronoi(int *faces, int nFaces, float *vertices, int nDirs, voronoi_data *voronoi)
Computes the Voronoi diagram for a spherical arrangement of points.
void unitSph2cart(float *dirs, int nDirs, int anglesInDegreesFLAG, float *dirs_xyz)
Converts spherical coordinates to Cartesian coordinates of unit length.
void unitCart2sph(float *dirs_xyz, int nDirs, int anglesInDegreesFLAG, float *dirs)
Converts Cartesian coordinates of unit length to spherical coordinates.
void sorti(int *in_vec, int *out_vec, int *new_idices, int len, int descendFLAG)
Sort a vector of integer values into ascending/decending order (optionally returning the new indices ...
void sphDelaunay(const float *dirs_deg, const int nDirs, int **faces, int *nFaces, float *vertices)
Delaunay triangulation of a spherical arrangement of points.
float getDistBetween2Points(float point_a[3], float point_b[3])
Returns the distance between "point_a" and "point_b".
void yawPitchRoll2Rzyx(float yaw, float pitch, float roll, int rollPitchYawFLAG, float R[3][3])
Constructs a 3x3 rotation matrix from the Euler angles, using the yaw-pitch-roll (zyx) convention.
void convhullnd(const float *points, const int nPoints, const int nd, int **faces, int *nFaces)
Builds the convex hull of an arrangement of points in N-dimensional space.
void cart2sph(float *cart, int nDirs, int anglesInDegreesFLAG, float *sph)
Converts Cartesian coordinates to spherical coordinates.
float L2_norm(float *v, int lenV)
Returns the L2 (Euclidean) norm of an arbitrary length vector.
void utility_svvdot(const float *a, const float *b, const int len, float *c)
Single-precision, vector-vector dot product, i.e.
void delaunaynd(const float *points, const int nPoints, const int nd, int **DT, int *nDT)
Computes the Delaunay triangulation of an arrangement of points in N-dimensional space.
float L2_norm3(float v[3])
Returns the L2 (Euclidean) norm of a 3-element vector.
void utility_svsmul(float *a, const float *s, const int len, float *c)
Single-precision, multiplies each element in vector 'a' with a scalar 's', i.e.
@ EULER_ROTATION_YAW_PITCH_ROLL
yaw-pitch-roll, 'zyx'
@ EULER_ROTATION_ROLL_PITCH_YAW
roll-pitch-yaw, 'xyz'
@ EULER_ROTATION_X_CONVENTION
x-convention, 'zxz'
@ EULER_ROTATION_Y_CONVENTION
y-convention, 'zyz'
void ** malloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D malloc (contiguously allocated, so use free() as usual to deallocate)
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
void * calloc1d(size_t dim1, size_t data_size)
1-D calloc (same as calloc, but with error checking)
void * realloc1d(void *ptr, size_t dim1_data_size)
1-D realloc (same as realloc, but with error checking)
Include header for SAF externals.
Main header for the utilities module (SAF_UTILITIES_MODULE)
static void getRz(float theta_rad, float Rz[3][3])
Helper function for euler2rotationMatrix()
static void getRy(float theta_rad, float Ry[3][3])
Helper function for euler2rotationMatrix()
static void getRx(float theta_rad, float Rx[3][3])
Helper function for euler2rotationMatrix()
vertex structure, used by convhull_3d
Quaternion data structure.
float x
X value of the quaternion [-1..1].
float z
Z value of the quaternion [-1..1].
float y
Y value of the quaternion [-1..1].
float w
W value of the quaternion [-1..1].
Data structure for Voronoi diagrams.
float ** vert
Vertices; nVert x 3.
int ** faces
faces; nFaces x nPointsPerFace[i]
int nFaces
Number of faces/polygons.
int * nPointsPerFace
Number of points for each face; nFaces x 1.
int nVert
Number of vertices.