无法重载类操作符 * 以乘以同类的另一个实例

-1 投票
1 回答
29 浏览
提问于 2025-04-14 17:58

我正在尝试实现一个四元数,所以我想能够像这样连乘:a * b * c。我已经重载了__mul__这个运算符,但在运行时出现了一个错误:TypeError: unsupported operand type(s) for *: 'Quat' and 'Quat'

另一方面,如果我创建一个mult()方法,它就能正常工作。

import math
from .vec3 import Vec3

class Quat:
    @classmethod
    def from_axis_angle(cls, _axis=Vec3(1.0, 0.0, 0.0), _angle=0.0):
        w = math.cos(_angle * 0.5)
        x = _axis.x * math.sin(_angle * 0.5)
        y = _axis.y * math.sin(_angle * 0.5)
        z = _axis.z * math.sin(_angle * 0.5)
        return cls(w, x, y, z)

    def __init__(self, _w, _x, _y, _z):
        self.w = _w
        self.x = _x
        self.y = _y
        self.z = _z

    def mult(self, _rhs):
        lhs_vec = Vec3(self.x, self.y, self.z)
        rhs_vec = Vec3(_rhs.x, _rhs.y, _rhs.z)
        w = self.w * _rhs.w - lhs_vec.dot(rhs_vec)
        xyz = self.w * rhs_vec + _rhs.w * lhs_vec + lhs_vec.cross(rhs_vec)
        return Quat(w, xyz.x, xyz.y, xyz.z)

    def ___mul__(self, _rhs):
        lhs_vec = Vec3(self.x, self.y, self.z)
        rhs_vec = Vec3(_rhs.x, _rhs.y, _rhs.z)
        w = self.w * _rhs.w - lhs_vec.dot(rhs_vec)
        xyz = self.w * rhs_vec + _rhs.w * lhs_vec + lhs_vec.cross(rhs_vec)
        return Quat(w, xyz.x, xyz.y, xyz.z)
    
    def __rmul__(self, _rhs):
        return _rhs.__mul__(self)

    def to_axis_angle(self):
        xyz = Vec3(self.x, self.y, self.z)
        if xyz.is_zero():
            axis = Vec3(1.0, 0.0, 0.0)
            angle = 0
            return (axis, angle)

        axis = xyz.normalised()
        angle = math.acos(self.w) * 2.0
        return (axis, angle)

1 个回答

3

你在___mul__里似乎多了一个下划线。试试__mul__

撰写回答