sandowk 2024-03-29 21:00 采纳率: 0%
浏览 9
已结题

C++使用Gunplot

这是我的代码,然后我想用PNUplot去画图,但是总是出现这个问题,说什么line 102 :invalid command,而且也Punplot里也啥都没有,之前简单画个正弦函数还是可以的,老师们求教

img

img

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <gnuplot-iostream.h>
struct Vector3D {
    double x, y, z;

    Vector3D operator+(const Vector3D& other) const {
        return { x + other.x, y + other.y, z + other.z };
    }

    Vector3D operator*(double scalar) const {
        return { x * scalar, y * scalar, z * scalar };
    }

    void print() const {
        std::cout << "(" << x << ", " << y << ", " << z << ")\n";
    }
};
double J0(double x)
{
    return _j0(x);
}
double J1(double x)
{
    return _j1(x);
}
const double pi = 3.14159265358979323846;
const double c = 3e8;
const double epsilon0 = 8.854187817e-12;
const double lambda0 = 1.5e-6;//波长
const double k0 = 2 * pi / lambda0;
const double n0 = 1.4682; // 介质的折射率
const double np = 1.0; // 粒子的折射率
const double r0 = 4.15e-6; // 光纤半径
const double kappa = 3.9e-12; // 耦合系数
const double E0 = 1.0; // 电场强度

Vector3D calculatePoyntingVector(double r, double phi, double delta)
{
    double Knew = k0 * n0 * sqrt(2.0 + 2.0 * sin(phi));
    double u0 = k0 * n0;
    double numerator = Knew * r0 * J0(u0 * r0) * J1(Knew * r0) - u0 * r0 * J1(u0 * r0) * J1(Knew * r0);
    double denominator = Knew * Knew - u0 * u0;
    double fraction = numerator / denominator;
    double S_scalar = (pi * pow(k0, 3) * c * pow(kappa, 2) * pow(E0, 2)) / (4 * r * epsilon0) * pow(fraction, 2) * pow(sin(delta - phi), 2);
    Vector3D S_vector = { r, phi, S_scalar };
    return S_vector;
}
int main() {
    // 初始化 gnuplot-iostream 的 Gnuplot 实例
    Gnuplot gp;

    // 设置 r 和 z 的范围和步长
    const double r_min = -100e-6, r_max = 100e-6, r_step =2e-6;
    const double z_min = 0, z_max = 600e-6, z_step = 2e-6;

    // 生成数据,这里我们用二维向量存储 (r, z, TotalS_z)
    std::vector<std::vector<std::tuple<double, double, double>>> matrix;

    for (double z = z_min; z <= z_max; z += z_step) {
        std::vector<std::tuple<double, double, double>> row;
        for (double r = r_min; r <= r_max; r += r_step) {
            double phi;
            if (r == 0) {
                phi = 0; // 当 r 等于 0 时,phi 应设置为合理的默认值
            }
            else {
                // 确保 acos 的参数在 [-1,1] 范围内
                double value = z / (r * 1.0000);
                if (value > 1.0) value = 1.0;
                if (value < -1.0) value = -1.0;
                phi = acos(value);
            }
            Vector3D S1 = calculatePoyntingVector(r, phi, 0);
            Vector3D S2 = calculatePoyntingVector(r, phi, pi / 2);
            double TotalS_z = S1.z + S2.z;
            // 检查 TotalS_z 是否是 NaN 或 Inf
            if (std::isnan(TotalS_z) || std::isinf(TotalS_z)) {
                TotalS_z = 0;
            }
            row.push_back(std::make_tuple(z, r, TotalS_z));
        }
        matrix.push_back(row);
    }
    
    // 发送数据到 GNUplot
    gp << "set pm3d map\n";
    gp << "set palette defined (0 'blue', 1 'green', 2 'yellow', 3 'red')\n";
    gp << "set cbrange [*:*]\n"; // 让 GNUplot 自动确定最佳范围
    gp << "set xlabel 'z (um)'\n";
    gp << "set ylabel 'r (um)'\n";
    gp << "splot '-' using 1:2:3 with pm3d title 'Energy density flow'\n";

    // 每行后加一个空行
    for (const auto& row : matrix) {
        gp.send1d(row);
        gp << "\n";
    }
        gp << "e\n";
    // 完成数据发送
    return 0;
}

  • 写回答

21条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-29 21:00
    关注
    获得0.45元问题酬金

    引自免费微信小程序:皆我百晓生

    根据您提供的信息和代码片段,您尝试使用gnuplot-iostream库将计算得到的能量密度流数据绘制成三维图像,但在执行过程中遇到了"Line 102: invalid command"的问题。

    首先,请确认您的gnuplot脚本命令是否正确。从代码中可以看出,您已成功设置了绘图的相关属性,并准备将矩阵中的数据发送给Gnuplot进行绘制。然而,Line 102: invalid command错误通常意味着Gnuplot无法解析在第102行所接收到的数据或命令。

    为了定位问题,我们需要检查在向Gnuplot发送数据的部分是否存在格式错误。以下是可能的解决步骤和代码修改建议:

    1. 确认每一行数据是否按照预期的格式(z:r:value)发送。看起来您的代码应该已经正确地组织了数据,但还是要仔细检查一下send1d(row)里的row内容。

    2. 您可以尝试在发送数据前,手动打印每一行要发送的数据,以验证其格式:

    for (const auto& row : matrix) {
        std::cout << "(" << std::get<0>(row[0]) << "," << std::get<1>(row[0]) << "," << std::get<2>(row[0]) << ")";
        // 输出所有数据点,用于检查格式
        for (size_t i = 1; i < row.size(); ++i) {
            std::cout << " (" << std::get<0>(row[i]) << "," << std::get<1>(row[i]) << "," << std::get<2>(row[i]) << ")";
        }
        std::cout << std::endl;
        gp.send1d(row);
        gp << "\n";
    }
    
    1. 验证gnuplot-iostream与Gnuplot版本兼容性,确保两者配合无误。

    2. 在发送完数据后,由于您已经在gp流中添加了换行符\n,因此理论上不需要额外的gp << "e\n";,因为send1d()方法会自动处理终止输入的命令。不过,有些情况下它可能是必需的,您可以保留这行,也可以尝试去掉看看是否影响结果。

    3. 如果上述步骤未能解决问题,请尝试简化测试,比如只发送几组简单的、已知有效的数据点到Gnuplot,以排除复杂计算导致的问题。

    4. 最后,确保编译器环境支持gnuplot-iostream库,并且库文件已正确链接。

    通过以上步骤排查,应该能找出并解决invalid command错误的原因。如果问题依然存在,请提供更多关于Line 102附近具体代码和输出的日志信息,以便进一步分析。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 4月6日
  • 创建了问题 3月29日

悬赏问题

  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装