vtk-m/vtkm/Transform3D.h

217 lines
6.7 KiB
C
Raw Normal View History

//=============================================================================
//
// 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 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 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_Transform3D_h
#define vtk_m_Transform3D_h
// This header file contains a collection of math functions useful in the
// linear transformation of homogeneous points for rendering in 3D.
#include <vtkm/Matrix.h>
#include <vtkm/VectorAnalysis.h>
namespace vtkm {
/// \brief Transform a 3D point by a transformation matrix.
///
/// Given a 4x4 transformation matrix and a 3D point, returns the point
/// transformed by the given matrix in homogeneous coordinates.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<T,3> Transform3DPoint(const vtkm::Matrix<T,4,4> &matrix,
const vtkm::Vec<T,3> &point)
{
vtkm::Vec<T,4> homogeneousPoint(point[0], point[1], point[2], T(1));
homogeneousPoint = vtkm::MatrixMultiply(matrix, homogeneousPoint);
T invW = T(1)/homogeneousPoint[3];
return vtkm::Vec<T,3>(
homogeneousPoint[0]*invW,
homogeneousPoint[1]*invW,
homogeneousPoint[2]*invW);
}
/// \brief Transform a 3D point by a transformation matrix.
///
/// Given a 4x4 transformation matrix and a 3D point, returns the point
/// transformed by the given matrix in homogeneous coordinates.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<T,3> Transform3DVector(const vtkm::Matrix<T,4,4> &matrix,
const vtkm::Vec<T,3> &vector)
{
vtkm::Vec<T,4> homogeneousVector(vector[0], vector[1], vector[2], T(0));
homogeneousVector = vtkm::MatrixMultiply(matrix, homogeneousVector);
return vtkm::Vec<T,3>(
homogeneousVector[0],
homogeneousVector[1],
homogeneousVector[2]);
}
/// \brief Returns a scale matrix.
///
/// Given a scale factor for the x, y, and z directions, returns a
/// transformation matrix for those scales.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Matrix<T,4,4>
Transform3DScale(const T &scaleX, const T &scaleY, const T &scaleZ)
{
vtkm::Matrix<T,4,4> scaleMatrix(T(0));
scaleMatrix(0,0) = scaleX;
scaleMatrix(1,1) = scaleY;
scaleMatrix(2,2) = scaleZ;
scaleMatrix(3,3) = T(1);
return scaleMatrix;
}
/// \brief Returns a scale matrix.
///
/// Given a scale factor for the x, y, and z directions (defined in a Vec),
/// returns a transformation matrix for those scales.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Matrix<T,4,4> Transform3DScale(const vtkm::Vec<T,3> &scaleVec)
{
return vtkm::Transform3DScale(scaleVec[0], scaleVec[1], scaleVec[2]);
}
/// \brief Returns a scale matrix.
///
/// Given a uniform scale factor, returns a transformation matrix for those
/// scales.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Matrix<T,4,4> Transform3DScale(const T &scale)
{
return vtkm::Transform3DScale(scale, scale, scale);
}
/// \brief Returns a translation matrix.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Matrix<T,4,4> Transform3DTranslate(const T &x, const T &y, const T &z)
{
vtkm::Matrix<T,4,4> translateMatrix;
vtkm::MatrixIdentity(translateMatrix);
translateMatrix(0,3) = x;
translateMatrix(1,3) = y;
translateMatrix(2,3) = z;
return translateMatrix;
}
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Matrix<T,4,4> Transform3DTranslate(const vtkm::Vec<T,3> &v)
{
return vtkm::Transform3DTranslate(v[0], v[1], v[2]);
}
/// \brief Returns a rotation matrix.
///
/// Given an angle (in radians) and an axis of rotation, returns a
/// transformation matrix that rotates around the given axis. The rotation
/// follows the right-hand rule, so if the vector points toward the user, the
/// rotation will be counterclockwise.
///
/// Note that, unlike with OpenGL, the angle is given in radians, not degrees.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Matrix<T,4,4> Transform3DRotate(T angleRadians,
const vtkm::Vec<T,3> &axisOfRotation)
{
const vtkm::Vec<T,3> normAxis = vtkm::Normal(axisOfRotation);
T sinAngle = vtkm::Sin(angleRadians);
T cosAngle = vtkm::Cos(angleRadians);
vtkm::Matrix<T,4,4> matrix;
matrix(0,0) = normAxis[0]*normAxis[0]*(1-cosAngle) + cosAngle;
matrix(0,1) = normAxis[0]*normAxis[1]*(1-cosAngle) - normAxis[2]*sinAngle;
matrix(0,2) = normAxis[0]*normAxis[2]*(1-cosAngle) + normAxis[1]*sinAngle;
matrix(0,3) = T(0);
matrix(1,0) = normAxis[1]*normAxis[0]*(1-cosAngle) + normAxis[2]*sinAngle;
matrix(1,1) = normAxis[1]*normAxis[1]*(1-cosAngle) + cosAngle;
matrix(1,2) = normAxis[1]*normAxis[2]*(1-cosAngle) - normAxis[0]*sinAngle;
matrix(1,3) = T(0);
matrix(2,0) = normAxis[2]*normAxis[0]*(1-cosAngle) - normAxis[1]*sinAngle;
matrix(2,1) = normAxis[2]*normAxis[1]*(1-cosAngle) + normAxis[0]*sinAngle;
matrix(2,2) = normAxis[2]*normAxis[2]*(1-cosAngle) + cosAngle;
matrix(2,3) = T(0);
matrix(3,0) = T(0);
matrix(3,1) = T(0);
matrix(3,2) = T(0);
matrix(3,3) = T(1);
return matrix;
}
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Matrix<T,4,4> Transform3DRotate(T angleRadians, T x, T y, T z)
{
return vtkm::Transform3DRotate(angleRadians, vtkm::Vec<T,3>(x,y,z));
}
/// \brief Returns a rotation matrix.
///
/// Returns a transformation matrix that rotates around the x axis.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Matrix<T,4,4> Transform3DRotateX(T angleRadians)
{
return vtkm::Transform3DRotate(angleRadians, T(1), T(0), T(0));
}
/// \brief Returns a rotation matrix.
///
/// Returns a transformation matrix that rotates around the y axis.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Matrix<T,4,4> Transform3DRotateY(T angleRadians)
{
return vtkm::Transform3DRotate(angleRadians, T(0), T(1), T(0));
}
/// \brief Returns a rotation matrix.
///
/// Returns a transformation matrix that rotates around the z axis.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
vtkm::Matrix<T,4,4> Transform3DRotateZ(T angleRadians)
{
return vtkm::Transform3DRotate(angleRadians, T(0), T(0), T(1));
}
} // namespace vtkm
#endif //vtk_m_Transform3D_h