211 lines
6.1 KiB
C
211 lines
6.1 KiB
C
|
//=============================================================================
|
||
|
//
|
||
|
// Copyright (c) Kitware, Inc.
|
||
|
// All rights reserved.
|
||
|
// See LICENSE.txt for details.
|
||
|
//
|
||
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
// PURPOSE. See the above copyright notice for more information.
|
||
|
//
|
||
|
// Copyright 2015 Sandia Corporation.
|
||
|
// Copyright 2015 UT-Battelle, LLC.
|
||
|
// Copyright 2015 Los Alamos National Security.
|
||
|
//
|
||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||
|
// the U.S. Government retains certain rights in this software.
|
||
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||
|
// this software.
|
||
|
//
|
||
|
//=============================================================================
|
||
|
#ifndef vtk_m_VectorAnalysis_h
|
||
|
#define vtk_m_VectorAnalysis_h
|
||
|
|
||
|
// This header file defines math functions that deal with linear albegra funcitons
|
||
|
|
||
|
#include <vtkm/Math.h>
|
||
|
#include <vtkm/Types.h>
|
||
|
#include <vtkm/TypeTraits.h>
|
||
|
#include <vtkm/VecTraits.h>
|
||
|
|
||
|
namespace vtkm {
|
||
|
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
/// \brief Returns the linear interpolation of two values based on weight
|
||
|
///
|
||
|
/// \c Lerp interpolates return the linerar interpolation of v0 and v1 based on w. v0
|
||
|
/// and v1 are scalars or vectors of same length. w can either be a scalar or a
|
||
|
/// vector of the same length as x and y. If w is outside [0,1] then lerp
|
||
|
/// extrapolates. If w=0 => v0 is returned if w=1 => v1 is returned.
|
||
|
///
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
T Lerp(const T &v0, const T & v1, const T &w)
|
||
|
{
|
||
|
return v0 + w * (v1-v0);
|
||
|
}
|
||
|
template<typename T, vtkm::IdComponent N>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
vtkm::Vec<T,N> Lerp(const vtkm::Vec<T,N> &v0,
|
||
|
const vtkm::Vec<T,N> &v1,
|
||
|
const T &w)
|
||
|
{
|
||
|
return v0 + w * (v1-v0);
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
/// \brief Returns the square of the magnitude of a vector.
|
||
|
///
|
||
|
/// It is usually much faster to compute the square of the magnitude than the
|
||
|
/// square, so you should use this function in place of Magnitude or RMagnitude
|
||
|
/// when possible.
|
||
|
///
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
typename vtkm::VecTraits<T>::ComponentType
|
||
|
MagnitudeSquared(const T &x)
|
||
|
{
|
||
|
return vtkm::dot(x,x);
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
namespace detail {
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
T MagnitudeTemplate(T x, vtkm::TypeTraitsScalarTag)
|
||
|
{
|
||
|
return vtkm::Abs(x);
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
typename vtkm::VecTraits<T>::ComponentType
|
||
|
MagnitudeTemplate(const T &x, vtkm::TypeTraitsVectorTag)
|
||
|
{
|
||
|
return vtkm::Sqrt(vtkm::MagnitudeSquared(x));
|
||
|
}
|
||
|
} // namespace detail
|
||
|
|
||
|
/// \brief Returns the magnitude of a vector.
|
||
|
///
|
||
|
/// It is usually much faster to compute MagnitudeSquared, so that should be
|
||
|
/// substituted when possible (unless you are just going to take the square
|
||
|
/// root, which would be besides the point). On some hardware it is also faster
|
||
|
/// to find the reciprocal magnitude, so RMagnitude should be used if you
|
||
|
/// actually plan to divide by the magnitude.
|
||
|
///
|
||
|
template<typename T>
|
||
|
typename vtkm::VecTraits<T>::ComponentType
|
||
|
Magnitude(const T &x)
|
||
|
{
|
||
|
return detail::MagnitudeTemplate(
|
||
|
x, typename vtkm::TypeTraits<T>::DimensionalityTag());
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
namespace detail {
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
T RMagnitudeTemplate(T x, vtkm::TypeTraitsScalarTag)
|
||
|
{
|
||
|
return T(1)/vtkm::Abs(x);
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
typename vtkm::VecTraits<T>::ComponentType
|
||
|
RMagnitudeTemplate(const T &x, vtkm::TypeTraitsVectorTag)
|
||
|
{
|
||
|
return vtkm::RSqrt(vtkm::MagnitudeSquared(x));
|
||
|
}
|
||
|
} // namespace detail
|
||
|
|
||
|
/// \brief Returns the reciprocal magnitude of a vector.
|
||
|
///
|
||
|
/// On some hardware RMagnitude is faster than Magnitude, but neither is
|
||
|
/// as fast as MagnitudeSquared.
|
||
|
///
|
||
|
template<typename T>
|
||
|
typename vtkm::VecTraits<T>::ComponentType
|
||
|
RMagnitude(const T &x)
|
||
|
{
|
||
|
return detail::RMagnitudeTemplate(
|
||
|
x, typename vtkm::TypeTraits<T>::DimensionalityTag());
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
namespace detail {
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
T NormalTemplate(T x, vtkm::TypeTraitsScalarTag)
|
||
|
{
|
||
|
return vtkm::CopySign(T(1), x);
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
T NormalTemplate(const T &x, vtkm::TypeTraitsVectorTag)
|
||
|
{
|
||
|
return vtkm::RMagnitude(x)*x;
|
||
|
}
|
||
|
} // namespace detail
|
||
|
|
||
|
/// \brief Returns a normalized version of the given vector.
|
||
|
///
|
||
|
/// The resulting vector points in the same direction but has unit length.
|
||
|
///
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
T Normal(const T &x)
|
||
|
{
|
||
|
return detail::NormalTemplate(
|
||
|
x, typename vtkm::TypeTraits<T>::DimensionalityTag());
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
/// \brief Changes a vector to be normal.
|
||
|
///
|
||
|
/// The given vector is scaled to be unit length.
|
||
|
///
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
void Normalize(T &x)
|
||
|
{
|
||
|
x = vtkm::Normal(x);
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
/// \brief Find the cross product of two vectors.
|
||
|
///
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
vtkm::Vec<T,3> Cross(const vtkm::Vec<T,3> &x, const vtkm::Vec<T,3> &y)
|
||
|
{
|
||
|
return vtkm::Vec<T,3>(x[1]*y[2] - x[2]*y[1],
|
||
|
x[2]*y[0] - x[0]*y[2],
|
||
|
x[0]*y[1] - x[1]*y[0]);
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
/// \brief Find the normal of a triangle.
|
||
|
///
|
||
|
/// Given three coordinates in space, which, unless degenerate, uniquely define
|
||
|
/// a triangle and the plane the triangle is on, returns a vector perpendicular
|
||
|
/// to that triangle/plane.
|
||
|
///
|
||
|
template<typename T>
|
||
|
VTKM_EXEC_CONT_EXPORT
|
||
|
vtkm::Vec<T,3> TriangleNormal(const vtkm::Vec<T,3> &a,
|
||
|
const vtkm::Vec<T,3> &b,
|
||
|
const vtkm::Vec<T,3> &c)
|
||
|
{
|
||
|
return vtkm::Cross(b-a, c-a);
|
||
|
}
|
||
|
|
||
|
|
||
|
} // namespace vtkm
|
||
|
|
||
|
#endif //vtk_m_VectorAnalysis_h
|