1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "common/math/vec.h" 18 19 void findOrthogonalVector(float inX, float inY, float inZ, float *outX, 20 float *outY, float *outZ) { 21 ASSERT_NOT_NULL(outX); 22 ASSERT_NOT_NULL(outY); 23 ASSERT_NOT_NULL(outZ); 24 float x, y, z; 25 26 // discard the one with the smallest absolute value 27 if (fabsf(inX) <= fabsf(inY) && fabsf(inX) <= fabsf(inZ)) { 28 x = 0.0f; 29 y = inZ; 30 z = -inY; 31 } else if (fabsf(inY) <= fabsf(inZ)) { 32 x = inZ; 33 y = 0.0f; 34 z = -inX; 35 } else { 36 x = inY; 37 y = -inX; 38 z = 0.0f; 39 } 40 41 float magSquared = x * x + y * y + z * z; 42 ASSERT(magSquared > 0); 43 // Only set invMag if magSquared is non-zero. 44 float invMag = 1.0f; 45 if (magSquared > 0) { 46 invMag = 1.0f / sqrtf(magSquared); 47 } 48 *outX = x * invMag; 49 *outY = y * invMag; 50 *outZ = z * invMag; 51 } 52 53 void vecAdd(float *u, const float *v, const float *w, int dim) { 54 ASSERT_NOT_NULL(u); 55 ASSERT_NOT_NULL(v); 56 ASSERT_NOT_NULL(w); 57 int i; 58 for (i = 0; i < dim; i++) { 59 u[i] = v[i] + w[i]; 60 } 61 } 62 63 void vecAddInPlace(float *v, const float *w, int dim) { 64 ASSERT_NOT_NULL(v); 65 ASSERT_NOT_NULL(w); 66 int i; 67 for (i = 0; i < dim; i++) { 68 v[i] += w[i]; 69 } 70 } 71 72 void vecSub(float *u, const float *v, const float *w, int dim) { 73 ASSERT_NOT_NULL(u); 74 ASSERT_NOT_NULL(v); 75 ASSERT_NOT_NULL(w); 76 int i; 77 for (i = 0; i < dim; i++) { 78 u[i] = v[i] - w[i]; 79 } 80 } 81 82 void vecScalarMul(float *u, const float *v, float c, int dim) { 83 ASSERT_NOT_NULL(u); 84 ASSERT_NOT_NULL(v); 85 int i; 86 for (i = 0; i < dim; i++) { 87 u[i] = c * v[i]; 88 } 89 } 90 91 void vecScalarMulInPlace(float *u, float c, int dim) { 92 ASSERT_NOT_NULL(u); 93 int i; 94 for (i = 0; i < dim; i++) { 95 u[i] *= c; 96 } 97 } 98 99 float vecNorm(const float *v, int dim) { 100 ASSERT_NOT_NULL(v); 101 float norm_sq = vecNormSquared(v, dim); 102 return sqrtf(norm_sq); 103 } 104 105 float vecNormSquared(const float *v, int dim) { 106 ASSERT_NOT_NULL(v); 107 return vecDot(v, v, dim); 108 } 109 110 float vecDot(const float *v, const float *w, int dim) { 111 ASSERT_NOT_NULL(v); 112 ASSERT_NOT_NULL(w); 113 int i; 114 float result = 0; 115 for (i = 0; i < dim; ++i) { 116 result += v[i] * w[i]; 117 } 118 return result; 119 } 120 121 float vecMaxAbsoluteValue(const float *v, int dim) { 122 ASSERT_NOT_NULL(v); 123 float max = NANO_ABS(v[0]); 124 float tmp; 125 int i; 126 for (i = 1; i < dim; ++i) { 127 tmp = NANO_ABS(v[i]); 128 if(tmp > max) { 129 max = tmp; 130 } 131 } 132 return max; 133 } 134