quaternion.h
:
//****************************************************
//* quaternion.h *
//* *
//* Implementaion for a generalized quaternion class *
//* *
//* Written 1.25.00 by Angela Bennett *
//****************************************************
#ifndef _QUATERNION_H_
#define _QUATERNION_H_
//#include <iostream.h>
#include <math.h>
#ifdef SHOEMAKE
#include "EulerAngles.h"
#endif
template<class _Tp>
class Quaternion
{
public:
//Quaternion
// -default constructor
// -creates a new quaternion with all parts equal to zero
Quaternion(void);
//Quaternion
// -constructor
// -parametes : w, x, y, z elements of the quaternion
// -creates a new quaternion based on the elements passed in
Quaternion(_Tp wi, _Tp xi, _Tp yi, _Tp zi);
//Quaternion
// -constructor
// -parameters : 4D vector
// -creates a new quaternion based on the elements passed in
Quaternion(_Tp v[4]);
//Quaternion
// -copy constructor
// -parameters : const quaternion q
// -creates a new quaternion based on the quaternion passed in
Quaternion(const Quaternion<_Tp>& q);
#ifdef SHOEMAKE
//Quaternion
// -constructor
// -parameters : yaw, pitch, and roll of an Euler angle
// -creates a new quaternion based on the Euler elements passed in
// -used with Shoemakes code
Quaternion(_Tp e[3], int order);
#endif
//~Quaternion
// -default destructor
~Quaternion();
//operator=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q2 sets q2 to be an object of q3
inline Quaternion<_Tp> operator = (const Quaternion<_Tp>& q);
//operator+
// -parameters : q1 - Quaternion object
// -return value : Quaternion
// -when called on quaternion q2 adds q1 + q2 and returns the sum in a new quaternion
inline Quaternion<_Tp> operator + (const Quaternion<_Tp>& q);
//operator-
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on q1 subtracts q1 - q2 and returns the difference as a new quaternion
inline Quaternion<_Tp> operator - (const Quaternion<_Tp>& q);
//operator*
// -parameters : q1 - Quaternion object
// -return values : Quaternion
// -when called on a quaternion q2, multiplies q2 *q1 and returns the product in a new quaternion
inline Quaternion<_Tp> operator * (const Quaternion<_Tp>& q);
//operator/
// -parameters : q1 and q2- Quaternion objects
// -return values : Quaternion
// -divide q1 by q2 and returns the quotient as q1
inline Quaternion<_Tp> operator / (Quaternion<_Tp>& q);
//operator+=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3 adds q1 and q3 and returns the sum as q3
inline Quaternion<_Tp>& operator += (const Quaternion<_Tp>& q);
//operator-=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3, subtracts q1 from q3 and returns the difference as q3
inline Quaternion<_Tp>& operator -= (const Quaternion<_Tp>& q);
//operator*=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3, multiplies q3 by q1 and returns the product as q3
inline Quaternion<_Tp>& operator *= (const Quaternion<_Tp>& q);
//operator/=
// -parameters : q1- Quaternion object
// -return values : quaternion
// -when called on quaternion q3, divides q3 by q1 and returns the quotient as q3
inline Quaternion<_Tp>& operator /= (Quaternion<_Tp>& q);
//operator<<
// -parameters : ostream o, quaternion q
// -return values :
// -prints out a quaternion by it's components
/* friend inline ostream& operator << (ostream& output, const Quaternion<_Tp>& q)
{
output << "[" << q.w << ", " << "(" << q.x << ", " << q.y << ", " << q.z << ")]";
return output;
}
*/
//operator!=
// -parameters : q1 and q2- Quaternion objects
// -return value : bool
// -determines if q1 and q2 and equal
bool operator != (const Quaternion<_Tp>& q);
//operator==
// -parameters : q1 and q2- Quaternion objects
// -return value : bool
// -determines if q1 and q2 and equal
bool operator == (const Quaternion<_Tp>& q);
//other methods: norm, inverse, conjugate, toEuler
//norm
// -parameters : none
// -return value : _Tp
// -when called on a quaternion object q, returns the norm of q
_Tp norm();
//magnitude
// -parameters : none
// -return value : _Tp
// -when called on a quaternion object q, returns the magnitude q
_Tp magnitude();
//scale
// -parameters : s- a value to scale q1 by
// -return value: quaternion
// -returns the original quaternion with each part, w,x,y,z, multiplied by some scalar s
inline Quaternion<_Tp> scale(_Tp s);
//inverse
// -parameters : none
// -return value : quaternion
// -when called on a quaternion object q, returns the inverse of q
inline Quaternion<_Tp> inverse();
//conjugate
// -parameters : none
// -return value : quaternion
// -when called on a quaternion object q, returns the conjugate of q
inline Quaternion<_Tp> conjugate();
//UnitQuaternion
// -parameters : none
// -return value : quaternion
// -when called on quaterion q, takes q and returns the unit quaternion of q
inline Quaternion<_Tp> UnitQuaternion();
// -parameters : 3D vector of type _Tp
// -return value : void
// -when given a 3D vector, v, rotates v by the quaternion
inline void QuatRotation(_Tp v[3]);
#ifdef SHOEMAKE
// -parameters : empty 3D vector, rotation order
// -return : void
// - converts this quaternion into Euler angles
void toEuler(_Tp e[3], int order);
#endifenter code here
private:
// [w, (x, y, z)]
_Tp w, x, y, z;
};
#endif
quaternion.cpp
:
//****************************************************
//* quaternion.c++ *
//* *
//* Implementaion for a generalized quaternion class *
//* *
//* Written 1.25.00 by Angela Bennett *
//****************************************************
#include "quaternion.h"
//Quaternion
// -default constructor
// -creates a new quaternion with all parts equal to zero
template<class _Tp>
Quaternion<_Tp>::Quaternion(void)
{
x = 0;
y = 0;
z = 0;
w = 0;
}
//Quaternion
// -constructor
// -parametes : x, y, z, w elements of the quaternion
// -creates a new quaternion based on the elements passed in
template<class _Tp>
Quaternion<_Tp>::Quaternion(_Tp wi, _Tp xi, _Tp yi, _Tp zi)
{
w = wi;
x = xi;
y = yi;
z = zi;
}
//Quaternion
// -constructor
// -parameters : vector/array of four elements
// -creates a new quaternion based on the elements passed in
template<class _Tp>
Quaternion<_Tp>::Quaternion(_Tp v[4])
{
w = v[0];
x = v[1];
y = v[2];
z = v[3];
}
//Quaternion
// -copy constructor
// -parameters : const quaternion q
// -creates a new quaternion based on the quaternion passed in
template<class _Tp>
Quaternion<_Tp>::Quaternion(const Quaternion<_Tp>& q)
{
w = q.w;
x = q.x;
y = q.y;
z = q.z;
}
#ifdef SHOEMAKE
//Quaternion
// -constructor
// -parameters : yaw, pitch, and roll of an Euler angle
// -creates a new quaternion based on the Euler elements passed in
// -used with Shoemakes code
template<class _Tp>
Quaternion<_Tp>::Quaternion(_Tp e[3], int order)
{
EulerAngles ea;
ea.x = e[0];
ea.y = e[1];
ea.z = e[2];
ea.w = order;
Quat q = Eul_ToQuat(ea);
x = q.x;
y = q.y;
z = q.z;
w = q.w;
}
#endif
//~Quaternion
// -destructor
// -deleted dynamically allocated memory
template<class _Tp>
Quaternion<_Tp>::~Quaternion()
{
}
//operator=
// -parameters : q1 - Quaternion object
// -return value : Quaternion
// -when called on quaternion q2 sets q2 to be an object of q3
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator = (const Quaternion<_Tp>& q)
{
w = q.w;
x = q.x;
y = q.y;
z = q.z;
return (*this);
}
//operator+
// -parameters : q1 - Quaternion object
// -return value : Quaternion
// -when called on quaternion q2 adds q1 + q2 and returns the sum in a new quaternion
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator + (const Quaternion<_Tp>& q)
{
return Quaternion(w+q.w, x+q.x, y+q.y, z+q.z);
}
//operator-
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on q1 subtracts q1 - q2 and returns the difference as a new quaternion
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator - (const Quaternion<_Tp>& q)
{
return Quaternion(w-q.w, x-q.x, y-q.y, z-q.z);
}
//operator*
// -parameters : q1 - Quaternion object
// -return values : Quaternion
// -when called on a quaternion q2, multiplies q2 *q1 and returns the product in a new quaternion
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator * (const Quaternion<_Tp>& q)
{
return Quaternion(
w*q.w - x*q.x - y*q.y - z*q.z,
w*q.x + x*q.w + y*q.z - z*q.y,
w*q.y + y*q.w + z*q.x - x*q.z,
w*q.z + z*q.w + x*q.y - y*q.x);
}
//operator/
// -parameters : q1 and q2- Quaternion objects
// -return values : Quaternion
// -divide q1 by q2 and returns the quotient q1
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator / (Quaternion<_Tp>& q)
{
return ((*this) * (q.inverse()));
}
//operator+=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3, adds q1 and q3 and returns the sum as q3
template<class _Tp>
Quaternion<_Tp>& Quaternion<_Tp>::operator += (const Quaternion<_Tp>& q)
{
w += q.w;
x += q.x;
y += q.y;
z += q.z;
return (*this);
}
//operator-=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3, subtracts q1 from q3 and returns the difference as q3
template<class _Tp>
Quaternion<_Tp>& Quaternion<_Tp>::operator -= (const Quaternion<_Tp>& q)
{
w -= q.w;
x -= q.x;
y -= q.y;
z -= q.z;
return (*this);
}
//operator*=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3, multiplies q3 by q1 and returns the product as q3
template<class _Tp>
Quaternion<_Tp>& Quaternion<_Tp>::operator *= (const Quaternion<_Tp>& q)
{
_Tp w_val = w*q.w - x*q.x - y*q.y - z*q.z;
_Tp x_val = w*q.x + x*q.w + y*q.z - z*q.y;
_Tp y_val = w*q.y + y*q.w + z*q.x - x*q.z;
_Tp z_val = w*q.z + z*q.w + x*q.y - y*q.x;
w = w_val;
x = x_val;
y = y_val;
z = z_val;
return (*this);
}
//operator/=
// -parameters : q1- Quaternion object
// -return values : quaternion
// -when called on quaternion q3, divides q3 by q1 and returns the quotient as q3
template<class _Tp>
Quaternion<_Tp>& Quaternion<_Tp>::operator /= (Quaternion<_Tp>& q)
{
(*this) = (*this)*q.inverse();
return (*this);
}
//operator!=
// -parameters : q1 and q2- Quaternion objects
// -return value : bool
// -determines if q1 and q2 are not equal
template<class _Tp>
bool Quaternion<_Tp>::operator != (const Quaternion<_Tp>& q)
{
return (w!=q.w || x!=q.x || y!=q.y || z!=q.z) ? true : false;
}
//operator==
// -parameters : q1 and q2- Quaternion objects
// -return value : bool
// -determines if q1 and q2 are equal
template<class _Tp>
bool Quaternion<_Tp>::operator == (const Quaternion<_Tp>& q)
{
return (w==q.w && x==q.x && y==q.y && z==q.z) ? true : false;
}
//norm
// -parameters : none
// -return value : _Tp
// -when called on a quaternion object q, returns the norm of q
template<class _Tp>
_Tp Quaternion<_Tp>::norm()
{
return (w*w + x*x + y*y + z*z);
}
//magnitude
// -parameters : none
// -return value : _Tp
// -when called on a quaternion object q, returns the magnitude q
template<class _Tp>
_Tp Quaternion<_Tp>::magnitude()
{
return sqrt(norm());
}
//scale
// -parameters : s- a value to scale q1 by
// -return value: quaternion
// -returns the original quaternion with each part, w,x,y,z, multiplied by some scalar s
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::scale(_Tp s)
{
return Quaternion(w*s, x*s, y*s, z*s);
}
// -parameters : none
// -return value : quaternion
// -when called on a quaternion object q, returns the inverse of q
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::inverse()
{
return conjugate().scale(1/norm());
}
//conjugate
// -parameters : none
// -return value : quaternion
// -when called on a quaternion object q, returns the conjugate of q
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::conjugate()
{
return Quaternion(w, -x, -y, -z);
}
//UnitQuaternion
// -parameters : none
// -return value : quaternion
// -when called on quaterion q, takes q and returns the unit quaternion of q
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::UnitQuaternion()
{
return (*this).scale(1/(*this).magnitude());
}
// -parameters : vector of type _Tp
// -return value : void
// -when given a 3D vector, v, rotates v by this quaternion
template<class _Tp>
void Quaternion<_Tp>::QuatRotation(_Tp v[3])
{
Quaternion <_Tp> qv(0, v[0], v[1], v[2]);
Quaternion <_Tp> qm = (*this) * qv * (*this).inverse();
v[0] = qm.x;
v[1] = qm.y;
v[2] = qm.z;
}
#ifdef SHOEMAKE
// -parameters : integer order- which will specify the order of the rotation, q- quaternion
// -return value : Euler angle
// -
template<class _Tp>
void Quaternion<_Tp>::toEuler(_Tp e[3], int order)
{
Quat q;
q.w = 0;
q.x = e[0];
q.y = e[1];
q.z = e[2];
EulerAngles ea = Eul_FromQuat(q, order);
w = ea.w;
x = ea.x;
y = ea.y;
z = ea.z;
}
#endif
Main.cpp
:
// Quaternion test class
#include "quaternion.h"
int main(int argc, char **argv)
{
cout << "Quaternion class test" << endl;
cout << "Constructors:" << endl;
float vect[4] = { 5, 6, 7, 8 };
float v[3]= { 1.1, 2.34, 7.65 };
Quaternion <float> q1;
Quaternion <float> q2(1.0f, 2.0f, 3.0f, 4.0f);
Quaternion <float> q3(q2);
Quaternion <float> q4(vect);
Quaternion <float> q7(3.0f, 1.0f, -2.0f, 1.0f);
Quaternion <float> q8(2.0f, -1.0f, 2.0f, 3.0f);
Quaternion <float> q9(3.0f, 1.0f, -2.0f, 1.0f);
Quaternion <float> q16(0.0f, 1.1f, 2.34f, 7.65f);
cout << "q1=" << q1 << endl;
cout << "q2=" << q2 << endl;
cout << "q3=" << q3 << endl;
cout << "q4=" << q4 << endl;
cout << "Operators:" << endl;
cout << "Operator =" << endl;
Quaternion <float> q5 = q2;
cout << "q5 = " << q5 << endl;
cout << "Operator +" << endl;
Quaternion <float> q6 = q5 + q4;
cout << "q5 + q4 = " << q6 << endl; //should equal (6,8,10,12)
cout << "Operator -" << endl;
q6 = q5 - q4;
cout << "q5 - q4 = " << q6 << endl; //should equal (-4,-4,-4,-4)
cout << "Operator *" << endl;
q6 = q7 * q8;
cout << "q7 * q8 = " << q6 << endl; //should equal (8,-9,-2,11)
cout << "Operator /" << endl;
q6 = q8.inverse();
cout << "q7/(q8.inverse) = " << q7/q6 << endl;//should equal [8, (-9, -2, 11)]
cout << "Operator += " << endl;
q4 += q5;
cout << "q4 += q5 is " << q4 << endl;//should equal [6, (8, 10, 12)]
cout << "Operator -= " << endl;
q5 -= q5;
cout << "q5 -= q5 is " << q5 << endl;//should equal [0, (0, 0, 0)]
cout << "Operator *= " << endl;
q7 *= q8;
cout << "q7 *= q8 is " << q7 << endl;//should equal [8, (-9, -2, 11)]
cout << "Operator /= " << endl;
q7= q9;
q6 = q8.inverse();
q7/=q6;
cout << "q7 /= q8.inverse() is " << q7 << endl;//should equal [8, (-9, -2, 11)]
cout << "Operator != " << endl;
if (q2 != q2)
cout << "doesn't work:(" << endl;
else
cout << "works!" << endl;
cout << "Operator == " << endl;
if (q2 == q2)
cout << "works!" << endl;
else
cout << "doesn't work:(" << endl;
cout << "Norm of q2 = " << q2.norm() << endl; //30
cout << "Magnitude of q2 = " << q2.magnitude() << endl; //5.4772255....
q6 = q2.scale(2);
cout << "Scale of q2 by 2 = " << q6 << endl;//should equal [2, (4, 6, 8)]
cout << "Inverse of q8 = " << q8.inverse() << endl;//should equal [0.111..., (0.0555..., -0.111..., -0.1666...)]
cout << "Conjugate of q8 = " << q8.conjugate() <<endl; //should equal (2,1,-2,-3)
cout << "Unit Quaternion of q8 is " << q8.UnitQuaternion() << endl;
//QuatRot
q8.QuatRotation(v);
cout << "Rotate q8 by 1.1, 2.34, 7.65 = " << v[0] << ", " << v[1] << ", " << v[2] << endl;
//should get the same answer as QuatRot(v, q8) ignoring the w factor
q2=q8*q16;
q3=q2*(q8.inverse());
cout << q3 << endl;
#ifdef SHOEMAKE
float v1[3] = { 2.3f, 3.2f, 4.3f };
cout << "\nEuler -> Quaternion convertion test:" << endl;
cout << " -in vector: (" << v1[0] << ", " << v1[1] << ", " << v1[2] << ")" << endl;
Quaternion <float> q10(v1, EulOrdZYXs);
cout << " -out quaternion: " << q10 << endl;
cout << "Quaternion -> Euler convertion test:" << endl;
cout << " -in quaternion: " << q10 << endl;
q10.toEuler(v1, EulOrdZYXs);
cout << " -out vector: (" << v1[0] << ", " << v1[1] << ", " << v1[2] << ")" << endl;
#endif
return 1;
}
我在Visual Studio 2012中创建了基于Quaternion的示例项目。我从http://www.ncsa.illinois.edu/People/kindr/emtc/quaternions/获得了此代码示例,但在编译时它会抛出以下错误:
Error 24 error LNK2019: unresolved external symbol "public: void __thiscall Quaternion<float>::QuatRotation(float * const)" (?QuatRotation@?$Quaternion@M@@QAEXQAM@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 18 error LNK2019: unresolved external symbol "public: float __thiscall Quaternion<float>::norm(void)" (?norm@?$Quaternion@M@@QAEMXZ) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 19 error LNK2019: unresolved external symbol "public: float __thiscall Quaternion<float>::magnitude(void)" (?magnitude@?$Quaternion@M@@QAEMXZ) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 23 error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::UnitQuaternion(void)" (?UnitQuaternion@?$Quaternion@M@@QAE?AV1@XZ) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 20 error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::scale(float)" (?scale@?$Quaternion@M@@QAE?AV1@M@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 7 error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::operator=(class Quaternion<float> const &)" (??4?$Quaternion@M@@QAE?AV0@ABV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 8 error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::operator+(class Quaternion<float> const &)" (??H?$Quaternion@M@@QAE?AV0@ABV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 11 error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::operator/(class Quaternion<float> &)" (??K?$Quaternion@M@@QAE?AV0@AAV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 10 error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::operator*(class Quaternion<float> const &)" (??D?$Quaternion@M@@QAE?AV0@ABV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 9 error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::operator-(class Quaternion<float> const &)" (??G?$Quaternion@M@@QAE?AV0@ABV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 21 error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::inverse(void)" (?inverse@?$Quaternion@M@@QAE?AV1@XZ) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 22 error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::conjugate(void)" (?conjugate@?$Quaternion@M@@QAE?AV1@XZ) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 12 error LNK2019: unresolved external symbol "public: class Quaternion<float> & __thiscall Quaternion<float>::operator+=(class Quaternion<float> const &)" (??Y?$Quaternion@M@@QAEAAV0@ABV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 15 error LNK2019: unresolved external symbol "public: class Quaternion<float> & __thiscall Quaternion<float>::operator/=(class Quaternion<float> &)" (??_0?$Quaternion@M@@QAEAAV0@AAV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 14 error LNK2019: unresolved external symbol "public: class Quaternion<float> & __thiscall Quaternion<float>::operator*=(class Quaternion<float> const &)" (??X?$Quaternion@M@@QAEAAV0@ABV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 13 error LNK2019: unresolved external symbol "public: class Quaternion<float> & __thiscall Quaternion<float>::operator-=(class Quaternion<float> const &)" (??Z?$Quaternion@M@@QAEAAV0@ABV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 17 error LNK2019: unresolved external symbol "public: bool __thiscall Quaternion<float>::operator==(class Quaternion<float> const &)" (??8?$Quaternion@M@@QAE_NABV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 16 error LNK2019: unresolved external symbol "public: bool __thiscall Quaternion<float>::operator!=(class Quaternion<float> const &)" (??9?$Quaternion@M@@QAE_NABV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 2 error LNK2019: unresolved external symbol "public: __thiscall Quaternion<float>::Quaternion<float>(void)" (??0?$Quaternion@M@@QAE@XZ) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 3 error LNK2019: unresolved external symbol "public: __thiscall Quaternion<float>::Quaternion<float>(float,float,float,float)" (??0?$Quaternion@M@@QAE@MMMM@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 4 error LNK2019: unresolved external symbol "public: __thiscall Quaternion<float>::Quaternion<float>(float * const)" (??0?$Quaternion@M@@QAE@QAM@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 5 error LNK2019: unresolved external symbol "public: __thiscall Quaternion<float>::Quaternion<float>(class Quaternion<float> const &)" (??0?$Quaternion@M@@QAE@ABV0@@Z) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 6 error LNK2019: unresolved external symbol "public: __thiscall Quaternion<float>::~Quaternion<float>(void)" (??1?$Quaternion@M@@QAE@XZ) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj sampleQuad
Error 25 error LNK1120: 23 unresolved externals c:\users\bhc0006\documents\visual studio 2012\Projects\sampleQuad\Debug\sampleQuad.exe sampleQuad
为什么会出现这种错误?
如何纠正此错误?
使用C ++计算四元数轮换的任何其他解决方案?
答案 0 :(得分:0)
这些错误是源文件(.cpp)中模板定义的结果。在编译Main.cpp
时尝试实例化模板时,编译器没有完整的类型信息,因为完整类型信息包含在单独的编译单元(Quaternion.cpp
文件)中。因此,当链接器试图在Main.cpp
中找到与相关模板实例化相对应的符号时,它就不能。您可以使用以下方法之一解决此问题:
Main.cpp
template class Quaternion<float>;
在此处查看更多内容:Storing C++ template function definitions in a .CPP file