Home | History | Annotate | Download | only in math
      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