File: vector.c

package info (click to toggle)
s3d 0.2.2.1-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,356 kB
  • sloc: ansic: 21,128; python: 488; perl: 98; makefile: 31; sh: 29
file content (108 lines) | stat: -rw-r--r-- 3,693 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// SPDX-License-Identifier: LGPL-2.1-or-later
/* SPDX-FileCopyrightText: 2004-2015  Simon Wunderlich <sw@simonwunderlich.de>
 * SPDX-FileCopyrightText: 2004-2015  Marek Lindner <mareklindner@neomailbox.ch>
 * SPDX-FileCopyrightText: 2004-2015  Andreas Langer <an.langer@gmx.de>
 */

#include <math.h>  /* sqrt() */
#include "s3d.h"

/** \brief calculate length of vector
 *
 * Calculates and returns the length of the given vector (which should be of the
 * type float[3]). More info on wikipedia
 * http://en.wikipedia.org/wiki/Vector_(spatial)
 */
float s3d_vector_length(const float vector[])
{

	return sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]);

}

/** \brief subtract two vectors
 *
 * Subtracts vector1 from vector2, writing result into result_vector. All vectors
 * should have the format float[3]. More info on wikipedia.
 * http://en.wikipedia.org/wiki/Vector_(spatial)
 */
void s3d_vector_subtract(const float vector1[], const float vector2[], float result_vector[])
{

	result_vector[0] = vector2[0] - vector1[0];
	result_vector[1] = vector2[1] - vector1[1];
	result_vector[2] = vector2[2] - vector1[2];

}

/** \brief calculate dot product of two vectors
 *
 * Calculates and returns the dot product of vector1 and vector2. All vectors
 * should have the format float[3]. More info on wikipedia.
 * http://en.wikipedia.org/wiki/Vector_(spatial)
 */
float s3d_vector_dot_product(const float vector1[], const float vector2[])
{
	return vector1[0] * vector2[0] + vector1[1] * vector2[1] + vector1[2] * vector2[2];
}

/** \brief calculate cross product of two vectors
 *
 * Calculates and returns the cross product of vector1 and vector2. All vectors
 * should have the format float[3]. More info on wikipedia.
 * http://en.wikipedia.org/wiki/Vector_(spatial)
 */
void s3d_vector_cross_product(const float vector1[], const float vector2[], float result_vector[])
{
	result_vector[0] = vector1[1] * vector2[2] - vector1[2] * vector2[1];
	result_vector[1] = vector1[2] * vector2[0] - vector1[0] * vector2[2];
	result_vector[2] = vector1[0] * vector2[1] - vector1[1] * vector2[0];
}

/** \brief calculate angle between two vectors
 *
 * Calculates and returns the angle between vector1 and vector2. Please note that
 * the resulting angle is between 0 and PI, therefore not covering the whole
 * period! To convert in degrees just do result*180/M_PI. All vectors should
 * have the format float[3]. More info on wikipedia.
 * http://en.wikipedia.org/wiki/Vector_(spatial)
 */
float s3d_vector_angle(const float vector1[], const float vector2[])
{

	return acos(s3d_vector_dot_product(vector1, vector2) / (s3d_vector_length(vector1) * s3d_vector_length(vector2)));

}

/** \brief calculate angle between vector and cam
 *
 * Given obj_pos and cam_pos in the format float[3], angle_rad about which angle
 * the object should be rotated around the y-axis so that it faces the camera.
 * This might become handy if you have some text floating in space and want it
 * to face the camera.
 * http://en.wikipedia.org/wiki/Vector_(spatial)
 */
float s3d_angle_to_cam(const float obj_pos[], const float cam_pos[], float *angle_rad)
{

	float angle, tmp_mov_vec[3], desc_norm_vec[3] = { 0.0, 0.0, -1.0 };


	tmp_mov_vec[0] = cam_pos[0] - obj_pos[0];
	tmp_mov_vec[1] = 0;   /* we are not interested in the y value */
	tmp_mov_vec[2] = cam_pos[2] - obj_pos[2];

	angle = s3d_vector_angle(desc_norm_vec, tmp_mov_vec);

	/* take care of inverse cosinus */
	if (tmp_mov_vec[0] > 0) {
		*angle_rad = 90.0 / M_PI - angle;
		angle = 180 - (180.0 / M_PI * angle);
	} else {
		*angle_rad = 90.0 / M_PI + angle;
		angle = 180 + (180.0 / M_PI * angle);
	}

	return angle;

}