VTK笔记-VTK的数学工具vtkMath类(未完)

vtkMath

  vtkMath提供了执行常见数学运算的方法。这些包括提供常数,如Pi;从度到弧度的转换;向量运算,如点积、叉积和向量范数;2x2和3x3矩阵的矩阵行列式;一元多项式求解器;用于随机数生成(仅用于向后兼容)。
在这里插入图片描述

常量定义

  定义常使用的PI:

static constexpr double Pi() { return 3.141592653589793; }

  使用cos(-1)计算出的PI值为3.1415926535897931;

基础数据操作

四舍五入

static int Round(float f) { return static_cast<int>(f + (f >= 0.0 ? 0.5 : -0.5)); }
static int Round(double f) { return static_cast<int>(f + (f >= 0.0 ? 0.5 : -0.5)); }

double类型到其他类型转换

  在计算中,常会遇到将double类型的值赋值给其他类型,如果直接强制类型转换,会出现精度的下降或数值的溢出;
  RoundDoubleToIntegralIfNecessaryval值转换到OutT类型值,可以保证ret值在OutT类型的合理范围内,不会溢出;

template <typename OutT>
static void RoundDoubleToIntegralIfNecessary(double val, OutT* ret) {
	vtk_detail::RoundDoubleToIntegralIfNecessary(val, ret);
}

整型数的截取

Floor向下取整,Ceil向上取整;

inline int vtkMath::Floor(double x)
{
   int i = static_cast<int>(x);
   return i - (i > x);
}
inline int vtkMath::Ceil(double x)
{
   int i = static_cast<int>(x);
   return i + (i < x);
}

幂函数

CeilLog2给出两个不小于x的最小幂的指数。

static int CeilLog2(vtkTypeUInt64 x);

IsPowerOfTwo函数的功能为:如果整数是2的幂,则返回true。

inline bool vtkMath::IsPowerOfTwo(vtkTypeUInt64 x){
   return ((x != 0) & ((x & (x - 1)) == 0));
}

NearestPowerOfTwo函数的功能为:计算两个不小于x的最近幂。
如果x小于或等于零,则返回值为1;如果结果太大而无法放入整数,则返回值为VTK_INT_MIN。

inline int vtkMath::NearestPowerOfTwo(int x){
   unsigned int z = static_cast<unsigned int>(((x > 0) ? x - 1 : 0));
   z |= z >> 1;
   z |= z >> 2;
   z |= z >> 4;
   z |= z >> 8;
   z |= z >> 16;
   return static_cast<int>(z + 1);
}

Factorial用于计算N阶乘;

static vtkTypeInt64 Factorial(int N);

随机数

VTK中有注释:不要使用Random()RandomSeed()GetSeed()Gaussian()这是静态的,因此容易出错(特别是对于回归测试),这只是为了向后兼容。

static void RandomSeed(int s);  
static int GetSeed();  
static double Random();  
static double Random(double min, double max);
// 生成按标准正态分布分布的伪随机数。
static double Gaussian();  
static double Gaussian(double mean, double std);

抽样和随机数组

Binomial来自m个对象(m>n)池的n个对象的组合数。

static vtkTypeInt64 Binomial(int m, int n);

BeginCombination函数功能:开始迭代“m选择n”对象,返回一个由n个整数组成的数组,每个整数从0到m-1。这些整数表示从集合[0,m]中选择的n项。一旦不再需要迭代器,需要调用vtkMath::FreeCombination()
NextCombination给定m,n和[0,m]范围内n个整数的有效组合,此函数将整数更改为m个池中n个项的所有组合序列中的下一个组合。如果该组合是输入时序列中的最后一项,则该组合将保持不变并返回0。否则,将返回1并更新该组合。
FreeCombination函数功能:释放由BeginCombination生成的combination指针;

static int* BeginCombination(int m, int n);  
static int NextCombination(int m, int n, int* combination);  
static void FreeCombination(int* combination);

最大最小值

template <class T> static T Min(const T& a, const T& b);  
template <class T> static T Max(const T& a, const T& b);

赋值

template <class VectorT1, class VectorT2>
static void Assign(const VectorT1& a, VectorT2&& b){
     b[0] = a[0];
     b[1] = a[1];
     b[2] = a[2];
}  
static void Assign(const double a[3], double b[3]) { vtkMath::Assign<>(a, b); }

加法

float数组和double数组的加法计算;

static void Add(const float a[3], const float b[3], float c[3]){
     for (int i = 0; i < 3; ++i)
     {
       c[i] = a[i] + b[i];
     }
}
  
static void Add(const double a[3], const double b[3], double c[3]){
     for (int i = 0; i < 3; ++i)
     {
       c[i] = a[i] + b[i];
     }
}

减法

数组之间和Vector之间的减法;

static void Subtract(const float a[3], const float b[3], float c[3]) {
     for (int i = 0; i < 3; ++i) {
       c[i] = a[i] - b[i];
     }
}  
static void Subtract(const double a[3], const double b[3], double c[3]) {
     for (int i = 0; i < 3; ++i) {
       c[i] = a[i] - b[i];
     }
}  
template <class VectorT1, class VectorT2, class VectorT3>
static void Subtract(const VectorT1& a, const VectorT2& b, VectorT3&& c) {
     c[0] = a[0] - b[0];
     c[1] = a[1] - b[1];
     c[2] = a[2] - b[2];
}

乘法

MultiplyScalar*用于计算数组与因子s的乘法;

static void MultiplyScalar(float a[3], float s) {
     for (int i = 0; i < 3; ++i) {
       a[i] *= s;
     }
}  
static void MultiplyScalar2D(float a[2], float s) {
     for (int i = 0; i < 2; ++i) {
       a[i] *= s;
     }
}  
static void MultiplyScalar(double a[3], double s) {
     for (int i = 0; i < 3; ++i) {
       a[i] *= s;
     }
}  
static void MultiplyScalar2D(double a[2], double s) {
     for (int i = 0; i < 2; ++i) {
       a[i] *= s;
     }
}

角度与弧度

  常用的角度Radian与弧度Degree的计算就是角度到弧度的转换,使用Pi值;

double ratio = 3.1415926 / 180;
double aratio = 180 / 3.1415926;

  在VTK中,将PI/180定义为常量0.017453292519943295,将180.0/PI定义为常量57.29577951308232;

inline float vtkMath::RadiansFromDegrees(float x){
   return x * 0.017453292f;
}  
inline double vtkMath::RadiansFromDegrees(double x){
   return x * 0.017453292519943295;
}
inline float vtkMath::DegreesFromRadians(float x){
   return x * 57.2957795131f;
}  
inline double vtkMath::DegreesFromRadians(double x){
   return x * 57.29577951308232;
}

向量运算

点积

两个向量的点积运算,支持float类型和double类型;

static float Dot(const float a[3], const float b[3]) {
     return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}  
static double Dot(const double a[3], const double b[3]) {
     return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
template <typename ReturnTypeT = double, typename TupleRangeT1, typename TupleRangeT2,
	typename EnableT = typename std::conditional<!std::is_pointer<TupleRangeT1>::value &&
         !std::is_array<TupleRangeT1>::value, TupleRangeT1, TupleRangeT2>::type::value_type>
static ReturnTypeT Dot(const TupleRangeT1& a, const TupleRangeT2& b) {
     return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}

叉积

// Cross product of two 3-vectors. Result (a x b) is stored in c[3].
inline void vtkMath::Cross(const float a[3], const float b[3], float c[3]) {
   float Cx = a[1] * b[2] - a[2] * b[1];
   float Cy = a[2] * b[0] - a[0] * b[2];
   float Cz = a[0] * b[1] - a[1] * b[0];
   c[0] = Cx;
   c[1] = Cy;
   c[2] = Cz;
}  
// Cross product of two 3-vectors. Result (a x b) is stored in c[3].
inline void vtkMath::Cross(const double a[3], const double b[3], double c[3]) {
   double Cx = a[1] * b[2] - a[2] * b[1];
   double Cy = a[2] * b[0] - a[0] * b[2];
   double Cz = a[0] * b[1] - a[1] * b[0];
   c[0] = Cx;
   c[1] = Cy;
   c[2] = Cz;
}

外积

计算两个3矢量的外积(浮点型)。

static void Outer(const float a[3], const float b[3], float c[3][3]){
     for (int i = 0; i < 3; ++i){
       for (int j = 0; j < 3; ++j){
         c[i][j] = a[i] * b[j];
       }
     }
}  
static void Outer(const double a[3], const double b[3], double c[3][3]){
     for (int i = 0; i < 3; ++i) {
       for (int j = 0; j < 3; ++j) {
         c[i][j] = a[i] * b[j];
       }
     }
}

矩阵运算

参考资料

1.https://vtk.org/doc/nightly/html/classvtkMath.html

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑山老妖的笔记本

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值