错误:流体模拟属性梯度计算中没有运算符“+=”与 float 和 Vector2 匹配

问题描述 投票:0回答:1

我正在尝试遵循 C++ 和 OpenGL 中的 Sebastian Lague 的流体模拟 视频。我现在正在计算

propertyGradient
值(时间戳是 14:15)。 我将尝试在下面提供所有相关的代码。

float CalculatePropertyGradient(Vector2 samplePoint, const std::vector<Vector2>& positions, const std::vector<float>& particleProperties, float smoothingRadius, float mass)
{
    float propertyGradient = 0.0f;
    DensityCalculator calculator(positions, smoothingRadius); 
    for (int i = 0; i < positions.size(); i++)
    {
        float dst = (positions[i] - samplePoint).magnitude();
        Vector2 dir = (positions[i] - samplePoint) / dst;
        float slope = SmoothingKernelDerivative(dst, smoothingRadius);
        float density = calculator.CalculateDensity(positions[i]); 
        Vector2 scaledDir = dir * particleProperties[i];
        propertyGradient += -(scaledDir) * slope *  mass / density;
    }
    return propertyGradient;
}

但是我在该行中遇到语法错误:

propertyGradient += -(scaledDir) * slope *  mass / density;
在 += 运算符下,我的 Vector2 类不支持涉及 float 和 vector2 的此操作

我的向量2类:

class Vector2 {
public:
    float X;
    float Y;

    Vector2(float x, float y) : X(x), Y(y) {}

    float magnitude() const {
        return sqrt(X * X + Y * Y);
    }

    Vector2 operator-(const Vector2& other) const {
        return Vector2(X - other.X, Y - other.Y);
    }

    Vector2 operator/(const float& scalar) const {
        return Vector2(X / scalar, Y / scalar);
    }

    Vector2 operator*(const float& right) const {
        return Vector2(X * right, Y * right);
    }

    Vector2 operator-(const float& scalar) const {
        return Vector2(X - scalar, Y - scalar);
    }

    Vector2 operator*(const Vector2& other) const {
        return Vector2(X * other.X, Y * other.Y);
    }
    Vector2 Zero() {
        return Vector2(0.0f, 0.0f);
    }
    
    Vector2 operator-() const {
        return Vector2(-X, -Y);
    }
    Vector2& operator+=(const float& scalar) {
        X += scalar;
        Y += scalar;
        return *this;
    }
};

我的密度等级:

class DensityCalculator {
private:
    std::vector<float> densities;
    std::vector<Vector2> positions;
    float smoothingRadius;

public:
    DensityCalculator(const std::vector<Vector2>& positions, float smoothingRadius)
        : positions(positions), smoothingRadius(smoothingRadius) {}

    void PreCalculateDensities() {
        densities.clear();
        for (const auto& position : positions) {
            densities.push_back(CalculateDensity(position));
        }
    }

    float CalculateDensity(Vector2 position) const {
        float density = 0;
        const float mass = 1;

        for (const auto& p : positions) {
            float dst = (p - position).magnitude();
            if (dst <= smoothingRadius) {
                float influence = SmoothingKernel(smoothingRadius, dst);
                density += mass * influence;
            }
        }
        return density;

    }

    float GetDensity(int index) const {
        return densities[index];
    }
};

SmoothingKernel 和 SmoothingKernel 导数函数:

float SmoothingKernel(float radius, float dst)
{
    if (dst < radius)
    {
        float volume = M_PI * pow(radius, 8) / 4;
        float v = std::max(radius * radius - dst * dst, 0.0f);
        return ((v * v * v) / volume);
    }
    else
    {
        return 0;
    }
}
static float SmoothingKernelDerivative(float dst, float radius)
{
    if (dst >= radius)
        return 0;
    float f = radius * radius - dst * dst;
    float scale = -24 / (M_PI * pow(radius, 8));
    return scale * dst * f * f;
}

这是我的主函数中的函数调用:

for (int i = 0; i < rows; ++i)
{
    for (int j = 0; j < cols; ++j) {
        float x = distX(mt);
        float y = distY(mt);
        balls.emplace_back(x, y, 0.0, 0.0, radius);

        // Calculate the value of ExampleFunction at the particle's location and store it in particleProperties
        float propertyValue = ExampleFunction(Vector2(x, y));
        particleProperties.push_back(propertyValue);
    }
}

ExampleFunction 就是

static float ExampleFunction(Vector2(pos))
{
    return cos(pos.Y - 3 + sin(pos.X));
}

我已经尝试过将vector2的运算符+=声明为作用于const对象,如另一篇文章所建议的,但我收到一个错误,X和Y必须是可修改的值。

c++ opengl vector floating-point operator-overloading
1个回答
0
投票

您没有接线员

float += Vector2

Vector2
类中实现以下内容

friend constexpr Vector2 operator += (float lhs, const Vector2& rhs) { /*...*/ }

或室外

constexpr Vector2 operator += (float lhs, const Vector2& rhs) { /*...*/ }
© www.soinside.com 2019 - 2024. All rights reserved.