| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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 2 | 
					
						
							|  |  |  |  * 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, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							| 
									
										
										
										
											2012-03-25 15:56:17 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  |  * The Original Code is: some of this file. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 20:37:56 +00:00
										 |  |  | /** \file blender/blenlib/intern/math_vector.c
 | 
					
						
							|  |  |  |  *  \ingroup bli | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_math.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | //******************************* Interpolation *******************************/
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | void interp_v2_v2v2(float target[2], const float a[2], const float b[2], const float t) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float s = 1.0f - t; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	target[0] = s * a[0] + t * b[0]; | 
					
						
							|  |  |  | 	target[1] = s * a[1] + t * b[1]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* weight 3 2D vectors,
 | 
					
						
							|  |  |  |  * 'w' must be unit length but is not a vector, just 3 weights */ | 
					
						
							| 
									
										
										
										
											2009-12-27 01:32:58 +00:00
										 |  |  | void interp_v2_v2v2v2(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2]; | 
					
						
							|  |  |  | 	p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-27 01:32:58 +00:00
										 |  |  | void interp_v3_v3v3(float target[3], const float a[3], const float b[3], const float t) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float s = 1.0f - t; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	target[0] = s * a[0] + t * b[0]; | 
					
						
							|  |  |  | 	target[1] = s * a[1] + t * b[1]; | 
					
						
							|  |  |  | 	target[2] = s * a[2] + t * b[2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-24 17:52:51 +00:00
										 |  |  | void interp_v4_v4v4(float target[4], const float a[4], const float b[4], const float t) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float s = 1.0f - t; | 
					
						
							| 
									
										
										
										
											2010-03-24 17:52:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	target[0] = s * a[0] + t * b[0]; | 
					
						
							|  |  |  | 	target[1] = s * a[1] + t * b[1]; | 
					
						
							|  |  |  | 	target[2] = s * a[2] + t * b[2]; | 
					
						
							|  |  |  | 	target[3] = s * a[3] + t * b[3]; | 
					
						
							| 
									
										
										
										
											2010-03-24 17:52:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | /* weight 3 vectors,
 | 
					
						
							|  |  |  |  * 'w' must be unit length but is not a vector, just 3 weights */ | 
					
						
							| 
									
										
										
										
											2009-12-27 01:32:58 +00:00
										 |  |  | void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2]; | 
					
						
							|  |  |  | 	p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2]; | 
					
						
							|  |  |  | 	p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-21 14:35:28 +00:00
										 |  |  | /* weight 3 vectors,
 | 
					
						
							| 
									
										
										
										
											2010-01-14 10:59:42 +00:00
										 |  |  |  * 'w' must be unit length but is not a vector, just 4 weights */ | 
					
						
							| 
									
										
										
										
											2009-12-27 01:32:58 +00:00
										 |  |  | void interp_v3_v3v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float w[4]) | 
					
						
							| 
									
										
										
										
											2009-11-21 14:35:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2] + v4[0] * w[3]; | 
					
						
							|  |  |  | 	p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2] + v4[1] * w[3]; | 
					
						
							|  |  |  | 	p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2] + v4[2] * w[3]; | 
					
						
							| 
									
										
										
										
											2009-11-21 14:35:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float w[3]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2]; | 
					
						
							|  |  |  | 	p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2]; | 
					
						
							|  |  |  | 	p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2]; | 
					
						
							|  |  |  | 	p[3] = v1[3] * w[0] + v2[3] * w[1] + v3[3] * w[2]; | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | void interp_v4_v4v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float v4[4], const float w[4]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2] + v4[0] * w[3]; | 
					
						
							|  |  |  | 	p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2] + v4[1] * w[3]; | 
					
						
							|  |  |  | 	p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2] + v4[2] * w[3]; | 
					
						
							|  |  |  | 	p[3] = v1[3] * w[0] + v2[3] * w[1] + v3[3] * w[2] + v4[3] * w[3]; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | void mid_v3_v3v3(float v[3], const float v1[3], const float v2[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	v[0] = 0.5f * (v1[0] + v2[0]); | 
					
						
							|  |  |  | 	v[1] = 0.5f * (v1[1] + v2[1]); | 
					
						
							|  |  |  | 	v[2] = 0.5f * (v1[2] + v2[2]); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-11 07:47:09 +00:00
										 |  |  | void mid_v2_v2v2(float v[2], const float v1[2], const float v2[2]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	v[0] = 0.5f * (v1[0] + v2[0]); | 
					
						
							|  |  |  | 	v[1] = 0.5f * (v1[1] + v2[1]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | /********************************** Angles ***********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Return the angle in radians between vecs 1-2 and 2-3 in radians
 | 
					
						
							| 
									
										
										
										
											2012-02-17 17:47:10 +00:00
										 |  |  |  * If v1 is a shoulder, v2 is the elbow and v3 is the hand, | 
					
						
							|  |  |  |  * this would return the angle at the elbow. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * note that when v1/v2/v3 represent 3 points along a straight line | 
					
						
							|  |  |  |  * that the angle returned will be pi (180deg), rather then 0.0 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | float angle_v3v3v3(const float v1[3], const float v2[3], const float v3[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float vec1[3], vec2[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sub_v3_v3v3(vec1, v2, v1); | 
					
						
							|  |  |  | 	sub_v3_v3v3(vec2, v2, v3); | 
					
						
							|  |  |  | 	normalize_v3(vec1); | 
					
						
							|  |  |  | 	normalize_v3(vec2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return angle_normalized_v3v3(vec1, vec2); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Fix [#31807] Ngon triangulation error
Notes:
*This implements a quite simple algorithm, which simply checks angles (actually, absolute cosines) of created tri and remaining face (which may be a tri, quad, or more NGon), so that both are "best" (ie avoid as much as possible too much narrow/wide corners), and also checks the new edge is OK (i.e. does not goes "out" of original face).
*Incidently, it fixes a typo in that bm_face_goodline() func!
*It's quite performant (a bit quicker than previous code, as far as I have tested it) and prevent creation of completely flat triangles as much as possible, but it's far from being a "best" solution (as it is still a "progressive" one)!
*It also introduces a new math func (in BLI_math_vector.h), cos_v3v3v3, which computes cosine (ie dot product of normalized vectors) and is roughly a quicker replacement for angle_v3v3v3, when real angles are not needed.
											
										 
											2012-06-24 16:19:19 +00:00
										 |  |  | /* Quicker than full angle computation */ | 
					
						
							|  |  |  | float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float vec1[3], vec2[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sub_v3_v3v3(vec1, p2, p1); | 
					
						
							|  |  |  | 	sub_v3_v3v3(vec2, p2, p3); | 
					
						
							|  |  |  | 	normalize_v3(vec1); | 
					
						
							|  |  |  | 	normalize_v3(vec2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return dot_v3v3(vec1, vec2); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-22 19:56:12 +00:00
										 |  |  | /* Return the shortest angle in radians between the 2 vectors */ | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | float angle_v3v3(const float v1[3], const float v2[3]) | 
					
						
							| 
									
										
										
										
											2009-12-22 19:56:12 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float vec1[3], vec2[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-15 15:14:08 +00:00
										 |  |  | 	normalize_v3_v3(vec1, v1); | 
					
						
							|  |  |  | 	normalize_v3_v3(vec2, v2); | 
					
						
							| 
									
										
										
										
											2009-12-22 19:56:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return angle_normalized_v3v3(vec1, vec2); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | float angle_v2v2v2(const float v1[2], const float v2[2], const float v3[2]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float vec1[2], vec2[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	vec1[0] = v2[0] - v1[0]; | 
					
						
							|  |  |  | 	vec1[1] = v2[1] - v1[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vec2[0] = v2[0] - v3[0]; | 
					
						
							|  |  |  | 	vec2[1] = v2[1] - v3[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	normalize_v2(vec1); | 
					
						
							|  |  |  | 	normalize_v2(vec2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return angle_normalized_v2v2(vec1, vec2); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Return the shortest angle in radians between the 2 vectors */ | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | float angle_v2v2(const float v1[2], const float v2[2]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-22 19:56:12 +00:00
										 |  |  | 	float vec1[2], vec2[2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-22 19:56:12 +00:00
										 |  |  | 	vec1[0] = v1[0]; | 
					
						
							|  |  |  | 	vec1[1] = v1[1]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-22 19:56:12 +00:00
										 |  |  | 	vec2[0] = v2[0]; | 
					
						
							|  |  |  | 	vec2[1] = v2[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	normalize_v2(vec1); | 
					
						
							|  |  |  | 	normalize_v2(vec2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return angle_normalized_v2v2(vec1, vec2); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-14 06:14:15 +00:00
										 |  |  | float angle_signed_v2v2(const float v1[2], const float v2[2]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const float perp_dot = (v1[1] * v2[0]) - (v1[0] * v2[1]); | 
					
						
							|  |  |  | 	return atan2f(perp_dot, dot_v2v2(v1, v2)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-27 01:32:58 +00:00
										 |  |  | float angle_normalized_v3v3(const float v1[3], const float v2[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */ | 
					
						
							|  |  |  | 	if (dot_v3v3(v1, v2) < 0.0f) { | 
					
						
							|  |  |  | 		float vec[3]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		vec[0] = -v2[0]; | 
					
						
							|  |  |  | 		vec[1] = -v2[1]; | 
					
						
							|  |  |  | 		vec[2] = -v2[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return (float)M_PI - 2.0f * (float)saasin(len_v3v3(vec, v1) / 2.0f); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		return 2.0f * (float)saasin(len_v3v3(v2, v1) / 2.0f); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | float angle_normalized_v2v2(const float v1[2], const float v2[2]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */ | 
					
						
							|  |  |  | 	if (dot_v2v2(v1, v2) < 0.0f) { | 
					
						
							|  |  |  | 		float vec[2]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		vec[0] = -v2[0]; | 
					
						
							|  |  |  | 		vec[1] = -v2[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return (float)M_PI - 2.0f * saasin(len_v2v2(vec, v1) / 2.0f); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		return 2.0f * (float)saasin(len_v2v2(v2, v1) / 2.0f); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-29 10:44:00 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * angle between 2 vectors defined by 3 coords, about an axis. */ | 
					
						
							|  |  |  | float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float v1_proj[3], v2_proj[3], tproj[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sub_v3_v3v3(v1_proj, v1, v2); | 
					
						
							|  |  |  | 	sub_v3_v3v3(v2_proj, v3, v2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* project the vectors onto the axis */ | 
					
						
							|  |  |  | 	project_v3_v3v3(tproj, v1_proj, axis); | 
					
						
							|  |  |  | 	sub_v3_v3(v1_proj, tproj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	project_v3_v3v3(tproj, v2_proj, axis); | 
					
						
							|  |  |  | 	sub_v3_v3(v2_proj, tproj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return angle_v3v3(v1_proj, v2_proj); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 09:39:46 +00:00
										 |  |  | void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float ed1[3], ed2[3], ed3[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sub_v3_v3v3(ed1, v3, v1); | 
					
						
							|  |  |  | 	sub_v3_v3v3(ed2, v1, v2); | 
					
						
							|  |  |  | 	sub_v3_v3v3(ed3, v2, v3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	normalize_v3(ed1); | 
					
						
							|  |  |  | 	normalize_v3(ed2); | 
					
						
							|  |  |  | 	normalize_v3(ed3); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	angles[0] = (float)M_PI - angle_normalized_v3v3(ed1, ed2); | 
					
						
							|  |  |  | 	angles[1] = (float)M_PI - angle_normalized_v3v3(ed2, ed3); | 
					
						
							| 
									
										
										
										
											2009-12-15 09:39:46 +00:00
										 |  |  | 	// face_angles[2] = M_PI - angle_normalized_v3v3(ed3, ed1);
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	angles[2] = (float)M_PI - (angles[0] + angles[1]); | 
					
						
							| 
									
										
										
										
											2009-12-15 09:39:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float ed1[3], ed2[3], ed3[3], ed4[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sub_v3_v3v3(ed1, v4, v1); | 
					
						
							|  |  |  | 	sub_v3_v3v3(ed2, v1, v2); | 
					
						
							|  |  |  | 	sub_v3_v3v3(ed3, v2, v3); | 
					
						
							|  |  |  | 	sub_v3_v3v3(ed4, v3, v4); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	normalize_v3(ed1); | 
					
						
							|  |  |  | 	normalize_v3(ed2); | 
					
						
							|  |  |  | 	normalize_v3(ed3); | 
					
						
							|  |  |  | 	normalize_v3(ed4); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	angles[0] = (float)M_PI - angle_normalized_v3v3(ed1, ed2); | 
					
						
							|  |  |  | 	angles[1] = (float)M_PI - angle_normalized_v3v3(ed2, ed3); | 
					
						
							|  |  |  | 	angles[2] = (float)M_PI - angle_normalized_v3v3(ed3, ed4); | 
					
						
							|  |  |  | 	angles[3] = (float)M_PI - angle_normalized_v3v3(ed4, ed1); | 
					
						
							| 
									
										
										
										
											2009-12-15 09:39:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 02:24:01 +00:00
										 |  |  | void angle_poly_v3(float *angles, const float *verts[3], int len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	float vec[3][3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	sub_v3_v3v3(vec[2], verts[len - 1], verts[0]); | 
					
						
							| 
									
										
										
										
											2012-01-20 02:24:01 +00:00
										 |  |  | 	normalize_v3(vec[2]); | 
					
						
							|  |  |  | 	for (i = 0; i < len; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		sub_v3_v3v3(vec[i % 3], verts[i % len], verts[(i + 1) % len]); | 
					
						
							|  |  |  | 		normalize_v3(vec[i % 3]); | 
					
						
							|  |  |  | 		angles[i] = (float)M_PI - angle_normalized_v3v3(vec[(i + 2) % 3], vec[i % 3]); | 
					
						
							| 
									
										
										
										
											2012-01-20 02:24:01 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | /********************************* Geometry **********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-11 21:27:39 +00:00
										 |  |  | /* Project v1 on v2 */ | 
					
						
							|  |  |  | void project_v2_v2v2(float c[2], const float v1[2], const float v2[2]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float mul; | 
					
						
							|  |  |  | 	mul = dot_v2v2(v1, v2) / dot_v2v2(v2, v2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	c[0] = mul * v2[0]; | 
					
						
							|  |  |  | 	c[1] = mul * v2[1]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | /* Project v1 on v2 */ | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | void project_v3_v3v3(float c[3], const float v1[3], const float v2[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float mul; | 
					
						
							|  |  |  | 	mul = dot_v3v3(v1, v2) / dot_v3v3(v2, v2); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	c[0] = mul * v2[0]; | 
					
						
							|  |  |  | 	c[1] = mul * v2[1]; | 
					
						
							|  |  |  | 	c[2] = mul * v2[2]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 19:02:28 +00:00
										 |  |  | /* project a vector on a plane defined by normal and a plane point p */ | 
					
						
							|  |  |  | void project_v3_plane(float v[3], const float n[3], const float p[3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float vector[3]; | 
					
						
							|  |  |  | 	float mul; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sub_v3_v3v3(vector, v, p); | 
					
						
							| 
									
										
										
										
											2012-03-26 00:42:21 +00:00
										 |  |  | 	mul = dot_v3v3(vector, n) / len_squared_v3(n); | 
					
						
							| 
									
										
										
										
											2012-03-25 19:02:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mul_v3_v3fl(vector, n, mul); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sub_v3_v3(v, vector); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | /* Returns a vector bisecting the angle at v2 formed by v1, v2 and v3 */ | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | void bisect_v3_v3v3v3(float out[3], const float v1[3], const float v2[3], const float v3[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float d_12[3], d_23[3]; | 
					
						
							|  |  |  | 	sub_v3_v3v3(d_12, v2, v1); | 
					
						
							|  |  |  | 	sub_v3_v3v3(d_23, v3, v2); | 
					
						
							|  |  |  | 	normalize_v3(d_12); | 
					
						
							|  |  |  | 	normalize_v3(d_23); | 
					
						
							|  |  |  | 	add_v3_v3v3(out, d_12, d_23); | 
					
						
							|  |  |  | 	normalize_v3(out); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Returns a reflection vector from a vector and a normal vector
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:19:11 +00:00
										 |  |  |  * reflect = vec - ((2 * DotVecs(vec, mirror)) * mirror) | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | void reflect_v3_v3v3(float out[3], const float v1[3], const float v2[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float vec[3], normal[3]; | 
					
						
							|  |  |  | 	float reflect[3] = {0.0f, 0.0f, 0.0f}; | 
					
						
							|  |  |  | 	float dot2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	copy_v3_v3(vec, v1); | 
					
						
							|  |  |  | 	copy_v3_v3(normal, v2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dot2 = 2 * dot_v3v3(vec, normal); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	reflect[0] = vec[0] - (dot2 * normal[0]); | 
					
						
							|  |  |  | 	reflect[1] = vec[1] - (dot2 * normal[1]); | 
					
						
							|  |  |  | 	reflect[2] = vec[2] - (dot2 * normal[2]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	copy_v3_v3(out, reflect); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | void ortho_basis_v3v3_v3(float v1[3], float v2[3], const float v[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	const float f = (float)sqrt(v[0] * v[0] + v[1] * v[1]); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (f < 1e-35f) { | 
					
						
							|  |  |  | 		// degenerate case
 | 
					
						
							|  |  |  | 		v1[0] = (v[2] < 0.0f) ? -1.0f : 1.0f; | 
					
						
							|  |  |  | 		v1[1] = v1[2] = v2[0] = v2[2] = 0.0f; | 
					
						
							|  |  |  | 		v2[1] = 1.0f; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	else { | 
					
						
							|  |  |  | 		const float d = 1.0f / f; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		v1[0] = v[1] * d; | 
					
						
							|  |  |  | 		v1[1] = -v[0] * d; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 		v1[2] = 0.0f; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		v2[0] = -v[2] * v1[1]; | 
					
						
							|  |  |  | 		v2[1] = v[2] * v1[0]; | 
					
						
							|  |  |  | 		v2[2] = v[0] * v1[1] - v[1] * v1[0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-29 05:15:55 +00:00
										 |  |  | /* Rotate a point p by angle theta around an arbitrary axis r
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:19:11 +00:00
										 |  |  |  * http://local.wasp.uwa.edu.au/~pbourke/geometry/
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-09-29 05:15:55 +00:00
										 |  |  | void rotate_normalized_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	const float costheta = cos(angle); | 
					
						
							|  |  |  | 	const float sintheta = sin(angle); | 
					
						
							| 
									
										
										
										
											2010-09-29 05:15:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	r[0] = ((costheta + (1 - costheta) * axis[0] * axis[0]) * p[0]) + | 
					
						
							| 
									
										
										
										
											2012-03-25 15:56:17 +00:00
										 |  |  | 	       (((1 - costheta) * axis[0] * axis[1] - axis[2] * sintheta) * p[1]) + | 
					
						
							|  |  |  | 	       (((1 - costheta) * axis[0] * axis[2] + axis[1] * sintheta) * p[2]); | 
					
						
							| 
									
										
										
										
											2010-09-29 05:15:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	r[1] = (((1 - costheta) * axis[0] * axis[1] + axis[2] * sintheta) * p[0]) + | 
					
						
							| 
									
										
										
										
											2012-03-25 15:56:17 +00:00
										 |  |  | 	       ((costheta + (1 - costheta) * axis[1] * axis[1]) * p[1]) + | 
					
						
							|  |  |  | 	       (((1 - costheta) * axis[1] * axis[2] - axis[0] * sintheta) * p[2]); | 
					
						
							| 
									
										
										
										
											2010-09-29 05:15:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	r[2] = (((1 - costheta) * axis[0] * axis[2] - axis[1] * sintheta) * p[0]) + | 
					
						
							| 
									
										
										
										
											2012-03-25 15:56:17 +00:00
										 |  |  | 	       (((1 - costheta) * axis[1] * axis[2] + axis[0] * sintheta) * p[1]) + | 
					
						
							|  |  |  | 	       ((costheta + (1 - costheta) * axis[2] * axis[2]) * p[2]); | 
					
						
							| 
									
										
										
										
											2010-09-29 05:15:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float axis_n[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	normalize_v3_v3(axis_n, axis); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rotate_normalized_v3_v3v3fl(r, p, axis_n, angle); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | /*********************************** Other ***********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-25 08:31:52 +00:00
										 |  |  | void print_v2(const char *str, const float v[2]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	printf("%s: %.3f %.3f\n", str, v[0], v[1]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-25 08:31:52 +00:00
										 |  |  | void print_v3(const char *str, const float v[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	printf("%s: %.3f %.3f %.3f\n", str, v[0], v[1], v[2]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-25 08:31:52 +00:00
										 |  |  | void print_v4(const char *str, const float v[4]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	printf("%s: %.3f %.3f %.3f %.3f\n", str, v[0], v[1], v[2], v[3]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-28 11:48:13 +00:00
										 |  |  | void minmax_v3v3_v3(float min[3], float max[3], const float vec[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	if (min[0] > vec[0]) min[0] = vec[0]; | 
					
						
							|  |  |  | 	if (min[1] > vec[1]) min[1] = vec[1]; | 
					
						
							|  |  |  | 	if (min[2] > vec[2]) min[2] = vec[2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	if (max[0] < vec[0]) max[0] = vec[0]; | 
					
						
							|  |  |  | 	if (max[1] < vec[1]) max[1] = vec[1]; | 
					
						
							|  |  |  | 	if (max[2] < vec[2]) max[2] = vec[2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-27 09:44:56 +00:00
										 |  |  | /** ensure \a v1 is \a dist from \a v2 */ | 
					
						
							|  |  |  | void dist_ensure_v3_v3fl(float v1[3], const float v2[3], const float dist) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!equals_v3v3(v2, v1)) { | 
					
						
							|  |  |  | 		float nor[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sub_v3_v3v3(nor, v1, v2); | 
					
						
							|  |  |  | 		normalize_v3(nor); | 
					
						
							|  |  |  | 		madd_v3_v3v3fl(v1, v2, nor, dist); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void dist_ensure_v2_v2fl(float v1[2], const float v2[2], const float dist) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!equals_v2v2(v2, v1)) { | 
					
						
							|  |  |  | 		float nor[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sub_v2_v2v2(nor, v1, v2); | 
					
						
							|  |  |  | 		normalize_v2(nor); | 
					
						
							|  |  |  | 		madd_v2_v2v2fl(v1, v2, nor, dist); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-20 09:18:55 +00:00
										 |  |  | /***************************** Array Functions *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-24 04:12:16 +00:00
										 |  |  | double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	double d = 0.0f; | 
					
						
							|  |  |  | 	const float *array_pt_a = array_src_a + (size - 1); | 
					
						
							|  |  |  | 	const float *array_pt_b = array_src_b + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		d += *(array_pt_a--) * *(array_pt_b--); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-11-24 04:12:16 +00:00
										 |  |  | 	return d; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float normalize_vn_vn(float *array_tar, const float *array_src, const int size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	double d = dot_vn_vn(array_tar, array_src, size); | 
					
						
							| 
									
										
										
										
											2011-11-24 04:12:16 +00:00
										 |  |  | 	float d_sqrt; | 
					
						
							|  |  |  | 	if (d > 1.0e-35) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		d_sqrt = (float)sqrt(d); | 
					
						
							|  |  |  | 		mul_vn_vn_fl(array_tar, array_src, size, 1.0f / d_sqrt); | 
					
						
							| 
									
										
										
										
											2011-11-24 04:12:16 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		fill_vn_fl(array_tar, size, 0.0f); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		d_sqrt = 0.0f; | 
					
						
							| 
									
										
										
										
											2011-11-24 04:12:16 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return d_sqrt; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float normalize_vn(float *array_tar, const int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return normalize_vn_vn(array_tar, array_tar, size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void range_vn_i(int *array_tar, const int size, const int start) | 
					
						
							| 
									
										
										
										
											2010-10-20 09:18:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	int *array_pt = array_tar + (size - 1); | 
					
						
							|  |  |  | 	int j = start + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(array_pt--) = j--; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-10-20 09:18:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-18 07:27:11 +00:00
										 |  |  | void range_vn_fl(float *array_tar, const int size, const float start, const float step) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float *array_pt = array_tar + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	while (i--) { | 
					
						
							| 
									
										
										
										
											2011-12-18 07:27:11 +00:00
										 |  |  | 		*(array_pt--) = start + step * (float)(i); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-05 06:14:50 +00:00
										 |  |  | void negate_vn(float *array_tar, const int size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float *array_pt = array_tar + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(array_pt--) *= -1.0f; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-05 06:14:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void negate_vn_vn(float *array_tar, const float *array_src, const int size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	const float *src = array_src + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							| 
									
										
										
										
											2012-03-25 15:56:17 +00:00
										 |  |  | 		*(tar--) = -*(src--); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-05 06:14:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-20 09:18:55 +00:00
										 |  |  | void mul_vn_fl(float *array_tar, const int size, const float f) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float *array_pt = array_tar + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(array_pt--) *= f; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-10-20 09:18:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void mul_vn_vn_fl(float *array_tar, const float *array_src, const int size, const float f) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	const float *src = array_src + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) = *(src--) * f; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-10-20 09:18:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void add_vn_vn(float *array_tar, const float *array_src, const int size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	const float *src = array_src + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) += *(src--); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-10-20 09:18:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-09 09:16:04 +00:00
										 |  |  | void add_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	const float *src_a = array_src_a + (size - 1); | 
					
						
							|  |  |  | 	const float *src_b = array_src_b + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) = *(src_a--) + *(src_b--); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-01-09 09:16:04 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-31 11:57:09 +00:00
										 |  |  | void madd_vn_vn(float *array_tar, const float *array_src, const float f, const int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	const float *src = array_src + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) += *(src--) * f; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void madd_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const float f, const int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	const float *src_a = array_src_a + (size - 1); | 
					
						
							|  |  |  | 	const float *src_b = array_src_b + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) = *(src_a--) + (*(src_b--) * f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-23 08:37:34 +00:00
										 |  |  | void sub_vn_vn(float *array_tar, const float *array_src, const int size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	const float *src = array_src + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) -= *(src--); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-01-23 08:37:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-09 09:16:04 +00:00
										 |  |  | void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	const float *src_a = array_src_a + (size - 1); | 
					
						
							|  |  |  | 	const float *src_b = array_src_b + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) = *(src_a--) - *(src_b--); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-01-09 09:16:04 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-31 11:57:09 +00:00
										 |  |  | void msub_vn_vn(float *array_tar, const float *array_src, const float f, const int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	const float *src = array_src + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) -= *(src--) * f; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void msub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const float f, const int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	const float *src_a = array_src_a + (size - 1); | 
					
						
							|  |  |  | 	const float *src_b = array_src_b + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) = *(src_a--) - (*(src_b--) * f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-24 04:12:16 +00:00
										 |  |  | void fill_vn_i(int *array_tar, const int size, const int val) | 
					
						
							| 
									
										
										
										
											2010-10-20 09:18:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	int *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) = val; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-10-20 09:18:55 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-12-19 07:05:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-23 23:57:17 +00:00
										 |  |  | void fill_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned short *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) = val; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-24 04:12:16 +00:00
										 |  |  | void fill_vn_fl(float *array_tar, const int size, const float val) | 
					
						
							| 
									
										
										
										
											2010-12-19 07:05:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float *tar = array_tar + (size - 1); | 
					
						
							|  |  |  | 	int i = size; | 
					
						
							|  |  |  | 	while (i--) { | 
					
						
							|  |  |  | 		*(tar--) = val; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-12-19 07:05:29 +00:00
										 |  |  | } |