det.c :
Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "structures.h"
/* This is the first step of our determinant calculator.
We take 4 or 5 points as input, build a formal array
and then calculate the determinant with the 'det'
function below. */
long long matrix(long long a[3], long long b[3], long long c[3], long long d[3], long long e[3], int rank) {
long long **m;
m = malloc(rank*sizeof(*m));
for (int i=0; i<rank; i++) {
m[i] = malloc(rank*sizeof(*m[i]));
m[i][0] = 1;
}
m[0][1] = a[0]; m[0][2] = a[1]; m[0][3] = a[2];
m[1][1] = b[0]; m[1][2] = b[1]; m[1][3] = b[2];
m[2][1] = c[0]; m[2][2] = c[1]; m[2][3] = c[2];
m[3][1] = d[0]; m[3][2] = d[1]; m[3][3] = d[2];
if (rank==5) {
m[0][4] = a[0]*a[0]+a[1]*a[1]+a[2]*a[2];
m[1][4] = b[0]*b[0]+b[1]*b[1]+b[2]*b[2];
m[2][4] = c[0]*c[0]+c[1]*c[1]+c[2]*c[2];
m[3][4] = d[0]*d[0]+d[1]*d[1]+d[2]*d[2];
m[4][1] = e[0]; m[4][2] = e[1]; m[4][3] = e[2]; m[4][4] = e[0]*e[0]+e[1]*e[1]+e[2]*e[2];
}
for (int i=0; i<rank; i++) {
for (int j=0; j<rank; j++) {
printf(" %lld ", m[i][j]);
} printf("\n");
}
long long n = det(m, rank);
for (int i=0; i<rank; i++) {
free(m[i]);
}
free(m);
return n;
}
/* Our determinant calculator which takes a NxN array and
will build smaller sub-arrays until we eventually hit the
3x3 floor which is ideal for our case as we will never
take a determinant of something smaller. */
long long det(long long **a, int rank) {
long long m = 0;
if (rank == 3) {
m = a[0][0]*(a[1][1]*a[2][2] - a[1][2]*a[2][1])
- a[0][1]*(a[1][0]*a[2][2] - a[1][2]*a[2][0])
+ a[0][2]*(a[1][0]*a[2][1] - a[1][1]*a[2][0]);
return m;
}
for (int i=0; i<rank; i++) {
long long **b = malloc((rank-1)*sizeof(*b));
for (int i=0; i<(rank-1); i++) {
b[i] = malloc((rank-1)*sizeof(*b[i]));
}
for (int j=1; j<rank; j++) {
int c = 0;
for (int k=0; k<rank; k++) {
if (k==i) continue;
b[j-1][c] = a[j][k];
c++;
}
}
if (i%2==0) {m += a[0][i]*det(b, rank-1);}
else m -= a[0][i]*det(b, rank-1);
for (int i=0; i<(rank-1); i++) free(b[i]);
free(b);
}
return m;
}
/* This is our intersection test. We take 5 points and determine
if e is inside the tetrahedron spanned by a, b, c and d. First,
we allocate two formal matrices based on our points. m is the
matrix highlighted by the paper (A) and l is a copy. We set
a static n to be the cofactor matrix of m and then set m to be
the transpose of n. Once we have the adjoint, we divide by
the determinant as is required by maths. fin is our final
inversed array. */
/* Once we have our final inversed array, we then do simple matrix
multiplication with our point to be tested which is our
t array. As conditions require, if every element of t is
greater than 0 and the sum of all 3 numbers is still less
than or equal to 1, we have an intersection. Our boolean
variable 'silh' is the marker of this and returns true
if and only if the point is inside the tetrahedron. */
bool cofact(long long a[3], long long b[3], long long c[3], long long d[3], long long e[3]) {
long long **m, **l;
m = malloc(3*sizeof(*m));
l = malloc(3*sizeof(*l));
for (int i=0; i<3; i++) {
m[i] = malloc(3*sizeof(*m[i]));
l[i] = malloc(3*sizeof(*l[i]));
}
m[0][0] = b[0] - a[0]; l[0][0] = m[0][0];
m[0][1] = b[1] - a[1]; l[0][1] = m[0][1];
m[0][2] = b[2] - a[2]; l[0][2] = m[0][2];
m[1][0] = c[0] - a[0]; l[1][0] = m[1][0];
m[1][1] = c[1] - a[1]; l[1][1] = m[1][1];
m[1][2] = c[2] - a[2]; l[1][2] = m[1][2];
m[2][0] = d[0] - a[0]; l[2][0] = m[2][0];
m[2][1] = d[1] - a[1]; l[2][1] = m[2][1];
m[2][2] = d[2] - a[2]; l[2][2] = m[2][2];
/*printf("Before :\n");
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
printf(" %lld ", m[i][j]);
} printf("\n");
}*/
long long n[3][3];
/* Cofactorization */
n[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1];
n[0][1] = -1*(m[1][0]*m[2][2] - m[2][0]*m[1][2]);
n[0][2] = m[1][0]*m[2][1] - m[2][0]*m[1][1];
n[1][0] = -1*(m[0][1]*m[2][2] - m[0][2]*m[2][1]);
n[1][1] = m[0][0]*m[2][2] - m[2][0]*m[0][2];
n[1][2] = -1*(m[0][0]*m[2][1] - m[2][0]*m[0][1]);
n[2][0] = m[0][1]*m[1][2] - m[1][1]*m[0][2];
n[2][1] = -1*(m[0][0]*m[1][2] - m[1][0]*m[0][2]);
n[2][2] = m[0][0]*m[1][1] - m[1][0]*m[0][1];
/* Transposition */
m[0][0] = n[0][0]; m[1][1] = n[1][1]; m[2][2] = n[2][2];
m[0][1] = n[1][0]; m[1][0] = n[0][1];
m[0][2] = n[2][0]; m[2][0] = n[0][2];
m[2][1] = n[1][2]; m[1][2] = n[2][1];
/*printf("After :\n");
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
printf(" %lld ", m[i][j]);
} printf("\n");
}*/
/* Determination */
long long z = det(l, 3);
//printf("det of adjoint : %lld\n", z);
long double fin[3][3];
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
fin[i][j] = (long double)m[i][j]/z;
}
}
/*printf("Then :\n");
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
printf(" %Lf ", fin[i][j]);
} printf("\n");
}*/
long double t[3];
t[0] = fin[0][0]*(long double)(e[0]-a[0]) + fin[0][1]*(long double)(e[1]-a[1]) + fin[0][2]*(long double)(e[2]-a[2]);
t[1] = fin[1][0]*(long double)(e[0]-a[0]) + fin[1][1]*(long double)(e[1]-a[1]) + fin[1][2]*(long double)(e[2]-a[2]);
t[2] = fin[2][0]*(long double)(e[0]-a[0]) + fin[2][1]*(long double)(e[1]-a[1]) + fin[2][2]*(long double)(e[2]-a[2]);
for (int i=0; i<3; i++) {
free(m[i]);
free(l[i]);
}
free(m); free(l);
long double silh = 0;
for (int i=0; i<3; i++) {
if (t[i]<0) return false;
silh += t[i];
}
if (silh<=1) return true;
return false;
}