0
\$\begingroup\$

I'm trying to determine what coordinates are in one space when given a point in another space.

For example, I've got a Matrix4x4 that I can use to convert a point in unity's world space to a skewed space defined by that matrix.

The inverse of this matrix returns me to the original world space.

private float HALF_SQRT_3 = Mathf.Sqrt(3) / 2;

private Matrix4x4 mWorldToSkewGrid = new Matrix4x4(
    new Vector4(HALF_SQRT_3, 0, 0, 0),
    new Vector4(0, 1, 0, 0),
    new Vector4(Mathf.Cos(Mathf.PI / 3) * HALF_SQRT_3, 0, Mathf.Sin(Mathf.PI / 3) * HALF_SQRT_3, 0),
    new Vector4(0, 0, 0, 1)
);

private Matrix4x4 mSkewGridToWorld = mWorldToSkewGrid.inverse;

I'm attempting to figure out how I can go about getting the coordinates of the skewed space AT the default world space rather than transforming a point in default space to the skewed space.

I assumed it was something similar to how unity converts a screen point into a world point. Something like this:

Vector4 p = mSkewGridToWorld * new Vector4(defaultWorldPos.x, defaultWorldPos.y, defaultWorldPos.z, 1.0f);
p.w = 1.0f / p.w;
p.x *= p.w;
p.y *= p.w;
p.z *= p.w;

Where p is intended to hold the position of defaultWorldPos but in the skewed coordinates where it would overlap in the skewed space.

Edit: Below is an example of the "default world space" in green being transformed into the "skewed space" in red, represented by a 10x10 grid. Rather than transforming say the grid cell 5x5 to the other space resulting in the point moving and being still at 5x5 in the skewed space, I want to know what skewed point is under 5x5, in this example it would be something like 2x6 in the skewed space. Example image showing the default world space in a green grid being transformed to the skewed space in a red grid.

\$\endgroup\$
1
  • \$\begingroup\$ Sounds like using the inverse of this matrix will be ok. \$\endgroup\$
    – Mangata
    Jan 17, 2023 at 6:23

2 Answers 2

0
\$\begingroup\$

Personally, I find that thinking in terms of "reference systems" makes this sort of reasoning a bit easier than thinking about transforming the space.

If you know the coordinates of the point in world space, and are trying to figure out what the coordinates of that same point would be from the grid's reference system, it's just

pointInGridSpace = worldtoGridMatrix * pointInWorldSpace.

\$\endgroup\$
0
\$\begingroup\$

Unity usually doesn't require you to work with transformation matrices yourself, because the Transform component abstracts them away for you. If you want to translate a point from the coordinate system relative to one component to another, you can use transform.TransformPoint(Vector3) with the transform of the first gameObject to transform a point from local space to world space, and then transform.InverseTransformPoint(Vector3) with the transform of the second gameObject to transform that point into the coordinate of the second object.

And by the way, if the whole reason why you want to do this is because you want to convert between screen pixels and world position, then you can do that with some useful utility methods of the Camera component rendering the scene. Like Camera.main.ScreenToWorldPoint(Vector3) and Camera.main.WorldToScreenPoint(Vector3). Or if you want to find out which collider the mouse cursor is currently pointing at: Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit);

\$\endgroup\$
1
  • \$\begingroup\$ Note that Transform.TransformPoint or InverseTransformPoint will not handle shear transforms as shown in the question — at least, not in one level. You'd need a scaled parent transform and a rotated child transform to combine to a shear, since an individual transform will only store axis-aligned scale, rotation, and translation. I talk about something similar in this answer. \$\endgroup\$
    – DMGregory
    Jan 17, 2023 at 14:53

You must log in to answer this question.

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