【问题标题】:operator overload and method call at the same time运算符重载和方法调用同时进行
【发布时间】:2020-08-24 16:16:24
【问题描述】:

我想为我的 QUATERNION 类重载 * 运算符,但不知何故,我无法将它与 QUATERNIONs 方法同时使用(Q4 示例)。 是否可以在不创建任何临时变量的情况下以某种方式使用Q1*Q2.conjugated()

C:\Users\xXx\Documents\Arduino\libraries\QUATERNION\extras\Quaternions\main.cpp|19|错误: 无法将“QUATERNION&”类型的非常量左值引用绑定到 '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;
}

【问题讨论】:

    标签: c++ operator-overloading


    【解决方案1】:

    QUATERNION operator * (QUATERNION&amp; A,QUATERNION&amp; B); 中,您通过非常量引用接受AB。编译器希望您更改它们。对于乘法来说,这显然是错误的。将缺少的 const 添加到两个参数以及代码中的所有其他引用中。

    似乎Angular 可能是一种类型。您目前为此使用float[3]

    【讨论】:

    • 我将 const 添加到:QUATERNION operator * (const QUATERNION&,const QUATERNION&);和 QUATERNION Q_mul(const QUATERNION&,const QUATERNION&);它看起来像它的工作。但我的问题是为什么需要它?而且我没有得到 Angular 的东西。
    • @Dobijasek:右值不能绑定到非 const 左值引用。另外,您最好将访问器方法标记为const
    猜你喜欢
    • 2013-05-14
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 2010-12-31
    相关资源
    最近更新 更多