Files
sics/vector.c
Ferdi Franceschini 10d29d597c Cleaned up ANSTO code to merge with sinqdev.sics
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c
Conflicts:
	.gitignore
	SICSmain.c
	asynnet.c
	confvirtualmot.c
	counter.c
	devexec.c
	drive.c
	event.h
	exebuf.c
	exeman.c
	histmem.c
	interface.h
	motor.c
	motorlist.c
	motorsec.c
	multicounter.c
	napi.c
	napi.h
	napi4.c
	network.c
	nwatch.c
	nxscript.c
	nxxml.c
	nxxml.h
	ofac.c
	reflist.c
	scan.c
	sicshipadaba.c
	sicsobj.c
	site_ansto/docs/Copyright.txt
	site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl
	site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl
	statusfile.c
	tasdrive.c
	tasub.c
	tasub.h
	tasublib.c
	tasublib.h
2015-04-23 20:49:26 +10:00

233 lines
5.2 KiB
C

/**
* This is a little collection of vector functions for use with the UB
* calculation routines. Therefore vectors are mapped onto the matrix
* package. Strictly speaking all routines only work properly on 3D
* vectors.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, March 2005
*/
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "vector.h"
#include "trigd.h"
/*----------------------------------------------------------------------*/
MATRIX makeVector()
{
return mat_creat(3, 1, ZERO_MATRIX);
}
/*---------------------------------------------------------------------*/
MATRIX makeVectorInit(double val[3])
{
int i;
MATRIX result = NULL;
result = makeVector();
if (result == NULL) {
return result;
}
for (i = 0; i < 3; i++) {
result[i][0] = val[i];
}
return result;
}
/*---------------------------------------------------------------------*/
void vectorToArray(MATRIX v, double val[3])
{
int i;
assert(MatCol(v) == 3);
for (i = 0; i < 3; i++) {
val[i] = v[i][0];
}
}
/*----------------------------------------------------------------------*/
void killVector(MATRIX v)
{
mat_free(v);
}
/*----------------------------------------------------------------------*/
void vectorSet(MATRIX v, int idx, double value)
{
assert(idx >= 0 && idx < 3);
v[idx][0] = value;
}
/*----------------------------------------------------------------------*/
double vectorGet(MATRIX v, int idx)
{
assert(idx >= 0 && idx < 3);
return v[idx][0];
}
/*----------------------------------------------------------------------*/
double vectorLength(MATRIX v)
{
assert(MatRow(v) == 3);
return sqrt(v[0][0] * v[0][0] + v[1][0] * v[1][0] + v[2][0] * v[2][0]);
}
/*---------------------------------------------------------------------*/
void normalizeVector(MATRIX v)
{
int i;
double norm;
norm = vectorLength(v);
if (norm > .00001) {
for (i = 0; i < 3; i++) {
v[i][0] /= norm;
}
} else {
for (i = 0; i < 3; i++) {
v[i][0] = .0;
}
}
}
/*----------------------------------------------------------------------*/
double vectorDotProduct(MATRIX v1, MATRIX v2)
{
double sum;
int i;
assert(MatRow(v1) == MatRow(v2));
sum = .0;
for (i = 0; i < MatRow(v1); i++) {
sum += v1[i][0] * v2[i][0];
}
return sum;
}
/*----------------------------------------------------------------------*/
MATRIX vectorCrossProduct(MATRIX v1, MATRIX v2)
{
MATRIX result;
assert(MatRow(v1) == 3);
assert(MatRow(v2) == 3);
result = makeVector();
if (result == NULL) {
return NULL;
}
vectorSet(result, 0,
vectorGet(v1, 1) * vectorGet(v2, 2)
- vectorGet(v1,2) * vectorGet(v2, 1));
vectorSet(result, 1,
vectorGet(v1, 2) * vectorGet(v2, 0)
- vectorGet(v1,0) * vectorGet(v2, 2));
vectorSet(result, 2,
vectorGet(v1, 0) * vectorGet(v2, 1)
- vectorGet(v1, 1) * vectorGet(v2, 0));
return result;
}
/*-------------------------------------------------------------------------*/
MATRIX matFromTwoVectors(MATRIX v1, MATRIX v2)
{
MATRIX a1, a2, a3, result;
int i;
a1 = mat_copy(v1);
if (a1 == NULL) {
return NULL;
}
normalizeVector(a1);
a3 = vectorCrossProduct(v1, v2);
if (a3 == NULL) {
return NULL;
}
normalizeVector(a3);
a2 = vectorCrossProduct(a1, a3);
if (a2 == NULL) {
return NULL;
}
result = mat_creat(3, 3, ZERO_MATRIX);
if (result == NULL) {
return NULL;
}
for (i = 0; i < 3; i++) {
result[i][0] = vectorGet(a1, i);
result[i][1] = vectorGet(a2, i);
result[i][2] = vectorGet(a3, i);
}
killVector(a1);
killVector(a2);
killVector(a3);
return result;
}
/*-----------------------------------------------------------------------*/
double angleBetween(MATRIX v1, MATRIX v2)
{
double angle, angles;
MATRIX v3 = NULL;
angle = vectorDotProduct(v1, v2) / (vectorLength(v1) * vectorLength(v2));
v3 = vectorCrossProduct(v1, v2);
if (v3 != NULL) {
angles = vectorLength(v3) / (vectorLength(v1) * vectorLength(v2));
angle = Atan2d(angles, angle);
} else {
angle = Acosd(angle);
}
return angle;
}
/*-----------------------------------------------------------------------
angleBetween gives only angles between 0 - 180. This is also the
only thing there is; the direction of the rotation depends on the
viewpoint and thus is ill defined. This version determines the
sign of the rotation from v3[2]. I made a special version in order not
to trouble other uses of angleBetween.
-----------------------------------------------------------------------*/
double tasAngleBetween(MATRIX v1, MATRIX v2)
{
double angle, angles, sum;
MATRIX v3 = NULL;
int i;
angle = vectorDotProduct(v1, v2) / (vectorLength(v1) * vectorLength(v2));
v3 = vectorCrossProduct(v1, v2);
if (v3 != NULL) {
angles = vectorLength(v3) / (vectorLength(v1) * vectorLength(v2));
angle = Atan2d(angles, angle);
for(i = 0, sum = .0; i < 3; i++){
sum += v3[i][0];
}
if(sum < 0){
angle *= -1.;
}
} else {
angle = Acosd(angle);
}
return angle;
}
/*----------------------------------------------------------------------*/
void scaleVector(MATRIX v, double scale)
{
int i;
for (i = 0; i < 3; i++) {
v[i][0] *= scale;
}
}