代码之家  ›  专栏  ›  技术社区  ›  John

减少C中的内存消耗++

  •  0
  • John  · 技术社区  · 3 周前

    我正在C++上编写一个实现与四元数交互的头文件。四元数可以解释为 a + bi + cj + dk ,因此其组件存储在 m_value 在里面 b, c, d, a 顺序我还支持将四元数表示为标量&矢量。我注意到在方法上 updateComponents() 我使用的内存是实际需要的两倍。我该怎么解决? m_value 以及标量&需要矢量表示。

    #ifndef QUAT_HPP
    #define QUAT_HPP
    
    #include <cmath>
    
    template<typename T>
    struct matrix_t {
        T data[16];
    };
    
    template<typename T>
    struct vector3_t {
        T x, y, z;
    };
    
    template<typename T>
    class Quat {
    public:
        Quat() : scalar(0), vector{0, 0, 0} {
            updateComponents();
        }
    
        Quat(T a, T b, T c, T d) : scalar(a), vector{b, c, d} {
            updateComponents();
        }
    
        Quat(T angle, bool mode, vector3_t<T> axes) {
            if (!mode) {
                angle = angle * M_PI / 180;
            }
            T norm = std::sqrt(axes.x * axes.x + axes.y * axes.y + axes.z * axes.z);
            scalar = std::cos(angle / 2);
            vector.x = axes.x / norm * std::sin(angle / 2);
            vector.y = axes.y / norm * std::sin(angle / 2);
            vector.z = axes.z / norm * std::sin(angle / 2);
            updateComponents();
        }
    
        const T *data() const { return m_value; };
    
        Quat<T> operator+(const Quat<T> &q2) const {
            return Quat(scalar + q2.scalar, vector.x + q2.vector.x, vector.y + q2.vector.y, vector.z + q2.vector.z);
        }
    
        Quat<T> &operator+=(const Quat<T> &q2) {
            *this = *this + q2;
            updateComponents();
            return *this;
        }
    
        Quat<T> operator-(Quat q2) const {
            return Quat(scalar - q2.scalar, vector.x - q2.vector.x, vector.y - q2.vector.y, vector.z - q2.vector.z);
        }
    
        Quat<T> &operator-=(Quat q2) {
            *this = *this - q2;
            updateComponents();
            return *this;
        }
    
        Quat<T> operator*(Quat q2) const {
            T a1 = scalar, b1 = vector.x, c1 = vector.y, d1 = vector.z;
            T a2 = q2.scalar, b2 = q2.vector.x, c2 = q2.vector.y, d2 = q2.vector.z;
            return Quat(
                    a1 * a2 - b1 * b2 - c1 * c2 - d1 * d2,
                    a1 * b2 + a2 * b1 + c1 * d2 - c2 * d1,
                    a1 * c2 + a2 * c1 + d1 * b2 - d2 * b1,
                    a1 * d2 + a2 * d1 + b1 * c2 - b2 * c1);
        }
    
        Quat<T> operator*(T s) const { return Quat(scalar * s, vector.x * s, vector.y * s, vector.z * s); }
    
        Quat<T> operator*(vector3_t<T> vec) const {
            Quat<T> q2 = Quat(0, vec.x, vec.y, vec.z);
            return *this * q2;
        }
    
        Quat<T> operator~() const { return Quat(scalar, -vector.x, -vector.y, -vector.z); }
    
        bool operator==(Quat q2) const {
            return (scalar == q2.scalar && vector.x == q2.vector.x && vector.y == q2.vector.y && vector.z == q2.vector.z);
        }
    
        bool operator!=(Quat q2) const { return !(*this == q2); }
    
        explicit operator T() const {
            return std::sqrt(scalar * scalar + vector.x * vector.x + vector.y * vector.y + vector.z * vector.z);
        }
    
        matrix_t<T> rotation_matrix() const {
            Quat<T> q = normalize();
            T s = q.scalar, x = q.vector.x, y = q.vector.y, z = q.vector.z;
            T r_11 = 1 - 2 * y * y - 2 * z * z, r_12 = 2 * x * y - 2 * z * s, r_13 = 2 * x * z + 2 * y * s,
              r_21 = 2 * x * y + 2 * z * s, r_22 = 1 - 2 * x * x - 2 * z * z, r_23 = 2 * y * z - 2 * x * s,
              r_31 = 2 * x * z - 2 * y * s, r_32 = 2 * y * z + 2 * x * s, r_33 = 1 - 2 * x * x - 2 * y * y;
            return {r_11, r_21, r_31, 0, r_12, r_22, r_32, 0, r_13, r_23, r_33, 0, 0, 0, 0, 1};
        }
    
        matrix_t<T> matrix() const {
            return {scalar, -vector.x, -vector.y, -vector.z, vector.x, scalar, -vector.z, vector.y,
                    vector.y, vector.z, scalar, -vector.x, vector.z, -vector.y, vector.x, scalar};
        }
    
        T angle(bool mode = true) const { return mode ? 2 * std::acos(scalar) : 2 * std::acos(scalar) * 180 / M_PI; }
    
        vector3_t<T> apply(vector3_t<T> vec) const {
            Quat<T> q = normalize();
            Quat<T> qv = q * vec;
            Quat<T> qq = qv * (~q);
            return {qq.vector.x, qq.vector.y, qq.vector.z};
        }
    
    private:
        T m_value[4];
        T scalar;
        vector3_t<T> vector;
    
        void updateComponents() {
            m_value[3] = scalar;
            m_value[0] = vector.x;
            m_value[1] = vector.y;
            m_value[2] = vector.z;
        }
    
        Quat<T> normalize() const {
            T norm = T(*this);
            return *this * (1 / norm);
        }
    };
    #endif
    
    

    我读过关于 union ,但我认为它不会像我预期的那样高效记忆。

    1 回复  |  直到 3 周前
        1
  •  0
  •   Smasheded    3 周前

    如果需要 *data() 要返回原样,您有两个选项。使用 m_value 对于所有的东西来说,使用它看起来都不太好 [0] 而不是 .x ect,但它会做你想做的事情,否则代码的功能会完全相同。 或者,你可以通过以下方式进入手动内存管理的杂草中 new 对本来应该是 m_value 每个 数据 呼叫如果你不小心的话,这可能会很快使用比现在多得多的内存,但它的优点是不会让其他代码像现在这样干扰你的私人成员