0
\$\begingroup\$

I am creating a game in Unity with 2D. When a button is clicked a static object is attaching a hinge joint to a dynamic object, so the dynamic object orbits it. When the dynamic object gets attached, I am setting the dynamics objects transform.up vector to be pointing at the static object. Then, taking what ever the dynamic objects magnitude was and setting that as its velocity to the right. I do this because I want the dynamic object to orbit the planet at the same exact speed as when it wasn't orbiting.

The problem I am having, is I don't know how to determine if the object should orbit clockwise or counter-clockwise. It's easy for me to determine this when I look at an image, but I don't know how to via code.

Here is an example enter image description here

Does anyone know how I can determine this?

\$\endgroup\$
  • \$\begingroup\$ Off-hand guess: compare the angle made by the arrow in your image (is that the original velocity vector?) with the line between the two object's centers. That angle will either have a positive value or a negative value, which will be your CW or CCW. \$\endgroup\$ – Draco18s Jan 26 at 1:57
1
\$\begingroup\$

Welcome to the joy of the cross product!

The cross product of two 3D vectors gives a third vector that's perpendicular to both the inputs:

Vector3 c = Vector3.Cross(a, b);

In a left-handed coordinate system like Unity's, you can make a thumbs-up pose with your left hand, and hold it so that the flat of your hand points in the direction a and your fingers curl toward b. The cross product of the two points in the direction of your thumb.

That means if a and b are in the 2D plane xy, the cross product points along the z axis: with z component greater than zero if b is clockwise of a, and less than zero if b is counter-clockwise of a.

So, specifically:

float OrbitDirection(Rigidbody2D orbiter, Transform center) {
    Vector3 toCenter = center.position - orbiter.position;
    return Mathf.Sign(Vector3.Cross(orbiter.velocity, toCenter).z);
    // This is equivalent to:
    // return Mathf.Sign(orbiter.velocity.x * toCenter.y - orbiter.velocity.y * toCenter.x);
}

This returns +1.0f if the object should orbit counter-clockwise (positive rotation about the z axis), and -1.0f if the object should orbit clockwise (negative rotation about the z axis).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.