首页 文章

用于散点图的排序浮点矢量(C / QCustomPlot)

提问于
浏览
0

Questions:

1 - 以相同的顺序对多个浮点向量进行排序(保持对应)

2 - QCustomPlot(QCP)仅绘制散点图的外边界 .

(回答这两个问题中的任何一个都可以解决我的问题)

Situation:

我有3个用于绘图的向量:

std::vector<float> x, y;
std::vector<int> hits;

得到的图是点击或未命中散点图 . 得到的图由QCustomPlot曲线使用,曲线最终为圆形“涂鸦” . 它只需要看起来类似于一个内部没有“涂鸦”的圆圈 . 我需要这个情节覆盖另一个情节 .

我对 xyhits 的初始顺序没有多少控制权 .

xy 按传统网格索引排序:

x = -8, -8, -8, -8, -8,  -4, -4, -4, -4, -4, ... 8
y = -8, -4,  0,  4,  8,  -8, -4,  0,  4,  8, ... 8

hits 基于更快(让's just say archer'箭头)基于快速目标的范围和速度成功命中(让我们只说鸟) .

得到的图是基于鸟作为中心参考的命中的外部boudary .

数据向量可以非常大 .

Method 1: 我可以计算范围和角度 . 然后对浮动向量进行排序:按顺序对角度进行排序,以便在QCustomPlot绘制外部边界时不使用'scribbles' . 但是,我需要知道如何根据 angle 的排序将相应的 xy 值保持在一起 .

// Make range and angle vectors for sorting
std::vector<float> range, angle;
for(int i = 0; i < x.size(); ++i {

    float r = sqrt(x[i]*x[i] + y[i]*y[i]);
    range.push_back(r);

    float a = 0;
    if(y < 0)
        a = -acos(x[i]/r);
    else
        a = acos(x[i]/r);
    angle.push_back(a);
}

// Sort all vectors by ascending angle vector.
/* Do stuff here! */

// Set up boundary plot data
QVector<float> plot_x, plot_y;
for(int i = 0; i < x.size(); ++i {
    if(hits[i]) {
        plot_x.push_back(x[i]);
        plot_y.push_back(y[i]);
    }
}
// curve is a QCPCurve object already existing.
curve->addData(plot_x, plot_y); // Already sorted QVectors

Method 2: 获取 QCustomPlot curve->addData(x, y) 成员仅绘制散点图 hits 的"perimeter line" . 我尝试过使用 QCPScatterStyle.setCustomPath ,但没有成功 .

先感谢您! -约翰

1 回答

  • 1

    如果要使用某些条件对多个向量进行排序,并且所有索引都对应创建一个新的向量作为索引,并对其进行排序,则使用这些索引创建新向量:

    #include <cmath>
    #include <QDebug>
    
    static float calc_angle(float x, float y){
        float r = sqrt(x*x + y*y);
        float angle = acos(x/r);
        return  y<0 ? -angle : angle;
    }
    
    int main(int argc, char *argv[])
    {
        std::vector<int> hits{0, 1, 2, 1, 0, 1, 2, 1, 0, 1};
        std::vector<float> x{-8, -8, -8, -8, -8,  -4, -4, -4, -4, -4};
        std::vector<float> y{-8, -4,  0,  4,  8,  -8, -4,  0,  4,  8};
    
        Q_ASSERT(x.size() == y.size() && y.size() == hits.size());
        std::vector<int> indexes(x.size());
        std::iota(indexes.begin(), indexes.end(), 0);
    
        std::sort(indexes.begin(), indexes.end(), [&](const int & i, const int & j) -> bool{
            return calc_angle(x[i], y[i]) < calc_angle(x[j], y[i]);
        });
        QVector<float> plot_x, plot_y;
        QVector<int> new_hits;
        for(const int & index : indexes){
            plot_x<<x[index];
            plot_y<<y[index];
            new_hits<<hits[index];
        }
    
        qDebug()<<indexes;
        qDebug()<< plot_x;
        qDebug()<<plot_y;
        qDebug()<<new_hits;
    
        return 0;//a.exec();
    }
    

    输出:

    std::vector(8, 0, 1, 2, 3, 4, 5, 6, 7, 9)
    QVector(-4, -8, -8, -8, -8, -8, -4, -4, -4, -4)
    QVector(4, -8, -4, 0, 4, 8, -8, -4, 0, 8)
    QVector(0, 0, 1, 2, 1, 0, 1, 2, 1, 1)
    

相关问题