You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
646 lines
16 KiB
646 lines
16 KiB
18 years ago
|
/* map3d.c */
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <math.h>
|
||
|
#include <strings.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include "vm.h"
|
||
|
|
||
|
#define NLIGHTS 16
|
||
|
|
||
|
#define PANMAX 127
|
||
|
#define PANRANGE M_PI_2
|
||
|
#define PANOFFSET 128
|
||
|
#define TILTMAX 127
|
||
|
#define TILTRANGE M_PI_4
|
||
|
#define TILTOFFSET 128
|
||
|
|
||
|
#define MAP3D_FILENAME ".map3d.caldata"
|
||
|
|
||
|
struct light {
|
||
|
double M[4][3];
|
||
|
double cp[3][3];
|
||
|
double pan[3];
|
||
|
double tilt[3];
|
||
|
};
|
||
|
|
||
|
struct light map3d_cal[NLIGHTS];
|
||
|
|
||
|
#define MAG(x) (sqrt(SQUARE(x[0]) + SQUARE(x[1]) + SQUARE(x[2])))
|
||
|
#define SQUARE(x) ((x) * (x))
|
||
|
#define PYTHAG3(a, b) sqrt(SQUARE(a[0]-b[0]) + SQUARE(a[1]-b[1]) + SQUARE(a[2]-b[2]))
|
||
|
|
||
|
#define DEG(x) (180 * (x) / M_PI)
|
||
|
|
||
|
void normalise(double *v)
|
||
|
{
|
||
|
double mag;
|
||
|
int i;
|
||
|
|
||
|
mag = MAG(v);
|
||
|
|
||
|
for (i = 0; i < 3; i++)
|
||
|
v[i] /= mag;
|
||
|
}
|
||
|
|
||
|
#define MM map3d_cal[light].M
|
||
|
|
||
|
void multiply(int light, double *i, double *o) {
|
||
|
o[0] = i[0] * MM[0][0] + i[1] * MM[1][0] + i[2] * MM[2][0] + MM[3][0];
|
||
|
o[1] = i[0] * MM[0][1] + i[1] * MM[1][1] + i[2] * MM[2][1] + MM[3][1];
|
||
|
o[2] = i[0] * MM[0][2] + i[1] * MM[1][2] + i[2] * MM[2][2] + MM[3][2];
|
||
|
}
|
||
|
|
||
|
#undef MM
|
||
|
|
||
|
void map3d_init(void)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void map3d_close(void)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void map3d_save(void)
|
||
|
{
|
||
|
int fd, rv;
|
||
|
|
||
|
fd = open(MAP3D_FILENAME, O_WRONLY | O_CREAT, 0666);
|
||
|
rv = write(fd, map3d_cal, sizeof(map3d_cal));
|
||
|
if (rv != sizeof(map3d_cal))
|
||
|
printf("Warning: Calibration data not saved correctly\n");
|
||
|
close(fd);
|
||
|
}
|
||
|
|
||
|
int map3d_load(void)
|
||
|
{
|
||
|
int fd, rv;
|
||
|
|
||
|
fd = open(MAP3D_FILENAME, O_RDONLY, 0666);
|
||
|
if (!fd)
|
||
|
return 0;
|
||
|
rv = read(fd, map3d_cal, sizeof(map3d_cal));
|
||
|
if (rv != sizeof(map3d_cal))
|
||
|
printf("Warning: Calibration data not read correctly\n");
|
||
|
close(fd);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
void map3d_transform(int light, double x, double y, double z,
|
||
|
int *pan, int *tilt)
|
||
|
{
|
||
|
double pv[3];
|
||
|
double rv[3];
|
||
|
double p, t;
|
||
|
|
||
|
// printf("Transforming for light %d: (%f, %f, %f)\n", light, x, y, z);
|
||
|
fflush(stdout);
|
||
|
pv[0] = x;
|
||
|
pv[1] = y;
|
||
|
pv[2] = z;
|
||
|
multiply(light, pv, rv);
|
||
|
normalise(rv);
|
||
|
t = asin(rv[1]);
|
||
|
p = asin(rv[0]/cos(t));
|
||
|
|
||
|
*pan = (int)round((p * PANMAX)/PANRANGE) + PANOFFSET;
|
||
|
*tilt = (int)round((t * TILTMAX)/TILTRANGE) + TILTOFFSET;
|
||
|
if (*pan < 0)
|
||
|
*pan = 0;
|
||
|
if (*pan > 255)
|
||
|
*pan = 255;
|
||
|
if (*tilt < 0)
|
||
|
*tilt = 0;
|
||
|
if (*tilt > 255)
|
||
|
*tilt = 255;
|
||
|
// printf("pan = %d, tilt = %d\n", *pan, *tilt);
|
||
|
}
|
||
|
|
||
|
void map3d_setcal(int light, int n, double x, double y, double z,
|
||
|
int pan, int tilt)
|
||
|
{
|
||
|
printf("setcal(%d, %d, %f, %f, %f, %d, %d)\n", light, n, x, y, z, pan, tilt);
|
||
|
map3d_cal[light].cp[n][0] = x;
|
||
|
map3d_cal[light].cp[n][1] = y;
|
||
|
map3d_cal[light].cp[n][2] = z;
|
||
|
map3d_cal[light].pan[n] = PANRANGE * ((double)pan - PANOFFSET) / PANMAX;
|
||
|
map3d_cal[light].tilt[n] = TILTRANGE * ((double)tilt - TILTOFFSET)
|
||
|
/ TILTMAX;
|
||
|
printf("Setcal: pan = %f, tilt = %f\n", map3d_cal[light].pan[n], map3d_cal[light].tilt[n]);
|
||
|
}
|
||
|
|
||
|
void unitvector(double *vec, double pan, double tilt)
|
||
|
{
|
||
|
double tmp[3];
|
||
|
double cosp, sinp, cost, sint;
|
||
|
|
||
|
/* Precalculate some values */
|
||
|
cosp = cos(pan);
|
||
|
sinp = sin(pan);
|
||
|
cost = cos(tilt);
|
||
|
sint = sin(tilt);
|
||
|
|
||
|
/* Start with a unit vector */
|
||
|
vec[0] = 0;
|
||
|
vec[1] = 0;
|
||
|
vec[2] = 1;
|
||
|
|
||
|
/* Rotate around X axis (tilt) */
|
||
|
tmp[0] = vec[0];
|
||
|
tmp[1] = vec[1]*cost + vec[2]*sint;
|
||
|
tmp[2] = vec[2]*cost - vec[1]*sint;
|
||
|
|
||
|
/* Rotate around Y axis (pan) */
|
||
|
vec[0] = tmp[0]*cosp + tmp[2]*sinp;
|
||
|
vec[1] = tmp[1];
|
||
|
vec[2] = tmp[2]*cosp - tmp[0]*sinp;
|
||
|
}
|
||
|
|
||
|
double dotproduct(double *a, double *b)
|
||
|
{
|
||
|
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
|
||
|
}
|
||
|
|
||
|
void crossproduct(double *a, double *b, double *r)
|
||
|
{
|
||
|
r[0] = a[1]*b[2] - a[2]*b[1];
|
||
|
r[1] = a[2]*b[0] - a[0]*b[2];
|
||
|
r[2] = a[0]*b[1] - a[1]*b[0];
|
||
|
}
|
||
|
|
||
|
void dumpmatrix(double sim[12][13]) {
|
||
|
int i, j;
|
||
|
|
||
|
for (i = 0; i < 12; i++) {
|
||
|
for (j = 0; j < 13; j++)
|
||
|
printf("\t%f", sim[i][j]);
|
||
|
printf("\n");
|
||
|
}
|
||
|
printf("\n");
|
||
|
}
|
||
|
|
||
|
void eliminate(double sim[12][13], double *var)
|
||
|
{
|
||
|
int i, j, k, maxpos;
|
||
|
double max, val, tmp, x;
|
||
|
|
||
|
dumpmatrix(sim);
|
||
|
|
||
|
for (i = 0; i < 12; i++) {
|
||
|
/* Find the maximum element in the ith column */
|
||
|
max = 0.0;
|
||
|
maxpos = i;
|
||
|
for (j = i; j < 12; j++) {
|
||
|
val = fabs(sim[j][i]);
|
||
|
if (val > max) {
|
||
|
max = val;
|
||
|
maxpos = j;
|
||
|
}
|
||
|
}
|
||
|
if (maxpos != i)
|
||
|
for (j = 0; j < 13; j++) {
|
||
|
tmp = sim[maxpos][j];
|
||
|
sim[maxpos][j] = sim[i][j];
|
||
|
sim[i][j] = tmp;
|
||
|
}
|
||
|
if (fabs(sim[i][i]) < 0.0001)
|
||
|
printf("Warning: Lost accuracy at row %d\n", i);
|
||
|
for (j = i+1; j < 12; j++) {
|
||
|
if (fabs(sim[j][i]) > 0.0) {
|
||
|
/*
|
||
|
* Subtract x times row i from row j,
|
||
|
* where x is chosen such that
|
||
|
* sim[i][i] * x = sim[j][i]
|
||
|
*/
|
||
|
x = sim[j][i] / sim[i][i];
|
||
|
for (k = 0; k < 13; k++)
|
||
|
sim[j][k] -= x*sim[i][k];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dumpmatrix(sim);
|
||
|
|
||
|
/* Next, substitute in the unknowns. */
|
||
|
for (i = 12-1; i >= 0; i--) {
|
||
|
var[i] = sim[i][12];
|
||
|
for (j = i+1; j < 12; j++)
|
||
|
var[i] -= var[j] * sim[i][j];
|
||
|
var[i] /= sim[i][i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* In: Guess, length, angle, space for solutions */
|
||
|
void solvetriangle(double c, double a, double A, double *solp, double *soln)
|
||
|
{
|
||
|
double root;
|
||
|
double cosA;
|
||
|
double med;
|
||
|
|
||
|
cosA = cos(A);
|
||
|
med = 4*c*c*cosA*cosA - 4*(c*c-a*a);
|
||
|
root = sqrt(med);
|
||
|
|
||
|
if (isnan(root))
|
||
|
/* sqrt() of a negative number */
|
||
|
if (med > -0.000000001)
|
||
|
root = 0;
|
||
|
|
||
|
*solp = (2*c*cosA + root)/2;
|
||
|
*soln = (2*c*cosA - root)/2;
|
||
|
}
|
||
|
|
||
|
double try(int n, double dguess, double a, double b, double c, double A, double B, double C)
|
||
|
{
|
||
|
double s1, s2;
|
||
|
double e, f, d;
|
||
|
|
||
|
solvetriangle(dguess, a, A, &s1, &s2);
|
||
|
e = (n>=4?s2:s1);
|
||
|
n = n % 4;
|
||
|
solvetriangle(e, c, C, &s1, &s2);
|
||
|
f = (n>=2?s2:s1);
|
||
|
n = n % 2;
|
||
|
solvetriangle(f, b, B, &s1, &s2);
|
||
|
d = (n>=1?s2:s1);
|
||
|
|
||
|
return d;
|
||
|
}
|
||
|
|
||
|
void getsolution(int n, double dguess, double a, double b, double c, double A, double B, double C, double *e, double *f)
|
||
|
{
|
||
|
double s1, s2;
|
||
|
|
||
|
solvetriangle(dguess, a, A, &s1, &s2);
|
||
|
*e = (n>=4?s2:s1);
|
||
|
n = n % 4;
|
||
|
solvetriangle(*e, c, C, &s1, &s2);
|
||
|
*f = (n>=2?s2:s1);
|
||
|
}
|
||
|
|
||
|
#define DINCR 0.005
|
||
|
|
||
|
/*
|
||
|
* A is angle opposite a, between d and e
|
||
|
* B is angle opposite b, between d and f
|
||
|
* C is angle opposite c, between e and f
|
||
|
*/
|
||
|
int trysolvetetra(int n, double a, double b, double c,
|
||
|
double A, double B, double C,
|
||
|
double *dr, double *er, double *fr)
|
||
|
{
|
||
|
double dguess;
|
||
|
double thresh = 0.000000000001;
|
||
|
double d, lastd;
|
||
|
double mind, maxd;
|
||
|
double d1, d2, d3;
|
||
|
double e, f;
|
||
|
int found;
|
||
|
|
||
|
lastd = 0.0/0.0; /* NaN */
|
||
|
mind = maxd = 0; /* Shut up compiler */
|
||
|
|
||
|
/* Find a bracket */
|
||
|
found = 0;
|
||
|
for (dguess = 0.0; dguess < 100.0; dguess+=DINCR) {
|
||
|
d = try(n, dguess, a, b, c, A, B, C) - dguess;
|
||
|
if (((d >= 0) && (lastd < 0)) || ((d <= 0) && (lastd > 0))) {
|
||
|
mind = dguess - DINCR;
|
||
|
maxd = dguess;
|
||
|
printf("Found bracket: (%f, %f)\n", mind, maxd);
|
||
|
found = 1;
|
||
|
break;
|
||
|
}
|
||
|
lastd = d;
|
||
|
}
|
||
|
if (!found)
|
||
|
return 0;
|
||
|
|
||
|
while ((maxd-mind) > thresh) {
|
||
|
d1 = try(n, mind, a, b, c, A, B, C) - mind;
|
||
|
d2 = try(n, (mind+maxd)/2, a, b, c, A, B, C) - (mind+maxd)/2;
|
||
|
d3 = try(n, maxd, a, b, c, A, B, C) - maxd;
|
||
|
if (((d2 >= 0) && (d1 < 0)) || ((d2 < 0) && (d1 >= 0)))
|
||
|
maxd = (mind+maxd)/2;
|
||
|
else
|
||
|
mind = (mind+maxd)/2;
|
||
|
}
|
||
|
|
||
|
d = (mind+maxd)/2;
|
||
|
|
||
|
getsolution(n, d, a, b, c, A, B, C, &e, &f);
|
||
|
|
||
|
printf("Found solution: (%f, %f, %f)\n", d, e, f);
|
||
|
|
||
|
*dr = d;
|
||
|
*er = e;
|
||
|
*fr = f;
|
||
|
|
||
|
if (!isfinite(d))
|
||
|
return 0;
|
||
|
if (!isfinite(e))
|
||
|
return 0;
|
||
|
if (!isfinite(f))
|
||
|
return 0;
|
||
|
if (d < 0)
|
||
|
return 0;
|
||
|
if (e < 0)
|
||
|
return 0;
|
||
|
if (f < 0)
|
||
|
return 0;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int solvetetra(double a, double b, double c,
|
||
|
double A, double B, double C,
|
||
|
double *dr, double *er, double *fr)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < 8; i++)
|
||
|
if (trysolvetetra(i, a, b, c, A, B, C, dr, er, fr))
|
||
|
return 1;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int map3d_calibrate(int light)
|
||
|
{
|
||
|
double v1[3], v2[3], v3[3], p4[3];
|
||
|
double angle1, angle2, angle3;
|
||
|
double a, b, c, d, e, f;
|
||
|
double pAB[3], pBC[3];
|
||
|
double axis1[3], axis2[3], axis3[3];
|
||
|
double axm1, axm2, axm3;
|
||
|
double hypot, alpha, beta, gamma, delta;
|
||
|
double sim[12][13];
|
||
|
double var[12];
|
||
|
double pv[3], tv[3];
|
||
|
int success, i;
|
||
|
|
||
|
/*
|
||
|
* First, create unit vectors in the directions of the
|
||
|
* pan & tilt values given
|
||
|
*/
|
||
|
unitvector(v1, map3d_cal[light].pan[0], map3d_cal[light].tilt[0]);
|
||
|
unitvector(v2, map3d_cal[light].pan[1], map3d_cal[light].tilt[1]);
|
||
|
unitvector(v3, map3d_cal[light].pan[2], map3d_cal[light].tilt[2]);
|
||
|
|
||
|
/*
|
||
|
* Now, we need the angles between them
|
||
|
*/
|
||
|
angle1 = acos(dotproduct(v1, v2));
|
||
|
angle2 = acos(dotproduct(v2, v3));
|
||
|
angle3 = acos(dotproduct(v3, v1));
|
||
|
|
||
|
printf("angles (%f, %f, %f)\n", DEG(angle1), DEG(angle2), DEG(angle3));
|
||
|
|
||
|
/*
|
||
|
* And the lengths of the edges which we know
|
||
|
*/
|
||
|
a = PYTHAG3(map3d_cal[light].cp[0], map3d_cal[light].cp[1]);
|
||
|
b = PYTHAG3(map3d_cal[light].cp[1], map3d_cal[light].cp[2]);
|
||
|
c = PYTHAG3(map3d_cal[light].cp[2], map3d_cal[light].cp[0]);
|
||
|
|
||
|
/* Solve the tetrahedron */
|
||
|
success = solvetetra(a, b, c, angle1, angle2, angle3, &d, &e, &f);
|
||
|
if (!success) {
|
||
|
printf("failed to solve tetrahedron\n");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* Multiply the vectors by their magnitudes */
|
||
|
for (i = 0; i < 3; i++) {
|
||
|
v1[i] *= e;
|
||
|
v2[i] *= d;
|
||
|
v3[i] *= f;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Find two vectors to define the triangle between
|
||
|
* the calibration points
|
||
|
*/
|
||
|
for (i = 0; i < 3; i++) {
|
||
|
pAB[i] = map3d_cal[light].cp[1][i]-map3d_cal[light].cp[0][i];
|
||
|
pBC[i] = map3d_cal[light].cp[2][i]-map3d_cal[light].cp[1][i];
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Create some perpendicular vectors in terms of which we can
|
||
|
* calculate a vector to the fourth point
|
||
|
*/
|
||
|
axis1[0] = pAB[0];
|
||
|
axis1[1] = pAB[1];
|
||
|
axis1[2] = pAB[2];
|
||
|
normalise(axis1);
|
||
|
crossproduct(axis1, pBC, axis2);
|
||
|
normalise(axis2);
|
||
|
crossproduct(axis1, axis2, axis3);
|
||
|
normalise(axis3);
|
||
|
|
||
|
/*
|
||
|
* Now we do some trigonometry to find out the distance to
|
||
|
* the fourth point in terms of the three axes
|
||
|
*/
|
||
|
beta = asin(d*sin(angle1)/a);
|
||
|
gamma = asin(f*sin(angle3)/c);
|
||
|
delta = acos(((a*a)+(c*c)-(b*b))/(2*a*c));
|
||
|
|
||
|
alpha = acos((cos(gamma)-cos(beta)*cos(delta))/(sin(beta)*sin(delta)));
|
||
|
|
||
|
hypot = e*sin(beta);
|
||
|
axm1 = e*cos(beta);
|
||
|
axm2 = hypot*sin(alpha);
|
||
|
axm3 = hypot*cos(alpha);
|
||
|
|
||
|
/* Now we have the magnitudes, let's get the vectors */
|
||
|
for (i = 0; i < 3; i++) {
|
||
|
axis1[i] *= axm1;
|
||
|
axis2[i] *= axm2;
|
||
|
axis3[i] *= axm3;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Now we can simply add these vectors to point A
|
||
|
* to get the fourth point
|
||
|
*/
|
||
|
for (i = 0; i < 3; i++)
|
||
|
p4[i] = map3d_cal[light].cp[0][i] + axis1[i] +
|
||
|
axis2[i] + axis3[i];
|
||
|
|
||
|
/*
|
||
|
* Now we can construct a matrix to represent 12 simultaneous
|
||
|
* equations, which we then solve to get our transformation matrix.
|
||
|
*/
|
||
|
bzero(sim, sizeof(sim));
|
||
|
|
||
|
/* First point */
|
||
|
sim[0][0] = map3d_cal[light].cp[0][0];
|
||
|
sim[0][1] = map3d_cal[light].cp[0][1];
|
||
|
sim[0][2] = map3d_cal[light].cp[0][2];
|
||
|
sim[0][9] = 1;
|
||
|
sim[0][12] = v1[0];
|
||
|
|
||
|
sim[1][3] = map3d_cal[light].cp[0][0];
|
||
|
sim[1][4] = map3d_cal[light].cp[0][1];
|
||
|
sim[1][5] = map3d_cal[light].cp[0][2];
|
||
|
sim[1][10] = 1;
|
||
|
sim[1][12] = v1[1];
|
||
|
|
||
|
sim[2][6] = map3d_cal[light].cp[0][0];
|
||
|
sim[2][7] = map3d_cal[light].cp[0][1];
|
||
|
sim[2][8] = map3d_cal[light].cp[0][2];
|
||
|
sim[2][11] = 1;
|
||
|
sim[2][12] = v1[2];
|
||
|
|
||
|
/* Second point */
|
||
|
sim[3][0] = map3d_cal[light].cp[1][0];
|
||
|
sim[3][1] = map3d_cal[light].cp[1][1];
|
||
|
sim[3][2] = map3d_cal[light].cp[1][2];
|
||
|
sim[3][9] = 1;
|
||
|
sim[3][12] = v2[0];
|
||
|
|
||
|
sim[4][3] = map3d_cal[light].cp[1][0];
|
||
|
sim[4][4] = map3d_cal[light].cp[1][1];
|
||
|
sim[4][5] = map3d_cal[light].cp[1][2];
|
||
|
sim[4][10] = 1;
|
||
|
sim[4][12] = v2[1];
|
||
|
|
||
|
sim[5][6] = map3d_cal[light].cp[1][0];
|
||
|
sim[5][7] = map3d_cal[light].cp[1][1];
|
||
|
sim[5][8] = map3d_cal[light].cp[1][2];
|
||
|
sim[5][11] = 1;
|
||
|
sim[5][12] = v2[2];
|
||
|
|
||
|
/* Third point */
|
||
|
sim[6][0] = map3d_cal[light].cp[2][0];
|
||
|
sim[6][1] = map3d_cal[light].cp[2][1];
|
||
|
sim[6][2] = map3d_cal[light].cp[2][2];
|
||
|
sim[6][9] = 1;
|
||
|
sim[6][12] = v3[0];
|
||
|
|
||
|
sim[7][3] = map3d_cal[light].cp[2][0];
|
||
|
sim[7][4] = map3d_cal[light].cp[2][1];
|
||
|
sim[7][5] = map3d_cal[light].cp[2][2];
|
||
|
sim[7][10] = 1;
|
||
|
sim[7][12] = v3[1];
|
||
|
|
||
|
sim[8][6] = map3d_cal[light].cp[2][0];
|
||
|
sim[8][7] = map3d_cal[light].cp[2][1];
|
||
|
sim[8][8] = map3d_cal[light].cp[2][2];
|
||
|
sim[8][11] = 1;
|
||
|
sim[8][12] = v3[2];
|
||
|
|
||
|
/* Fourth point */
|
||
|
sim[9][0] = p4[0];
|
||
|
sim[9][1] = p4[1];
|
||
|
sim[9][2] = p4[2];
|
||
|
sim[9][9] = 1;
|
||
|
sim[9][12] = 0;
|
||
|
|
||
|
sim[10][3] = p4[0];
|
||
|
sim[10][4] = p4[1];
|
||
|
sim[10][5] = p4[2];
|
||
|
sim[10][10] = 1;
|
||
|
sim[10][12] = 0;
|
||
|
|
||
|
sim[11][6] = p4[0];
|
||
|
sim[11][7] = p4[1];
|
||
|
sim[11][8] = p4[2];
|
||
|
sim[11][11] = 1;
|
||
|
sim[11][12] = 0;
|
||
|
|
||
|
eliminate(sim, var);
|
||
|
|
||
|
map3d_cal[light].M[0][0] = var[0];
|
||
|
map3d_cal[light].M[1][0] = var[1];
|
||
|
map3d_cal[light].M[2][0] = var[2];
|
||
|
map3d_cal[light].M[0][1] = var[3];
|
||
|
map3d_cal[light].M[1][1] = var[4];
|
||
|
map3d_cal[light].M[2][1] = var[5];
|
||
|
map3d_cal[light].M[0][2] = var[6];
|
||
|
map3d_cal[light].M[1][2] = var[7];
|
||
|
map3d_cal[light].M[2][2] = var[8];
|
||
|
map3d_cal[light].M[3][0] = var[9];
|
||
|
map3d_cal[light].M[3][1] = var[10];
|
||
|
map3d_cal[light].M[3][2] = var[11];
|
||
|
|
||
|
printf("%f\t%f\t%f\t\t%f\n", var[0], var[3], var[6], var[9]);
|
||
|
printf("%f\t%f\t%f\t\t%f\n", var[1], var[4], var[7], var[10]);
|
||
|
printf("%f\t%f\t%f\t\t%f\n", var[2], var[5], var[8], var[11]);
|
||
|
|
||
|
printf("Calibration points are:\n");
|
||
|
multiply(light, map3d_cal[light].cp[0], tv);
|
||
|
printf("(%f, %f, %f) => (%f, %f, %f)\n", map3d_cal[light].cp[0][0], map3d_cal[light].cp[0][1], map3d_cal[light].cp[0][2], tv[0], tv[1], tv[2]);
|
||
|
multiply(light, map3d_cal[light].cp[1], tv);
|
||
|
printf("(%f, %f, %f) => (%f, %f, %f)\n", map3d_cal[light].cp[1][0], map3d_cal[light].cp[1][1], map3d_cal[light].cp[1][2], tv[0], tv[1], tv[2]);
|
||
|
multiply(light, map3d_cal[light].cp[2], tv);
|
||
|
printf("(%f, %f, %f) => (%f, %f, %f)\n", map3d_cal[light].cp[2][0], map3d_cal[light].cp[2][1], map3d_cal[light].cp[2][2], tv[0], tv[1], tv[2]);
|
||
|
multiply(light, p4, tv);
|
||
|
printf("(%f, %f, %f) => (%f, %f, %f)\n", p4[0], p4[1], p4[2], tv[0], tv[1], tv[2]);
|
||
|
for (i = 0; i < 10; i++) {
|
||
|
pv[0] = 0;
|
||
|
pv[1] = (double)i/10.0;
|
||
|
pv[2] = 0;
|
||
|
multiply(light, pv, tv);
|
||
|
printf("(%f, %f, %f) => (%f, %f, %f)\n", pv[0], pv[1], pv[2], tv[0], tv[1], tv[2]);
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/* Set parameters based on position (x, y, z) and direction (tx, ty, tz) */
|
||
|
/* Temp: x, y = pan, tilt measured to (0, 0, 0)
|
||
|
tx, ty = pan, tilt of light fixture
|
||
|
tz = distance from light fixture to (0, 0, 0)
|
||
|
*/
|
||
|
void map3d_setparams(int light, int opan, int otilt, double lpan, double ltilt, double dist)
|
||
|
{
|
||
|
double n[3];
|
||
|
double up[3];
|
||
|
double right[3];
|
||
|
double v[3];
|
||
|
double op, ot;
|
||
|
|
||
|
op = PANRANGE * ((double)opan - PANOFFSET) / PANMAX;
|
||
|
ot = TILTRANGE * ((double)otilt - TILTOFFSET) / TILTMAX;
|
||
|
|
||
|
unitvector(v, op, ot);
|
||
|
unitvector(n, lpan, ltilt);
|
||
|
|
||
|
up[0] = 0;
|
||
|
up[1] = (n[1] + sqrt(n[1]*n[1]+4*n[2]*n[2])) /
|
||
|
(4*n[2]);
|
||
|
up[2] = -up[1]*n[1]/n[2];
|
||
|
normalise(up);
|
||
|
|
||
|
crossproduct(n, up, right);
|
||
|
normalise(right);
|
||
|
|
||
|
printf("n:\t%f\t%f\t%f\n", n[0], n[1], n[2]);
|
||
|
printf("up: \t%f\t%f\t%f\n", up[0], up[1], up[2]);
|
||
|
printf("right: \t%f\t%f\t%f\n", right[0], right[1], right[2]);
|
||
|
printf("\n");
|
||
|
|
||
|
/* Construct matrix */
|
||
|
|
||
|
map3d_cal[light].M[0][0] = right[0];
|
||
|
map3d_cal[light].M[0][1] = right[1];
|
||
|
map3d_cal[light].M[0][2] = right[2];
|
||
|
map3d_cal[light].M[1][0] = up[0];
|
||
|
map3d_cal[light].M[1][1] = up[1];
|
||
|
map3d_cal[light].M[1][2] = up[2];
|
||
|
map3d_cal[light].M[2][0] = n[0];
|
||
|
map3d_cal[light].M[2][1] = n[1];
|
||
|
map3d_cal[light].M[2][2] = n[2];
|
||
|
map3d_cal[light].M[3][0] = dist*v[0];
|
||
|
map3d_cal[light].M[3][1] = dist*v[1];
|
||
|
map3d_cal[light].M[3][2] = dist*v[2];
|
||
|
|
||
|
printf("\t%f\t%f\t%f\t\t%f\n", map3d_cal[light].M[0][0], map3d_cal[light].M[0][1], map3d_cal[light].M[0][2], map3d_cal[light].M[3][0]);
|
||
|
printf("\t%f\t%f\t%f\t\t%f\n", map3d_cal[light].M[1][0], map3d_cal[light].M[1][1], map3d_cal[light].M[1][2], map3d_cal[light].M[3][1]);
|
||
|
printf("\t%f\t%f\t%f\t\t%f\n", map3d_cal[light].M[2][0], map3d_cal[light].M[2][1], map3d_cal[light].M[2][2], map3d_cal[light].M[3][2]);
|
||
|
printf("\n");
|
||
|
|
||
|
}
|