问题
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