我有两个类,一个3D矢量类(Vector3),其数组为3个浮点数作为其成员(float [3]),以及一个3×3矩阵类,它将这些矢量中的3个存储在另一个数组中(Vector3 [3] ])。我的vector类要求矩阵类绕轴旋转,而我的矩阵类需要所有东西的向量。我正在使用前向声明和指针来处理它,就像这个问题:What is the best way to deal with co-dependent classes in C++?,但必须有一个更好的方法来设计它以完全避免这种情况。目前我在我的矩阵头文件中声明了一个指向Vector3的指针,然后在我的实现文件中用new初始化它,但这感觉很笨拙。关于如何解决这个问题的任何指针(没有双关语)? 编辑:我使用矢量类来表示我想围绕任意轴旋转的3D点。
我希望它可以使用的代码:
//Vector3.h
#include "Matrix3.h"
class Matrix3;
class Vector3 {
float xyz[3];
};
//Vector3.cpp
Vector3 Vector3::rotatePoint(Vector3 o, Vector3 a, float theta) {
Vector3 point = (*this);
Vector3 x = Vector3(1,0,0);
Vector3 y = Vector3(0,1,0);
Vector3 z = Vector3(0,0,1);
// Create new coordinate system
Vector3 new_coord[4];
new_coord[0] = o;
new_coord[1] = a.normalize();
unsigned closer_to;
if (a*x < a*y) {
new_coord[2] = (a % x).normalize();
closer_to = 0; // x
}
else {
new_coord[2] = (a % y).normalize();
closer_to = 1; // y
}
new_coord[3] = (a % new_coord[2]).normalize();
// Transform point to new coord system
Matrix3 trans_matrix = Matrix3(new_coord[0], new_coord[1], new_coord[2]);
point = trans_matrix*(point - o);
// Rotate about a by theta degrees
Matrix3 r_m(closer_to, theta);
point = r_m*point;
//Transform back to original coord system
point = (trans_matrix.inverse()*point) + o;
return point;
}
//Matrix3.h
#include "Vector3.h"
class Vector3;
class Matrix3 {
Vector3 rows[3];
}
我用来使其工作的代码:
//Vector3.h
class Matrix3;
class Vector3 {
float xyz[3];
};
//Matrix3.h
#include "Vector3.h"
class Vector3;
class Matrix3 {
Vector3 *rows;
}
//Matrix3.cpp
Matrix3::Matrix3() {
rows = new V3[3];
}
答案 0 :(得分:0)
我接受了@n.m给出的建议。和@Chris Dodd&只是从我的Vector标题中删除了Matrix3 include,并进入了我的Vector实现文件,如下所示:
//Vector3.h
class Vector3 {
float xyz[3];
}
//Vector.cpp
#include "Vector3.h"
#include "Matrix3.h"
//Matrix3.h
#include "Vector3.h"
class Vector3;
class Matrix3 {
Vector3 rows[3];
}
//Matrix3.cpp
#include "Matrix3.h"
答案 1 :(得分:0)
由于你正在处理向量和矩阵,你可以定义一个矩阵类,其中包含维度的模板(也许是元素类型) - 然后,向量类(取决于向量的类型)是一个矩阵其中一个维度= 1.如果这样做,您最终只会得到一个类,一组代码以及执行所需操作所需的所有功能。您可以避免任何类间依赖关系,因为您只有一个类!
该类本身看起来像这样:
template<unsigned m, unsigned n, typename T = float>
class matrix {
T e[m * n];
public:
T* operator [](unsigned i) { return e + i; }
T * const operator [](unsigned i) const { return e + i; }
/* repeat for -, *, / -- same pattern */
matrix<m,n>& operator += (matrix<m,n> const& a) {
for (unsigned i = 0; i < m * n; ++i) e[i] += a.e[i];
return *this;
}
};
然后你应该定义任何不在类外使用相同大小的矩阵的函数(这就是为什么我们有[]运算符)。请注意,*和/运算符适用于所有元素,不计算通常的矩阵 - 矩阵乘法或矩阵 - 矩阵除法。相反,您需要具有反转函数和乘法函数。
template<unsigned m, unsigned n, unsigned k>
matrix<m,k> const multiply(matrix<m,n> const& a, matrix<n,k> const& b);
template<unsigned m>
matrix<m,m> const invert(matrix<m,m> const&);
template<unsigned m, unsigned n>
matrix<n,m> const transpose(matrix<m,n> const&);
请注意,如果您有一种反转通用非方阵的方法,我不知道它,上面的模板只适用于方阵。填写我作为练习留给您的函数的代码。
要获得3矢量和3x3矩阵,您可以将它们设置为:
typedef matrix<3,1,float> vector3f;
typedef matrix<3,3,float> matrix3x3f;
请记住添加比较运算符以及您需要的任何其他内容。
如果您愿意,还可以添加矩阵标量和标量矩阵运算符和函数(比如,为矩阵中的所有元素添加标量)。
如果想要更好地控制[]运算符中的元素,可以使用向量作为基类,然后将矩阵定义为向量向量。这将给你相同的优势,但可能更容易适合你的心态(很多人认为矢量和矩阵是不同的类型)。