fast dirty approximation of center of (list of 3D vertex) that forms a very shallow convex hull

寵の児 提交于 2020-01-04 14:16:40

问题


I want to find XY of the center (red) of a convex-hull points (orange circles) set that is a result from collision detection.

Using separating-axis technique, I know for sure that the convex shape (pink) is relatively thin in Z-axis.

In >90% of my use cases, the amount of vertices is not more than 8.

My poor algorithm (AABB) ... MCVE

I tried to implement it by calculating the center point of AABB.
However, when I use it in real Physics simulation, the collision point (red) is not accurate enough for box-stack stability.

Here is the test case (the vertices are extruded in +y and -y to create volume) :-

int main(){
    std::vector<Vec3> hullPoints;
    hullPoints.push_back(Vec3(-0.5,-0.5,-0.1));
    hullPoints.push_back(Vec3(-0.5,-0.5,0.1));
    hullPoints.push_back(Vec3(-0.5,0.5,-0.1));
    hullPoints.push_back(Vec3(-0.5,0.5,0.1));
    hullPoints.push_back(Vec3(0.5,-0.5,-0.2));
    hullPoints.push_back(Vec3(0.5,-0.5,0.2));
    hullPoints.push_back(Vec3(0.5,0.5,-0.2));
    hullPoints.push_back(Vec3(0.5,0.5,0.2));
    //^^^^ INPUT
    Vec3 centerOfHull;// approximate
    Vec3 centerMax=Vec3(-100000,-100000,-100000);
    Vec3 centerMin=Vec3(100000,100000,100000);
    for(unsigned int n=0;n<hullPoints.size();n++){
        Vec3 hullPoint=hullPoints[n];
        for(unsigned int m3=0;m3<3;m3++){
            centerMax[m3]=std::max( centerMax[m3],hullPoint[m3]);
            centerMin[m3]=std::min( centerMin[m3],hullPoint[m3]);
        }
    }
    centerOfHull=centerMax*0.5 + centerMin*0.5;
    std::cout<<"centerOfHull="<< centerOfHull.toString()<<std::endl;
    //it prints (0,0,0)
}

I wish it to return something like Vec3(a value between 0.05 and 0.45, 0, don't care).

References

I want a very fast algorithm that doesn't have to be very accurate.
There are some algorithm in the internet e.g.

  • Skeleton (so unrelated) : Better "centerpoint" than centroid
  • Just average all hull points. Its accuracy is too bad. (e.g. result of my example = Vec3(0,0,0))
    It is even worse for unevenly-distributed vertices e.g.
  • Generate the whole convex hull (and all faces). It is too slow for unnecessary high precision.

Answers doesn't need to contain any C++ code.
Just a rough suggestion can be very useful.


Appendix (Vec3 library)

It is provided only for MCVE completeness.

#include <vector>
#include <iostream>
#include <string>
struct Vec3{ 
    //modify from https://www.flipcode.com/archives/Faster_Vector_Math_Using_Templates.shtml
    float x, y, z;
    inline Vec3( void ) {}
    inline Vec3( const float x, const float y, const float z )
    { this->x = x; this->y = y; this->z = z; }

    inline Vec3 operator + ( const Vec3& A ) const  { 
        return Vec3( x + A.x, y + A.y, z + A.z );
    }
    inline Vec3 operator *( const float& A ) const   {
        return Vec3( x*A, y*A,z*A); 
    }
    inline float Dot( const Vec3& A ) const    { 
        return A.x*x + A.y*y + A.z*z; 
    }

    inline float& operator[]( int arr)  {
        switch(arr){
            case 0: return x;
            case 1: return y;
            case 2: return z;
        }
        std::cout<<"error"<<std::endl;
        return x;
    }
    std::string toString( ) const    { 
        return "("+std::to_string(x)+","+std::to_string(y)+","+std::to_string(z)+")";
    }
};

来源:https://stackoverflow.com/questions/58424042/fast-dirty-approximation-of-center-of-list-of-3d-vertex-that-forms-a-very-shal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!