/* This file is part of the OpenLB library * * Copyright (C) 2013, 2014 Lukas Baron, Mathias J. Krause * E-mail contact: info@openlb.net * The most recent release of OpenLB can be downloaded at * * * 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, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef VECTOR_HELPERS_H #define VECTOR_HELPERS_H #include #include #include #include #include #include #include "io/ostreamManager.h" #include "core/vector.h" namespace olb { template class Vector; namespace util { /// return true if a is close to zero template inline bool nearZero(const T& a) { if (a==T()) return true; T EPSILON = std::numeric_limits::epsilon(); if (a > -EPSILON && a < EPSILON) { return true; } else { return false; } } template inline bool nearZero(const T& a, const T& epsilon) { if (a > -epsilon && a < epsilon) { return true; } else { return false; } } template inline bool approxEqual(const T& a, const T& b, const T& epsilon) { if (a==b) return true; return nearZero(a - b, epsilon); } template inline bool approxEqual(const T& a, const T& b) { if (a==b) return true; if (nearZero(a) && nearZero(b)) return true; T EPSILON = std::numeric_limits::epsilon()*4.*fabs(a); return approxEqual(a,b,EPSILON); } template inline void copyN(T c[], const T a[], const unsigned dim) { for (unsigned i=0; i inline void copy3(T c[], const T a[]) { for (unsigned i=0; i<3; i++) { c[i] = a[i]; } } template std::vector fromVector3(const Vector& vec) { std::vector v; v.push_back(vec[0]); v.push_back(vec[1]); v.push_back(vec[2]); return v; } template std::vector fromVector2(const Vector& vec) { std::vector v; v.push_back(vec[0]); v.push_back(vec[1]); return v; } /// l2 norm of a vector of arbitrary length template T norm(const std::vector& a) { T v(0); for (unsigned iD=0; iD T norm2(const std::vector& a) { T v = T(); for (unsigned iD=0; iD T dotProduct3D(const Vector& a, const Vector& b) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; } /// dot product, only valid in 2d template T dotProduct2D(const Vector& a, const Vector& b) { return a[0]*b[0] + a[1]*b[1]; } /// returns a normalized vector, works for arbitrary lengths template std::vector normalize(const std::vector& a) { std::vector out(a); T scale = norm(a); assert(scale>0); for (unsigned int iDim=0; iDim Vector floor(const Vector& a) { Vector out; for (unsigned int iDim=0; iDim < Size; ++iDim) { out[iDim] = std::floor(a[iDim]); } return out; } /// applies ceil to each component of a vector template Vector ceil(const Vector& a) { Vector out; for (unsigned int iDim=0; iDim < Size; ++iDim) { out[iDim] = std::ceil(a[iDim]); } return out; } /* /// algorithm by Möller–Trumbore (TODO add ref), implemented by Lucas Cruz and Mathias J. Krause /// returns true if there is an intersection of a triangle given by (point0, point1, point1) and a ray given by its origin and direction and computes the distance template bool triangleIntersectionWithNormalDirection(const std::vector& point0, const std::vector& point1, const std::vector& point2, const std::vector& origin, const std::vector& normalDirection, T& distance) { T EPSILON = std::numeric_limits::epsilon(); std::vector e1, e2; std::vector P, Q, TT; T det, inv_det; T t, u, v; e1 = point1 - point0; e2 = point2 - point0; P = crossProduct3D(normalDirection, e2); det = dotProduct3D(P, e1); if (det > -EPSILON && det < EPSILON) { return false; } inv_det = T(1) / det; TT = origin - point0; u = dotProduct3D(TT, P)*inv_det; if (u < T() || u > T(1)) { return false; } Q = crossProduct3D(TT, e1); v = dotProduct3D(normalDirection, Q) * inv_det; if (v < T() || u + v > T(1)) { return false; } t = dotProduct3D(e2, Q)*inv_det; if (t > EPSILON) { distance = t; return true; } return false; } template bool triangleIntersection(const std::vector& point0, const std::vector& point1, const std::vector& point2, const std::vector& origin, const std::vector& direction, T& distance) { std::vector normalDirection(normalize(direction) ); return triangleIntersectionWithNormalDirection(point0, point1, point2, origin, normalDirection, distance ); } */ template std::vector assign(T a, T b) { std::vector v1; v1.push_back(a); v1.push_back(b); return v1; } template std::vector assign(T a, T b, T c) { std::vector v1; v1.push_back(a); v1.push_back(b); v1.push_back(c); return v1; } template void print(U data, const std::string& name="", OstreamManager clout = OstreamManager(std::cout,"print"), const char delimiter=',') { static_assert(!std::is_integral::value && !std::is_floating_point::value, "passed integral or floating_point value to function print()"); if (name != "") { clout << name << " = "; } for( auto& element : data ) { clout << std::fixed << element << delimiter << ' '; } clout << std::endl; } } // namespace util } // namespace olb #endif