| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "common/math/vec.h" |
| |
| #include "common/math/macros.h" |
| |
| void findOrthogonalVector(float inX, float inY, float inZ, float *outX, |
| float *outY, float *outZ) { |
| CHRE_ASSERT_NOT_NULL(outX); |
| CHRE_ASSERT_NOT_NULL(outY); |
| CHRE_ASSERT_NOT_NULL(outZ); |
| float x, y, z; |
| |
| // discard the one with the smallest absolute value |
| if (fabsf(inX) <= fabsf(inY) && fabsf(inX) <= fabsf(inZ)) { |
| x = 0.0f; |
| y = inZ; |
| z = -inY; |
| } else if (fabsf(inY) <= fabsf(inZ)) { |
| x = inZ; |
| y = 0.0f; |
| z = -inX; |
| } else { |
| x = inY; |
| y = -inX; |
| z = 0.0f; |
| } |
| |
| float magSquared = x * x + y * y + z * z; |
| CHRE_ASSERT(magSquared > 0); |
| // Only set invMag if magSquared is non-zero. |
| float invMag = 1.0f; |
| if (magSquared > 0) { |
| invMag = 1.0f / sqrtf(magSquared); |
| } |
| *outX = x * invMag; |
| *outY = y * invMag; |
| *outZ = z * invMag; |
| } |
| |
| void vecAdd(float *u, const float *v, const float *w, size_t dim) { |
| CHRE_ASSERT_NOT_NULL(u); |
| CHRE_ASSERT_NOT_NULL(v); |
| CHRE_ASSERT_NOT_NULL(w); |
| size_t i; |
| for (i = 0; i < dim; i++) { |
| u[i] = v[i] + w[i]; |
| } |
| } |
| |
| void vecAddInPlace(float *v, const float *w, size_t dim) { |
| CHRE_ASSERT_NOT_NULL(v); |
| CHRE_ASSERT_NOT_NULL(w); |
| size_t i; |
| for (i = 0; i < dim; i++) { |
| v[i] += w[i]; |
| } |
| } |
| |
| void vecSub(float *u, const float *v, const float *w, size_t dim) { |
| CHRE_ASSERT_NOT_NULL(u); |
| CHRE_ASSERT_NOT_NULL(v); |
| CHRE_ASSERT_NOT_NULL(w); |
| size_t i; |
| for (i = 0; i < dim; i++) { |
| u[i] = v[i] - w[i]; |
| } |
| } |
| |
| void vecScalarMul(float *u, const float *v, float c, size_t dim) { |
| CHRE_ASSERT_NOT_NULL(u); |
| CHRE_ASSERT_NOT_NULL(v); |
| size_t i; |
| for (i = 0; i < dim; i++) { |
| u[i] = c * v[i]; |
| } |
| } |
| |
| void vecScalarMulInPlace(float *v, float c, size_t dim) { |
| CHRE_ASSERT_NOT_NULL(v); |
| size_t i; |
| for (i = 0; i < dim; i++) { |
| v[i] *= c; |
| } |
| } |
| |
| float vecNorm(const float *v, size_t dim) { |
| CHRE_ASSERT_NOT_NULL(v); |
| float norm_sq = vecNormSquared(v, dim); |
| return sqrtf(norm_sq); |
| } |
| |
| float vecNormSquared(const float *v, size_t dim) { |
| CHRE_ASSERT_NOT_NULL(v); |
| return vecDot(v, v, dim); |
| } |
| |
| float vecDot(const float *v, const float *w, size_t dim) { |
| CHRE_ASSERT_NOT_NULL(v); |
| CHRE_ASSERT_NOT_NULL(w); |
| size_t i; |
| float result = 0; |
| for (i = 0; i < dim; ++i) { |
| result += v[i] * w[i]; |
| } |
| return result; |
| } |
| |
| float vecMaxAbsoluteValue(const float *v, size_t dim) { |
| CHRE_ASSERT_NOT_NULL(v); |
| float max = NANO_ABS(v[0]); |
| float tmp; |
| size_t i; |
| for (i = 1; i < dim; ++i) { |
| tmp = NANO_ABS(v[i]); |
| if(tmp > max) { |
| max = tmp; |
| } |
| } |
| return max; |
| } |