Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 00021 * The Original Code is: some of this file. 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 * */ 00025 00032 #include "BLI_math.h" 00033 00034 //******************************* Interpolation *******************************/ 00035 00036 void interp_v2_v2v2(float target[2], const float a[2], const float b[2], const float t) 00037 { 00038 float s = 1.0f-t; 00039 00040 target[0]= s*a[0] + t*b[0]; 00041 target[1]= s*a[1] + t*b[1]; 00042 } 00043 00044 /* weight 3 2D vectors, 00045 * 'w' must be unit length but is not a vector, just 3 weights */ 00046 void interp_v2_v2v2v2(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3]) 00047 { 00048 p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2]; 00049 p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2]; 00050 } 00051 00052 void interp_v3_v3v3(float target[3], const float a[3], const float b[3], const float t) 00053 { 00054 float s = 1.0f-t; 00055 00056 target[0]= s*a[0] + t*b[0]; 00057 target[1]= s*a[1] + t*b[1]; 00058 target[2]= s*a[2] + t*b[2]; 00059 } 00060 00061 void interp_v4_v4v4(float target[4], const float a[4], const float b[4], const float t) 00062 { 00063 float s = 1.0f-t; 00064 00065 target[0]= s*a[0] + t*b[0]; 00066 target[1]= s*a[1] + t*b[1]; 00067 target[2]= s*a[2] + t*b[2]; 00068 target[3]= s*a[3] + t*b[3]; 00069 } 00070 00071 /* weight 3 vectors, 00072 * 'w' must be unit length but is not a vector, just 3 weights */ 00073 void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]) 00074 { 00075 p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2]; 00076 p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2]; 00077 p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2]; 00078 } 00079 00080 /* weight 3 vectors, 00081 * 'w' must be unit length but is not a vector, just 4 weights */ 00082 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]) 00083 { 00084 p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2] + v4[0]*w[3]; 00085 p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2] + v4[1]*w[3]; 00086 p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2] + v4[2]*w[3]; 00087 } 00088 00089 void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float w[3]) 00090 { 00091 p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2]; 00092 p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2]; 00093 p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2]; 00094 p[3] = v1[3]*w[0] + v2[3]*w[1] + v3[3]*w[2]; 00095 } 00096 00097 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]) 00098 { 00099 p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2] + v4[0]*w[3]; 00100 p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2] + v4[1]*w[3]; 00101 p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2] + v4[2]*w[3]; 00102 p[3] = v1[3]*w[0] + v2[3]*w[1] + v3[3]*w[2] + v4[3]*w[3]; 00103 } 00104 00105 void mid_v3_v3v3(float v[3], const float v1[3], const float v2[3]) 00106 { 00107 v[0]= 0.5f*(v1[0] + v2[0]); 00108 v[1]= 0.5f*(v1[1] + v2[1]); 00109 v[2]= 0.5f*(v1[2] + v2[2]); 00110 } 00111 00112 /********************************** Angles ***********************************/ 00113 00114 /* Return the angle in radians between vecs 1-2 and 2-3 in radians 00115 If v1 is a shoulder, v2 is the elbow and v3 is the hand, 00116 this would return the angle at the elbow */ 00117 float angle_v3v3v3(const float v1[3], const float v2[3], const float v3[3]) 00118 { 00119 float vec1[3], vec2[3]; 00120 00121 sub_v3_v3v3(vec1, v2, v1); 00122 sub_v3_v3v3(vec2, v2, v3); 00123 normalize_v3(vec1); 00124 normalize_v3(vec2); 00125 00126 return angle_normalized_v3v3(vec1, vec2); 00127 } 00128 00129 /* Return the shortest angle in radians between the 2 vectors */ 00130 float angle_v3v3(const float v1[3], const float v2[3]) 00131 { 00132 float vec1[3], vec2[3]; 00133 00134 normalize_v3_v3(vec1, v1); 00135 normalize_v3_v3(vec2, v2); 00136 00137 return angle_normalized_v3v3(vec1, vec2); 00138 } 00139 00140 float angle_v2v2v2(const float v1[2], const float v2[2], const float v3[2]) 00141 { 00142 float vec1[2], vec2[2]; 00143 00144 vec1[0] = v2[0]-v1[0]; 00145 vec1[1] = v2[1]-v1[1]; 00146 00147 vec2[0] = v2[0]-v3[0]; 00148 vec2[1] = v2[1]-v3[1]; 00149 00150 normalize_v2(vec1); 00151 normalize_v2(vec2); 00152 00153 return angle_normalized_v2v2(vec1, vec2); 00154 } 00155 00156 /* Return the shortest angle in radians between the 2 vectors */ 00157 float angle_v2v2(const float v1[2], const float v2[2]) 00158 { 00159 float vec1[2], vec2[2]; 00160 00161 vec1[0] = v1[0]; 00162 vec1[1] = v1[1]; 00163 00164 vec2[0] = v2[0]; 00165 vec2[1] = v2[1]; 00166 00167 normalize_v2(vec1); 00168 normalize_v2(vec2); 00169 00170 return angle_normalized_v2v2(vec1, vec2); 00171 } 00172 00173 float angle_normalized_v3v3(const float v1[3], const float v2[3]) 00174 { 00175 /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */ 00176 if (dot_v3v3(v1, v2) < 0.0f) { 00177 float vec[3]; 00178 00179 vec[0]= -v2[0]; 00180 vec[1]= -v2[1]; 00181 vec[2]= -v2[2]; 00182 00183 return (float)M_PI - 2.0f*(float)saasin(len_v3v3(vec, v1)/2.0f); 00184 } 00185 else 00186 return 2.0f*(float)saasin(len_v3v3(v2, v1)/2.0f); 00187 } 00188 00189 float angle_normalized_v2v2(const float v1[2], const float v2[2]) 00190 { 00191 /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */ 00192 if (dot_v2v2(v1, v2) < 0.0f) { 00193 float vec[2]; 00194 00195 vec[0]= -v2[0]; 00196 vec[1]= -v2[1]; 00197 00198 return (float)M_PI - 2.0f*saasin(len_v2v2(vec, v1)/2.0f); 00199 } 00200 else 00201 return 2.0f*(float)saasin(len_v2v2(v2, v1)/2.0f); 00202 } 00203 00204 void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3]) 00205 { 00206 float ed1[3], ed2[3], ed3[3]; 00207 00208 sub_v3_v3v3(ed1, v3, v1); 00209 sub_v3_v3v3(ed2, v1, v2); 00210 sub_v3_v3v3(ed3, v2, v3); 00211 00212 normalize_v3(ed1); 00213 normalize_v3(ed2); 00214 normalize_v3(ed3); 00215 00216 angles[0]= (float)M_PI - angle_normalized_v3v3(ed1, ed2); 00217 angles[1]= (float)M_PI - angle_normalized_v3v3(ed2, ed3); 00218 // face_angles[2] = M_PI - angle_normalized_v3v3(ed3, ed1); 00219 angles[2]= (float)M_PI - (angles[0] + angles[1]); 00220 } 00221 00222 void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3]) 00223 { 00224 float ed1[3], ed2[3], ed3[3], ed4[3]; 00225 00226 sub_v3_v3v3(ed1, v4, v1); 00227 sub_v3_v3v3(ed2, v1, v2); 00228 sub_v3_v3v3(ed3, v2, v3); 00229 sub_v3_v3v3(ed4, v3, v4); 00230 00231 normalize_v3(ed1); 00232 normalize_v3(ed2); 00233 normalize_v3(ed3); 00234 normalize_v3(ed4); 00235 00236 angles[0]= (float)M_PI - angle_normalized_v3v3(ed1, ed2); 00237 angles[1]= (float)M_PI - angle_normalized_v3v3(ed2, ed3); 00238 angles[2]= (float)M_PI - angle_normalized_v3v3(ed3, ed4); 00239 angles[3]= (float)M_PI - angle_normalized_v3v3(ed4, ed1); 00240 } 00241 00242 /********************************* Geometry **********************************/ 00243 00244 /* Project v1 on v2 */ 00245 void project_v2_v2v2(float c[2], const float v1[2], const float v2[2]) 00246 { 00247 float mul; 00248 mul = dot_v2v2(v1, v2) / dot_v2v2(v2, v2); 00249 00250 c[0] = mul * v2[0]; 00251 c[1] = mul * v2[1]; 00252 } 00253 00254 /* Project v1 on v2 */ 00255 void project_v3_v3v3(float c[3], const float v1[3], const float v2[3]) 00256 { 00257 float mul; 00258 mul = dot_v3v3(v1, v2) / dot_v3v3(v2, v2); 00259 00260 c[0] = mul * v2[0]; 00261 c[1] = mul * v2[1]; 00262 c[2] = mul * v2[2]; 00263 } 00264 00265 /* Returns a vector bisecting the angle at v2 formed by v1, v2 and v3 */ 00266 void bisect_v3_v3v3v3(float out[3], const float v1[3], const float v2[3], const float v3[3]) 00267 { 00268 float d_12[3], d_23[3]; 00269 sub_v3_v3v3(d_12, v2, v1); 00270 sub_v3_v3v3(d_23, v3, v2); 00271 normalize_v3(d_12); 00272 normalize_v3(d_23); 00273 add_v3_v3v3(out, d_12, d_23); 00274 normalize_v3(out); 00275 } 00276 00277 /* Returns a reflection vector from a vector and a normal vector 00278 reflect = vec - ((2 * DotVecs(vec, mirror)) * mirror) 00279 */ 00280 void reflect_v3_v3v3(float out[3], const float v1[3], const float v2[3]) 00281 { 00282 float vec[3], normal[3]; 00283 float reflect[3] = {0.0f, 0.0f, 0.0f}; 00284 float dot2; 00285 00286 copy_v3_v3(vec, v1); 00287 copy_v3_v3(normal, v2); 00288 00289 dot2 = 2 * dot_v3v3(vec, normal); 00290 00291 reflect[0] = vec[0] - (dot2 * normal[0]); 00292 reflect[1] = vec[1] - (dot2 * normal[1]); 00293 reflect[2] = vec[2] - (dot2 * normal[2]); 00294 00295 copy_v3_v3(out, reflect); 00296 } 00297 00298 void ortho_basis_v3v3_v3(float v1[3], float v2[3], const float v[3]) 00299 { 00300 const float f = (float)sqrt(v[0]*v[0] + v[1]*v[1]); 00301 00302 if (f < 1e-35f) { 00303 // degenerate case 00304 v1[0] = (v[2] < 0.0f) ? -1.0f : 1.0f; 00305 v1[1] = v1[2] = v2[0] = v2[2] = 0.0f; 00306 v2[1] = 1.0f; 00307 } 00308 else { 00309 const float d= 1.0f/f; 00310 00311 v1[0] = v[1]*d; 00312 v1[1] = -v[0]*d; 00313 v1[2] = 0.0f; 00314 v2[0] = -v[2]*v1[1]; 00315 v2[1] = v[2]*v1[0]; 00316 v2[2] = v[0]*v1[1] - v[1]*v1[0]; 00317 } 00318 } 00319 00320 /* Rotate a point p by angle theta around an arbitrary axis r 00321 http://local.wasp.uwa.edu.au/~pbourke/geometry/ 00322 */ 00323 void rotate_normalized_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle) 00324 { 00325 const float costheta= cos(angle); 00326 const float sintheta= sin(angle); 00327 00328 r[0]= ((costheta + (1 - costheta) * axis[0] * axis[0]) * p[0]) + 00329 (((1 - costheta) * axis[0] * axis[1] - axis[2] * sintheta) * p[1]) + 00330 (((1 - costheta) * axis[0] * axis[2] + axis[1] * sintheta) * p[2]); 00331 00332 r[1]= (((1 - costheta) * axis[0] * axis[1] + axis[2] * sintheta) * p[0]) + 00333 ((costheta + (1 - costheta) * axis[1] * axis[1]) * p[1]) + 00334 (((1 - costheta) * axis[1] * axis[2] - axis[0] * sintheta) * p[2]); 00335 00336 r[2]= (((1 - costheta) * axis[0] * axis[2] - axis[1] * sintheta) * p[0]) + 00337 (((1 - costheta) * axis[1] * axis[2] + axis[0] * sintheta) * p[1]) + 00338 ((costheta + (1 - costheta) * axis[2] * axis[2]) * p[2]); 00339 } 00340 00341 void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle) 00342 { 00343 float axis_n[3]; 00344 00345 normalize_v3_v3(axis_n, axis); 00346 00347 rotate_normalized_v3_v3v3fl(r, p, axis_n, angle); 00348 } 00349 00350 /*********************************** Other ***********************************/ 00351 00352 void print_v2(const char *str, const float v[2]) 00353 { 00354 printf("%s: %.3f %.3f\n", str, v[0], v[1]); 00355 } 00356 00357 void print_v3(const char *str, const float v[3]) 00358 { 00359 printf("%s: %.3f %.3f %.3f\n", str, v[0], v[1], v[2]); 00360 } 00361 00362 void print_v4(const char *str, const float v[4]) 00363 { 00364 printf("%s: %.3f %.3f %.3f %.3f\n", str, v[0], v[1], v[2], v[3]); 00365 } 00366 00367 void minmax_v3v3_v3(float min[3], float max[3], const float vec[3]) 00368 { 00369 if(min[0]>vec[0]) min[0]= vec[0]; 00370 if(min[1]>vec[1]) min[1]= vec[1]; 00371 if(min[2]>vec[2]) min[2]= vec[2]; 00372 00373 if(max[0]<vec[0]) max[0]= vec[0]; 00374 if(max[1]<vec[1]) max[1]= vec[1]; 00375 if(max[2]<vec[2]) max[2]= vec[2]; 00376 } 00377 00378 00379 /***************************** Array Functions *******************************/ 00380 00381 double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size) 00382 { 00383 double d= 0.0f; 00384 const float *array_pt_a= array_src_a + (size-1); 00385 const float *array_pt_b= array_src_b + (size-1); 00386 int i= size; 00387 while(i--) { d += *(array_pt_a--) * *(array_pt_b--); } 00388 return d; 00389 } 00390 00391 float normalize_vn_vn(float *array_tar, const float *array_src, const int size) 00392 { 00393 double d= dot_vn_vn(array_tar, array_src, size); 00394 float d_sqrt; 00395 if (d > 1.0e-35) { 00396 d_sqrt= (float)sqrt(d); 00397 mul_vn_vn_fl(array_tar, array_src, size, 1.0f/d_sqrt); 00398 } 00399 else { 00400 fill_vn_fl(array_tar, size, 0.0f); 00401 d_sqrt= 0.0f; 00402 } 00403 return d_sqrt; 00404 } 00405 00406 float normalize_vn(float *array_tar, const int size) 00407 { 00408 return normalize_vn_vn(array_tar, array_tar, size); 00409 } 00410 00411 void range_vn_i(int *array_tar, const int size, const int start) 00412 { 00413 int *array_pt= array_tar + (size-1); 00414 int j= start + (size-1); 00415 int i= size; 00416 while(i--) { *(array_pt--) = j--; } 00417 } 00418 00419 void range_vn_fl(float *array_tar, const int size, const float start, const float step) 00420 { 00421 float *array_pt= array_tar + (size-1); 00422 int i= size; 00423 while(i--) { 00424 *(array_pt--) = start + step * (float)(i); 00425 } 00426 } 00427 00428 void negate_vn(float *array_tar, const int size) 00429 { 00430 float *array_pt= array_tar + (size-1); 00431 int i= size; 00432 while(i--) { *(array_pt--) *= -1.0f; } 00433 } 00434 00435 void negate_vn_vn(float *array_tar, const float *array_src, const int size) 00436 { 00437 float *tar= array_tar + (size-1); 00438 const float *src= array_src + (size-1); 00439 int i= size; 00440 while(i--) { *(tar--) = - *(src--); } 00441 } 00442 00443 void mul_vn_fl(float *array_tar, const int size, const float f) 00444 { 00445 float *array_pt= array_tar + (size-1); 00446 int i= size; 00447 while(i--) { *(array_pt--) *= f; } 00448 } 00449 00450 void mul_vn_vn_fl(float *array_tar, const float *array_src, const int size, const float f) 00451 { 00452 float *tar= array_tar + (size-1); 00453 const float *src= array_src + (size-1); 00454 int i= size; 00455 while(i--) { *(tar--) = *(src--) * f; } 00456 } 00457 00458 void add_vn_vn(float *array_tar, const float *array_src, const int size) 00459 { 00460 float *tar= array_tar + (size-1); 00461 const float *src= array_src + (size-1); 00462 int i= size; 00463 while(i--) { *(tar--) += *(src--); } 00464 } 00465 00466 void add_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size) 00467 { 00468 float *tar= array_tar + (size-1); 00469 const float *src_a= array_src_a + (size-1); 00470 const float *src_b= array_src_b + (size-1); 00471 int i= size; 00472 while(i--) { *(tar--) = *(src_a--) + *(src_b--); } 00473 } 00474 00475 void sub_vn_vn(float *array_tar, const float *array_src, const int size) 00476 { 00477 float *tar= array_tar + (size-1); 00478 const float *src= array_src + (size-1); 00479 int i= size; 00480 while(i--) { *(tar--) -= *(src--); } 00481 } 00482 00483 void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size) 00484 { 00485 float *tar= array_tar + (size-1); 00486 const float *src_a= array_src_a + (size-1); 00487 const float *src_b= array_src_b + (size-1); 00488 int i= size; 00489 while(i--) { *(tar--) = *(src_a--) - *(src_b--); } 00490 } 00491 00492 void fill_vn_i(int *array_tar, const int size, const int val) 00493 { 00494 int *tar= array_tar + (size-1); 00495 int i= size; 00496 while(i--) { *(tar--) = val; } 00497 } 00498 00499 void fill_vn_fl(float *array_tar, const int size, const float val) 00500 { 00501 float *tar= array_tar + (size-1); 00502 int i= size; 00503 while(i--) { *(tar--) = val; } 00504 }