首页 新闻 会员 周边 捐助

编码实现:两点距离小50的取两个点的平均值作为一点。c++

0
悬赏园豆:40 [已解决问题] 解决于 2013-10-14 11:12
double dist = sqrt ( pow((x1-x2), 2) + pow((y1-y2), 2) );//两点距离公式
std::vector<cv::Point2f> corners;//所有坐标值得集合
问题补充:

首先谢谢高手的回答。比如:
vector<cv::Point2f> vec;
vec.push_back(cv::Point2f(0,0)); //1
vec.push_back(cv::Point2f(1,0)); //2
vec.push_back(cv::Point2f(0,0)); //3
vec.push_back(cv::Point2f(98,99)); //4
vec.push_back(cv::Point2f(100,100));//5
找出来任何两个点的距离小于50的点,然后取这个些点的中心坐标,比如上面所有点中1,2,3任意两个之间的距离小于50就取中间坐标为(0.33,0)。4,5小于50取中间坐标为(99,99.5)
最终我想得到的集合是两个点:(0.33,0) (99,99.5).

(0.0),(1.0),(0.0)三个点的中心坐标怎么求不用写了吧?

 

麻烦看下这个代码可以吗?

void erase(vector<cv::Point2f> &v)
{
    std::vector<cv::Point2f> result,filter,tempOut=v;
    for(int i=0;i<tempOut.size();i++)
    {
        for(int j=i+1;j<tempOut.size();j++)
        {
            cv::Point2f vo=tempOut[i],vi=tempOut[j];
            double x1=(vo).x,x2=(vi).x,y1=(vo).y,y2=(vi).y;
            double dist = sqrt ( pow((x1-x2), 2) + pow((y1-y2), 2) );
            if (dist <= 50)
            {
                filter.push_back(vi);
                tempOut.erase(tempOut.begin()+j);
                j--;
            }
        }
        //
        filter.push_back(tempOut[i]);
        int count=filter.size();
        double argX=0,avgY=0;
        for(int i=0;i<count;i++)
        {
            argX+=filter[i].x;
            avgY+=filter[i].y;
        }
        result.push_back(cv::Point2f(argX/count,avgY/count));
        filter.clear();
    }

 

亲福的主页 亲福 | 初学一级 | 园豆:40
提问于:2013-10-11 13:58
< >
分享
最佳答案
0

汗~,没看懂需求

收获园豆:30
空明流光 | 初学一级 |园豆:111 | 2013-10-11 16:59

哪里不清楚呢?

亲福 | 园豆:40 (初学一级) | 2013-10-11 17:08

@KissFu: 需求算是看懂了,很简单的一个需求,但对你说的这个结构std::vector<cv::Point2f>不熟悉,你上面的方法中循环可能存在问题,即i和j的循环次数我看好像不对吧? 如果求中间点,这样求(伪代码),写得也比较凌乱,看不懂就算了,我这里没有vc环境:

public class point

{

  public point(double x,double y)

  {

    X=x;Y=y;

  }

  double X,

  double Y

}

point[]={new point(0,0),new point(1,0),new point(0,0),...};

for(int i = 0 ;i<sizeof(point)/sizeof(point[0]);i++)

{

  for(int j = 0 ;j<sizeof(point)/sizeof(point[0]);j++)

  {

    //自己不能和自己比较

    if(i==j)

      continue;

    //两个坐标重复

    if(point[i].X==point[j].X && point[i].Y==point[j].Y))

    {

      //将此坐标加入一个新集合,正在遍历的集合是不能删除的。

      continue;

    }

    

    if((sqrt(pow((point[i].X-point[j].X), 2) + pow((point[i].Y-point[j].Y), 2) )<50)

    {

      int x= (point[i].X+point[j].X)/2;

      int y= (point[i].Y-point[j].Y)/2;

      point c = new point(x,y);

      //这是中间点坐标

    }

  }

}

foreach(int i =0;i<deleteList.count;i++)

{

  //从集合中删除刚才找到的集合

  pointList.remove(deleteList[i]);

}

空明流光 | 园豆:111 (初学一级) | 2013-10-14 09:17

@沧海一杰: 非常感谢您的回答。

主要还是要对c++标准库里面的向量std::vector<cv::Point2f>的理解。

第一:自己不能和自己比较、两个坐标重复这两个条件可以用另外一个嵌套循环解决的。

外层循环到i=0的时候,内层j=i+1=1然后接着循环。

第二:就是删除正在循环的集合的某个元素,vector删除某个元素的时候,当前索引会指向下一个值,size-1。我这里有点投机取巧,因为只是在内层删除,而且还是删除当前索引之后的元素,所以要考虑内层的索引指向的值,删除之后就j--就可以指向下一个值啦。

第三:求中间点坐标,要考虑如果是多个点求中间值!!比如,外层i=0,内层j=i+1=1,j=i+2=2,j=i+3=3。内层三个点和外层一个点都<50,然后删除内层三个点,外层一个点不删除,因为内层循环完后,四个点求中间点坐标,把中间点放入另外一个集合里面。外层继续循环。

 

我不知这样说您是否能理解?我这样是否存在隐患?再次表示感谢。

亲福 | 园豆:40 (初学一级) | 2013-10-14 11:07
其他回答(1)
0

好像很简单的样子,除了不熟这个集合是怎么构成的,C++不熟。
我猜集合不是矩阵就是数组形式,那就好办,循环取点坐标(去掉重复的),计算dist,判断<50,再产生新坐标

收获园豆:10
iEvent | 园豆:529 (小虾三级) | 2013-10-11 14:19

我c++也不是太熟悉,所以我想要个代码,遍历集合的期间,还有删减其中的重复。麻烦

支持(0) 反对(0) 亲福 | 园豆:40 (初学一级) | 2013-10-11 14:32

@KissFu: 

std::vector<std::vector<CvPoint>> ptAll;

 

     for(int jj = 0;jj<ptAll.size();jj++) 
     { 
      for(int ii =0;ii<ptAll[jj].size();ii++) 
      { 
        ptAll[jj][ii]....;
      }
     }
支持(0) 反对(0) iEvent | 园豆:529 (小虾三级) | 2013-10-11 15:28

@chous: std::vector<std::vector<CvPoint>>这个是集合套一个集合。我的事一个集合。std::vector<cv::Point2f> corners;

支持(0) 反对(0) 亲福 | 园豆:40 (初学一级) | 2013-10-11 16:06

@KissFu: corners[][]这样不能操作吗?

支持(0) 反对(0) iEvent | 园豆:529 (小虾三级) | 2013-10-12 08:03
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册