如图中的问题,已知空间向量v1, v2, 求解v1关于v2的对称向量v3。
关键API:

  /**
   * Compute angle in radians between two vectors.
   */
  static double AngleBetweenVectors(const double v1[3], const double v2[3]);


  /**
   * rotate a vector by WXYZ
   * using // https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
   */
  static void RotateVectorByWXYZ(const float v[3], const float q[4], float r[3]);
  static void RotateVectorByWXYZ(const double v[3], const double q[4], double r[3]);

相关的维基百科:https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
我们需要计算出旋转轴向量和旋转角度。旋转轴可以使用两个向量的叉积求解,旋转角度即是原向量的夹角的两倍(镜像对称)。

实验代码:

#include <iostream>
#include <vtkMath.h>
#include "tool.h"

using namespace std;

int main()
{
    PointStruct v1( 2, 0, 0 );
    PointStruct v2( 1, 1, 0 );
    PointStruct v3;
    v1.Unit();
    v2.Unit();
    cout << "v1: " << v1;
    cout << "v2: " << v2;

    double radians = vtkMath::AngleBetweenVectors( v1.point, v2.point );
    PointStruct normal = v1^v2;
    normal.Unit();

    cout << "normal: " << normal;
    cout << "degree: " << vtkMath::DegreesFromRadians( radians ) << endl;
    double q[4] = { 2*radians, normal[0], normal[1], normal[2] };
    vtkMath::RotateVectorByWXYZ( v1.point, q, v3.point );
    cout << "v3: " << v3 << endl;
    return 0;
}
/*
v1: PointStruct [1, 0, 0]
v2: PointStruct [0.707107, 0.707107, 0]
normal: PointStruct [0, 0, 1]
degree: 45
v3: PointStruct [6.12323e-17, 1, 0]
*/

或者测试数据:

PointStruct v1( 0, 0, -3 );
PointStruct v2( 1, 1, 0 );

=>
v1: PointStruct [0, 0, -1]
v2: PointStruct [0.707107, 0.707107, 0]
normal: PointStruct [0.707107, -0.707107, 0]
degree: 90
v3: PointStruct [8.65956e-17, 8.65956e-17, 1]

实验中所需要的结构体,tool.h:

#ifndef TOOL_H
#define TOOL_H

#include <iostream>
#include <math.h>
using namespace std;

class PointStruct
{
public:
    double point[3];
    PointStruct(double x, double y, double z) { point[0]=x; point[1]=y; point[2]=z;}
    PointStruct operator^=( PointStruct &p) { SetPoint(point[1]*p.point[2]-point[2]*p.point[1], point[2]*p.point[0]-point[0]*p.point[2], point[0]*p.point[1]-point[1]*p.point[0]); return *this; }

    double Length() { return sqrt(point[0]*point[0]+point[1]*point[1]+point[2]*point[2]); }
    PointStruct Unit() { return (operator/=(Length())); }
    friend ostream& operator<<(ostream & os, PointStruct & p) { os << "PointStruct [" << p[0] <<", " << p[1] <<", " << p[2] << "]\n"; return os; }
};

#endif // TOOL_H

分类: C plus plus

发表评论

电子邮件地址不会被公开。 必填项已用*标注