点云凸包

乘胜追击再写一个点云凸包怎么找的代码好了,毕竟下一次更新也不知道是什么时候,太懒了,太懒了,不适合搞学术

啥是凸包呢,在网上随便找了一个图哈,大概意思就是每个转角的地方都是凸出去的,这个代码师兄也跟我说很简单很简单,行吧,反正我是想了好久才想出来的,可能师兄的简单==和我的简单不是一个量级吧

//叉乘
double multi(CCVector3 p1,CCVector3 p2,CCVector3 p0) 
{
    return ((p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x));
}

//p1,p2的距离
double distance2(CCVector3 p1,CCVector3 p2) 
{
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}

//找到点集的凸包
int convex_hull(QVector<CCVector3> *input,QVector<CCVector3> *output) 
{  
    long npt=input->size();
    if (npt< 0) return 0;
    int i,j,k,top;  
    k=0; //找到最下且偏左的那个点  
    for(i=1;i<npt;i++)  
        if(input->at(i).y<input->at(k).y||(input->at(i).y==input->at(k).y&&(input->at(i).x<input->at(k).x)))  
            k=i;  
 
    CCVector3 tempts=input->data()[(0)];
    CCVector3 firstpts=input->data()[(k)];
    input->data()[(k)]=tempts;
    input->data()[(0)]=firstpts;

    //按极角从小到大,距离偏短进行排序  
    for(i=1;i<npt;i++)  
    {  
        k=i;  
        for(j=i+1;j<npt;j++)  
            if(multi(input->at(j),input->at(k),input->at(0))>0||(fabs(multi(input->at(j),input->at(k),input->at(0)))<=eps&&  
                (distance2(input->at(0),input->at(j))<distance2(input->at(0),input->at(k)))))  
            {
                k=j; //k保存极角最小的那个点,或者相同距离原点最近  
            }
        tempts=input->data()[(i)];
        input->data()[(i)]=input->data()[(k)];
        input->data()[(k)]=tempts; 
    }  
    //第三个点先入栈  
    double  *stack=new double[npt+1];
    stack[0]=0;  
    stack[1]=1;  
    stack[2]=2;  
    top=2; //判断与其余所有点的关系  
    for(i=3;i<npt;i++)  
    {  
        //不满足向左转角度大于45°的关系,栈顶元素出栈  
        while((multi(input->at(i),input->at(stack[top]),input->at(stack[top-1]))/(distance2(input->at(i),input->at(stack[top]))*distance2(input->at(stack[top]),input->at(stack[top-1])))>-0.1 ||fabs(multi(input->at(i),input->at(stack[top]),input->at(stack[top-1])))<=eps)) 
        {
                top--;
                if(top==0)
                    break;
        }
        //当前点与栈内所有点满足向左关系,因此入栈  
            top++;
            stack[top]=i;  
    } 

    /*//计算凸包的面积
    area = 0;  
    for (i = 1; i < top; i++)  
        area += fabs(multi(input->at(stack[0]), input->at(stack[i]), input->at(stack[i+1]))); */ 

    if(top==0)
        return 0;
    else
    {
        for(int i=0;i<top;i++)
        {
            CCVector3 pt_=input->at(stack[i]);
            output->push_back(pt_);
        }
        return top;
    }
    delete[]stack;
}  
 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值