/************************************************************************
* math_vector.c
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>
************************************************************************/

#include "common.h"

#include <math.h>

/* get a vector from start/end points */
void vect_create(v3_t *start, v3_t *end, v3_t *v)
{
	v->x = end->x - start->x;
	v->y = end->y - start->y;
	v->z = end->z - start->z;
	vect_normalise(v);
}

/* get the length of a vector */
float vect_length(v3_t *v)
{
	return sqrtf(v->x*v->x + v->y*v->y + v->z*v->z);
}

/* normalise a vector */
void vect_normalise(v3_t *v)
{
	float l;
	l= vect_length(v);
	if (l==0)
		l = 1;

	v->x/=l;
	v->y/=l;
	v->z/=l;
}

/* get the scalar product of vectors */
float vect_scalarproduct(v3_t *v1, v3_t *v2)
{
    return (v1->x*v2->x + v1->y*v2->y + v1->z*v2->z);
}

/* get the cross product of vectors */
void vect_crossproduct(v3_t *v1, v3_t *v2, v3_t *v3)
{
	v3->x=(v1->y*v2->z)-(v1->z*v2->y);
	v3->y=(v1->z*v2->x)-(v1->x*v2->z);
	v3->z=(v1->x*v2->y)-(v1->y*v2->x);
}

/* get the dot product of vectors */
void vect_dotproduct(v3_t *v1, v3_t *v2, v3_t *v3)
{
	v3->x=(v1->y*v2->z)+(v1->z*v2->y);
	v3->y=(v1->z*v2->x)+(v1->x*v2->z);
	v3->z=(v1->x*v2->y)+(v1->y*v2->x);
}

/* subtract a vector from a vector */
void vect_subtract(v3_t *v1, v3_t *v2, v3_t *v3)
{
	v3->x = (v1->x-v2->x);
	v3->y = (v1->y-v2->y);
	v3->z = (v1->z-v2->z);
}

/* get the diameter of a vector */
float vect_diameter(v3_t *v)
{
	return sqrtf(vect_scalarproduct(v,v));
}

/* get the dot product of vectors */
float math_dotproduct(v3_t *v1, v3_t *v2)
{
	return (v1->x*v2->x + v1->y*v2->y + v1->z*v2->z);
}

/* get the distance between two points */
float math_distance(v3_t *v1, v3_t *v2)
{
	float xd = v2->x-v1->x;
	float yd = v2->y-v1->y;
	float zd = v2->z-v1->z;

	if (xd < 0.0)
		xd *= -1.0;
	if (yd < 0.0)
		yd *= -1.0;
	if (zd < 0.0)
		zd *= -1.0;

	return sqrtf(xd*xd + yd*yd + zd*zd);
}
