同时进行运算符重载和方法调用
operator overload and method call at the same time
我想为我的 QUATERNION class 重载 *
运算符,但不知何故我无法将它与 QUATERNION 方法同时使用(Q4 示例)。
是否可以在不创建任何临时变量的情况下以某种方式使用 Q1*Q2.conjugated()
?
C:\Users\xXx\Documents\Arduino\libraries\QUATERNION\extras\Quaternions\main.cpp|19|error:
cannot bind non-const lvalue reference of type 'QUATERNION&' to an
rvalue of type 'QUATERNION'|
QUATERNION Q1(1,2,3,4);
QUATERNION Q2(5,6,7,8);
QUATERNION Q2c = Q2.conjugated();
QUATERNION Q3 = Q1*Q2c; // work fine
QUATERNION Q4 = Q1*Q2.conjugated(); // not working
QUATERNION.h
#ifndef QUATERNION_H
#define QUATERNION_H
class QUATERNION
{
public:
float w;
float x;
float y;
float z;
QUATERNION(void);
QUATERNION(float,float,float,float);
float magnitude(void);
void normalize(void);
void scale(float);
QUATERNION normalized(void);
QUATERNION conjugated(void);
};
// operatory ==========================================
QUATERNION operator * (QUATERNION&,QUATERNION&);
QUATERNION operator * (QUATERNION&,float);
bool operator == (QUATERNION&,QUATERNION&);
// funkcje ============================================
QUATERNION Q_mul(QUATERNION&,QUATERNION&);
QUATERNION Q_scaled(QUATERNION&,float);
QUATERNION Q_fromAngular(const float*);
void Q_toAngular(QUATERNION&,float*,bool);
#endif // QUATERNION_H
QUATERNION.cpp
#include "QUATERNION.h"
#include "math.h"
QUATERNION::QUATERNION() : QUATERNION(1,0,0,0)
{
}
QUATERNION::QUATERNION(float w,float x,float y,float z){
this->w = w;
this->x = x;
this->y = y;
this->z = z;
}
float QUATERNION::magnitude(){
return sqrt(w*w+x*x+y*y+z*z);
}
void QUATERNION::normalize(){
float invMag = 1.0/magnitude();
scale(invMag);
}
void QUATERNION::scale(float scalar){
w *= scalar;
x *= scalar;
y *= scalar;
z *= scalar;
}
QUATERNION QUATERNION::normalized(){
QUATERNION q = QUATERNION(w,x,y,z);
q.normalize();
return q;
}
QUATERNION QUATERNION::conjugated(){
return QUATERNION(w,-x,-y,-z);
}
// operatory ==========================================
QUATERNION operator * (QUATERNION &A,QUATERNION &B){
return Q_mul(A,B);
}
QUATERNION operator * (QUATERNION &q,float scalar){
return Q_scaled(q,scalar);
}
bool operator == (QUATERNION &A,QUATERNION &B){
float epsilon = 1.0e-5;
return fabs(A.w-B.w)<=epsilon && fabs(A.x-B.x)<=epsilon
&& fabs(A.y-B.y)<=epsilon && fabs(A.z-B.z)<=epsilon;
}
// funkcje ============================================
QUATERNION Q_mul(QUATERNION &A,QUATERNION &B){
return QUATERNION(
A.w * B.w - A.x * B.x - A.y * B.y - A.z * B.z, // w
A.w * B.x + A.x * B.w + A.y * B.z - A.z * B.y, // x
A.w * B.y - A.x * B.z + A.y * B.w + A.z * B.x, // y
A.w * B.z + A.x * B.y - A.y * B.x + A.z * B.w); // z
}
QUATERNION Q_scaled(QUATERNION &q,float scalar){
return QUATERNION(q.w*scalar,q.x*scalar,q.y*scalar,q.z*scalar);
}
QUATERNION Q_fromAngular(const float *w) {
float theta,q0,q1,q2,q3;
float dt = 1;
float x = w[0]*dt;
float y = w[1]*dt;
float z = w[2]*dt;
theta = sqrt(x*x + y*y + z*z);
if (theta<=1.0e-6) return QUATERNION(1,0,0,0);
q0 = cos(theta/2.0f);
q1 = sin(theta/2.0f)/theta * x;
q2 = sin(theta/2.0f)/theta * y;
q3 = sin(theta/2.0f)/theta * z;
return QUATERNION(q0,q1,q2,q3);
// w/theta - normalizacja wektora
}
void Q_toAngular(QUATERNION &q,float *angular,bool deg) {
// http://www.euclideanspace.com/physics/kinematics/angularvelocity/index.htm
float w=q.w,x=q.x,y=q.y,z=q.z;
if (w<0){
// w*=-1.0;
// x*=-1.0;
// y*=-1.0;
// z*=-1.0;
}
if (fabs(w)==1){
// unika dzielenia przez 0
// taki kwaternion nie zawiera rotacji
angular[0] = 0;
angular[1] = 0;
angular[2] = 0;
return;
}
// https://math.stackexchange.com/questions/3753611/quaternion-to-rotation-vector-sintheta-2-sqrt1-quaternion-w2
// theta = acos(w)*2
// sqrt(1-w*w) = sin(theta/2)
// float m = ( acos(w)*2.0 )/sqrt(1-w*w); // theta/sin(theta/2)
float theta = 2*acos(w);
float m = theta/sin(theta/2);
if (deg)
m*= 180.0/M_PI;
angular[0] = x*m;
angular[1] = y*m;
angular[2] = z*m;
}
在 QUATERNION operator * (QUATERNION& A,QUATERNION& B);
中,您通过 non-const 引用接受 A
和 B
。编译器希望您更改它们。对于乘法,这显然是错误的。将缺少的 const
添加到两个参数以及代码中的所有其他引用。
而且 Angular
似乎也是一种类型。您目前为此使用 float[3]
。
我想为我的 QUATERNION class 重载 *
运算符,但不知何故我无法将它与 QUATERNION 方法同时使用(Q4 示例)。
是否可以在不创建任何临时变量的情况下以某种方式使用 Q1*Q2.conjugated()
?
C:\Users\xXx\Documents\Arduino\libraries\QUATERNION\extras\Quaternions\main.cpp|19|error: cannot bind non-const lvalue reference of type 'QUATERNION&' to an rvalue of type 'QUATERNION'|
QUATERNION Q1(1,2,3,4);
QUATERNION Q2(5,6,7,8);
QUATERNION Q2c = Q2.conjugated();
QUATERNION Q3 = Q1*Q2c; // work fine
QUATERNION Q4 = Q1*Q2.conjugated(); // not working
QUATERNION.h
#ifndef QUATERNION_H
#define QUATERNION_H
class QUATERNION
{
public:
float w;
float x;
float y;
float z;
QUATERNION(void);
QUATERNION(float,float,float,float);
float magnitude(void);
void normalize(void);
void scale(float);
QUATERNION normalized(void);
QUATERNION conjugated(void);
};
// operatory ==========================================
QUATERNION operator * (QUATERNION&,QUATERNION&);
QUATERNION operator * (QUATERNION&,float);
bool operator == (QUATERNION&,QUATERNION&);
// funkcje ============================================
QUATERNION Q_mul(QUATERNION&,QUATERNION&);
QUATERNION Q_scaled(QUATERNION&,float);
QUATERNION Q_fromAngular(const float*);
void Q_toAngular(QUATERNION&,float*,bool);
#endif // QUATERNION_H
QUATERNION.cpp
#include "QUATERNION.h"
#include "math.h"
QUATERNION::QUATERNION() : QUATERNION(1,0,0,0)
{
}
QUATERNION::QUATERNION(float w,float x,float y,float z){
this->w = w;
this->x = x;
this->y = y;
this->z = z;
}
float QUATERNION::magnitude(){
return sqrt(w*w+x*x+y*y+z*z);
}
void QUATERNION::normalize(){
float invMag = 1.0/magnitude();
scale(invMag);
}
void QUATERNION::scale(float scalar){
w *= scalar;
x *= scalar;
y *= scalar;
z *= scalar;
}
QUATERNION QUATERNION::normalized(){
QUATERNION q = QUATERNION(w,x,y,z);
q.normalize();
return q;
}
QUATERNION QUATERNION::conjugated(){
return QUATERNION(w,-x,-y,-z);
}
// operatory ==========================================
QUATERNION operator * (QUATERNION &A,QUATERNION &B){
return Q_mul(A,B);
}
QUATERNION operator * (QUATERNION &q,float scalar){
return Q_scaled(q,scalar);
}
bool operator == (QUATERNION &A,QUATERNION &B){
float epsilon = 1.0e-5;
return fabs(A.w-B.w)<=epsilon && fabs(A.x-B.x)<=epsilon
&& fabs(A.y-B.y)<=epsilon && fabs(A.z-B.z)<=epsilon;
}
// funkcje ============================================
QUATERNION Q_mul(QUATERNION &A,QUATERNION &B){
return QUATERNION(
A.w * B.w - A.x * B.x - A.y * B.y - A.z * B.z, // w
A.w * B.x + A.x * B.w + A.y * B.z - A.z * B.y, // x
A.w * B.y - A.x * B.z + A.y * B.w + A.z * B.x, // y
A.w * B.z + A.x * B.y - A.y * B.x + A.z * B.w); // z
}
QUATERNION Q_scaled(QUATERNION &q,float scalar){
return QUATERNION(q.w*scalar,q.x*scalar,q.y*scalar,q.z*scalar);
}
QUATERNION Q_fromAngular(const float *w) {
float theta,q0,q1,q2,q3;
float dt = 1;
float x = w[0]*dt;
float y = w[1]*dt;
float z = w[2]*dt;
theta = sqrt(x*x + y*y + z*z);
if (theta<=1.0e-6) return QUATERNION(1,0,0,0);
q0 = cos(theta/2.0f);
q1 = sin(theta/2.0f)/theta * x;
q2 = sin(theta/2.0f)/theta * y;
q3 = sin(theta/2.0f)/theta * z;
return QUATERNION(q0,q1,q2,q3);
// w/theta - normalizacja wektora
}
void Q_toAngular(QUATERNION &q,float *angular,bool deg) {
// http://www.euclideanspace.com/physics/kinematics/angularvelocity/index.htm
float w=q.w,x=q.x,y=q.y,z=q.z;
if (w<0){
// w*=-1.0;
// x*=-1.0;
// y*=-1.0;
// z*=-1.0;
}
if (fabs(w)==1){
// unika dzielenia przez 0
// taki kwaternion nie zawiera rotacji
angular[0] = 0;
angular[1] = 0;
angular[2] = 0;
return;
}
// https://math.stackexchange.com/questions/3753611/quaternion-to-rotation-vector-sintheta-2-sqrt1-quaternion-w2
// theta = acos(w)*2
// sqrt(1-w*w) = sin(theta/2)
// float m = ( acos(w)*2.0 )/sqrt(1-w*w); // theta/sin(theta/2)
float theta = 2*acos(w);
float m = theta/sin(theta/2);
if (deg)
m*= 180.0/M_PI;
angular[0] = x*m;
angular[1] = y*m;
angular[2] = z*m;
}
在 QUATERNION operator * (QUATERNION& A,QUATERNION& B);
中,您通过 non-const 引用接受 A
和 B
。编译器希望您更改它们。对于乘法,这显然是错误的。将缺少的 const
添加到两个参数以及代码中的所有其他引用。
而且 Angular
似乎也是一种类型。您目前为此使用 float[3]
。