- Home /
how polygon collider 2d calculates center of mass?
i'm trying to make 2D characters with 2D rigidbodies and having hard time with defining real center of mass of all body parts.
I dont use polygon colliders but i know if you use them, they set automatically the center of mass on the correct spot of the sprite. i assume center of mass is calculated with the values of points (vertex) of polygon collider.
Can anyone give me some tips about how can i calculate and assign center of mass of the sprites without using polygon collider?
Answer by enestezi · Dec 15, 2016 at 10:10 AM
okay, i discover that there is something called Sprite.vertices . It came with Unity5 and theoretically i should be able to calculate the "real" center of mass of the sprites with that array.
I think i have to add the vertices together and divide them with the total amount of vertices.
when im done, i will post the code.
This won't give you the correct center of mass. There are many different "centres" in geometry but none of them resembles the center of mass, at least not for arbitrary polygons. If you have many points close together (due to an arc for example) and just a few far away, using the arithmetic mean between all points will give you a point much closer to those "point clouds".
Calculating the proper center of mass is quite complicated. $$anonymous$$athematically it's the double integral of all points inside your covered area. The usual approach is to split down the area into primitives (usually triangles), calculate the center of mass for each triangle and do a weighted sum of those. For strictly convex polygons you can use this forumla
Why do you actually need to compute this manually? Why not simply adding a polygon colllider as well as Rigidbody2D and use it's centerOf$$anonymous$$ass?
I'm trying to make a program in Unity for playing around with shadow play puppets (mostly "$$anonymous$$aragöz"). The characters i want to use made out of jointed limbs. There is a hole on their upperbody which allows to use sticks to move them (kinda drag them around) behind curtain and rotate the bodies with twisting the sticks: Example
I build the 2D characters with HingeJoints to simulate how they actually move. I drag them with mouse. As you expect, the joints have to swing little bit back and fort as i drag. This swinging movement is not realistic enough as long the Center of $$anonymous$$ass relatively correct. I dont use polygon collider because this shadow puppets doesnt realy collide with each other. The artist drag them together without a real collision : Example
I use little colliders at the hand or hat to use them to grab something or lift the hat. I use for the stick holes circle colliders too, because, you know, they have to collide.
Rigidbody2D assigns pivot of sprite as center of mass (if you dont use collider calculation version). Pivot is as default at the center of the sprite, which is center of the rectangle which contains this particular limb. For a leg for example, i can guess and put pivot in sprite editor somewhere on the middle of the leg, but i want to make it programmatically and if possible correct.
you said "split down the area into primitives (usually triangles)". does it mean i can maybe use Sprite.triangles?
Answer by enestezi · Dec 18, 2016 at 03:40 PM
okay, here is my workaround:
public class CoM : MonoBehaviour {
public Rigidbody2D rb;
public PolygonCollider2D pc;
public Vector2 com;
public Vector2 p_com;
void Awake ()
{
rb = gameObject.GetComponent<Rigidbody2D> ();
com = rb.centerOfMass;
pc = gameObject.AddComponent<PolygonCollider2D> ();
pc =gameObject.GetComponent<PolygonCollider2D>();
p_com = rb.centerOfMass;
Destroy (pc);
rb.centerOfMass = p_com;
}
void Update ()
{
Debug.Log ("before: " + com);
Debug.Log ("with pc: " + p_com);
Debug.Log ("after: " + rb.centerOfMass);
}
}