so i'm wondering what the algorithm for finding a shapes center of mass if I have a set of vertices?
Also if it makes the algorithm shorter my complex polygons are saved as a set of simple convex polygons, and you can get their ve开发者_C百科rtices.
I found the above equation but i don't know how to translate it......
In light of new evidence, I firmly believe your given formula is wrong. Allow me to provide a different algorithm. I tried to make it look C++ish, but I'm sure I got some things wrong. If you'd like to nitpick about those, that's fine. If you'd like to downvote on them, I can't stop you, but I'd rather you edit them away to make the post better. :-)
// use doubles if appropriate
float xsum = 0.0;
float ysum = 0.0;
float area = 0.0;
for(int i = 0; i < points.size - 1; i++) {
// I'm not a c++ guy... do you need to use pointers? You make the call here
Point p0 = points[i];
Point p1 = points[i+1];
double areaSum = (p0.x * p1.y) - (p1.x * p0.y)
xsum += (p0.x + p1.x) * areaSum;
ysum += (p0.y + p1.y) * areaSum;
area += areaSum;
}
float centMassX = xsum / (area * 6);
float centMassY = ysum / (area * 6);
Try the algorithm given here. It will work for convex polygons.
Te general approach is to split figure into pieces for which the calculation is easier, calculate mass centers for them and combine them: C=sum(C[i]*mass[i])/sum(mass[i])
First of all you should define how mass is distributed in the polygon. Possible (simple) distributions:
- Concentrated in vertices (uniformly) - the formulae in your question is for this case
- Uniformly distributed on border of polygon - in this case you should calculate mass center of each line (it's just the middle of the line), multiply it by line length, add all of them and divide by entire border length
- Uniformly distributed on area of polygon - simplest for understanding way is to split it to triangles, calculate mass center for each of them, multiply by its area, add all of them, divide by entire area of the polygon
You can use a simple average function, roughly like this:
template <typename T, typename iterator> T avg(iterator const& begin, iterator const& end) {
T result;
size_t size(0);
for (iterator it = begin; it != end; ++it) {
result += *it;
size++;
}
return result/size;
}
Now, assuming your values are in a set, you could do:
std::set<double> xs; // assuming your values are in there
double x = avg<double,std::set<double>::iterator>(xs.begin(), xs.end());
Without having run it through g++, I'm not sure, which of the template parameters could be inferred automatically.
精彩评论