如何使用向量计算点之间的距离

时间:2014-08-07 17:06:03

标签: c++ vector distance

我正在尝试计算坐标之间的距离。 我正在检测相机/视频的运动(用于网球跟踪/ OpenCV库)并保存所有候选人的坐标 所以这意味着球的运动以及球员或者任何可能产生的噪音。

我将坐标存储在点的矢量中,并将它们写入excel文件。 所以现在我的excel文件包含1列=帧数,2列=该帧上的候选数量,之后是所有x和y坐标。

问题:我想要做的是计算每个点与下一帧中所有点的距离。 假设我的坐标的excel看起来像那样:

frame nr    candidates      X   Y   X   Y   X   Y   X   Y
       1            3       x1  y1  x2  y2  x3  y3      

       2            4       x5  y5  x6  y6  x7  y7  x8  y8  

       3            1       x9  y9

       4            2       x10 y10 x11 y12

现在我想计算所有距离,所以x1,y1和x5,y5距离,x1,y1和x6,y6。 x1,y1和x7,y7。 x1,y1和x8,y8然后是x2,y2和x5,y5等等。因此,如果我在第一帧中有3个候选者而在第二帧中有4个候选者,那么我需要获得12个距离。 那么第二和第三的相同:x5,y5和x9,y9然后是x6,y6和x9,y9 ...... 第3和第4等等...... d = sqrt((x2-x1)^ 2 +(y2-y1)^ 2)是我想要使用的公式。 我怎么能这样做? 我知道如果我只有2分,我怎么能这样做,发现一个示例代码见下文,但是当我有很多坐标时我怎么能完成呢?

#include <stdio.h>
#include <iostream>
#include <vector>

using std::cout;
using std::cin;

//2 dimensional vector struct
struct points
{
    float x, y;
};

int main()
{
int Dimensions = 0;
float r;
std::vector<points> pointvect; // vector declaration

cout << "Set dimension of vector";
cin >> Dimensions; //with struct only 2D accepted
for (int i = 0; i<Dimensions; i++)
{ // Input coordinates x, ye
    pointvect.resize(pointvect.size() + 1); //This will make pointvect be able to hold 1 more point at the end
    cout << "Input x:";
    cin >> pointvect[i].x; //assign values
    cout << "Input y:";
    cin >> pointvect[i].y;
}

for (int i = 0; i<pointvect.size() - 1; i++)
{
    cout << "Distance between " << pointvect[i].x << "," << pointvect[i].y << " and " << pointvect[i + 1].x << "," << pointvect[i + 1].y << std::endl;
    //Pythagorean Theorem (also used to calculate distance can be found by taking sqrt (  (y2 - y1)^2  + (x2-x1)^2 )
    float Distance = sqrt(pow((pointvect[i].y - pointvect[i + 1].y), 2) + pow((pointvect[i].x - pointvect[i + 1].x), 2));
    cout << "Distance:" << Distance << std::endl;
}

system("pause");
return 0;
}

所以我希望我的问题是可以理解的。提前谢谢!

2 个答案:

答案 0 :(得分:3)

如果您重新排列数据以便为每个帧创建单独的向量,那么您可以使事情变得更容易。现在,您将所有数据重新组合成一个向量。

更好的是,std::map<int, std::vector<points>>似乎更合适。然后,您可以将帧编号与点向量相关联,使事情变得更加容易。

#include <map>
#include <vector>
#include <cmath>
#include <iostream>

struct points 
{ 
    float x, y; 
    points(float px=0, float py=0) : x(px), y(py) {}
};

typedef std::vector<points> PointVector;
typedef std::map<int, PointVector> MapPointVector;

float CalculateDistance(const points& p1, const points& p2)
{
    float diffY = p1.y - p2.y;
    float diffX = p1.x - p2.x;
    return sqrt((diffY * diffY) + (diffX * diffX));
}

void DisplayDistances(const MapPointVector& mp, int v1, int v2)
{
    MapPointVector::const_iterator it1 = mp.find(v1);
    MapPointVector::const_iterator it2 = mp.find(v2);
    if (it1 != mp.end() && it2 != mp.end())
    {
        const PointVector& vec1 = it1->second;
        const PointVector& vec2 = it2->second;
        for (size_t i = 0; i < vec1.size(); ++i)
        {
            for (size_t j = 0; j < vec2.size(); ++j)
                std::cout << CalculateDistance(vec1[i], vec2[j]) << "\n";
        }
    }
}

int main()
{
    MapPointVector mp;
    PointVector v1;
    PointVector v2;
    // assume v1 and v2 have been filled with info
    v1.push_back(points(1, 2));
    v1.push_back(points(10, 20));
    v1.push_back(points(5, 10));
    v1.push_back(points(0, 0));

    v2.push_back(points(11, 21));
    v2.push_back(points(13, 20));
    v2.push_back(points(5, 8));
    v2.push_back(points(1, 1));

    // associate them with frame 1 and frame 2
    mp[1] = v1;
    mp[2] = v2;
    DisplayDistances(mp, 1, 2); // display the distances for frame 1 and frame 2. 
}

此示例不仅显示嵌套循环,还显示std::map用于将帧编号与样本数据集相关联的用法。 DisplayDistances函数获取我们想要获取距离的帧并显示它们。

答案 1 :(得分:1)

我将候选人存储在积分矢量中。您可以使用嵌套for循环

double dist(Point p, Point q) {
    return std::sqrt((p.x-q.x)*(p.x-q.x) +
                    (p.y-q.y)*(p.y-q.y));
}

...

std::vector<double> distances;
for(int a=0; a<frame1.size(); a++) {
    for(int b=0; b<frame2.size(); b++) {
        distances.push_back( dist(frame1.at(a), frame2.at(b)) );
    }
}