0
\$\begingroup\$

Here is a diagram of what I'm looking for:

example of the issue

I am trying to find the math solution to determine where that smaller circle is relative to the bigger circle's view.

I thought that the easiest way would be to get a vector between the small circle and the big circle and a second vector that is pointing out from the bigger circle's base to a little in front of its view (normalized of course), and then do a dot product to get the angle... but I have no idea how to get the small pointing out vector from the big circle's base to its view direction in front of it.

I'm not interested in using a Unity pre-implemented function to resolve this. What do I need to calculate this, or maybe you have a better idea for how to resolve this?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

The easiest way to do this would be:

Vector3 localPoint = bigCircle.transform.InverseTransformPoint(
                          smallCircle.transform.position
                     );

This local variable now holds the position of the small circle within the big circle's local coordinate system. That is, a coordinate system where (0, 0, 0) is the origin of the big circle, +z points to the big circle's "forward" direction (blue arrow of the local transformation gizmo), +x points to its right (red arrow), and +y points to the circle's up (green arrow).

If you then want to get a signed angle in the big circle's horizontal plane, that could look like:

float angleDegrees = Mathf.Atan2(localPoint.x, localPoint.z) * Mathf.Rad2Deg;

That will give you a bearing angle where 0 = directly ahead / "N", 90 = to the right / "E", 180 = exactly behind / "S".

Since you say you want to calculate this with math, not use a pre-built function, what InverseTransformPoint is doing is taking bigCircle.transform.localToWorldMatrix and inverting it to get worldToLocalMatrix, then multiplying the provided point by this matrix:

 Vector3 localPoint = bigCircle.trandform.worldToLocalMatrix 
                      * smallCircle.transform.position;

You can get a similar result without matrix math like so:

// Remove bigCircle's translation.
Vector3 worldOffset = smallCircle.transform.position - bigCircle.transform.position;

// Remove bigCircle's rotation.
Quaternion antiRotation = Quaternion.Inverse(bigCircle.transform.rotation);
Vector3 localOffsetScaled = antiRotation * worldOffset;

// Remove bigCircle's scale (if applicable).
Vector3 antiScale = bigCircle.transform.localScale;
antiScale = new Vector3(1f/antiScale.x, 1f/antiScale.y, 1f/antiScale.z);
Vector3 localOffsetUnscaled = Vector3.Scale(localOffsetScaled, antiScale);
\$\endgroup\$
1
  • \$\begingroup\$ Thank you that was very a very detailed answer \$\endgroup\$
    – Sawb
    Sep 22, 2022 at 7:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .