1
\$\begingroup\$

Imagine a (x,y,z) coordinate system within a solar system, with (0,0,0) beeing the center of sun where Z axis goes thru both solar poles.

I'm standing on a planet inside a house within that solar system.

Now from my perspective Z axis is skewed in unknown direction depending on where exactly the planet is at this moment.

What would be the steps I should take to create a local coordinate system with (0,0,0) being the house and where Z axis is perpendicular to the ground/house, so that I would be able to convert coordinates from local to global.

I have the global coordinate of my house and directional vectors for where is up/forward/right for my house.

I have some limited knowledge of vector math and projecting vectors on other surfaces, but there is a gap in my understanding that keeps me from solving this.

local housePos = vec(getHouseWorldPosition())        -- (x,y,z) position of house in global cooridnates (housePos.x,housePos.y,housePos.z)

local vRight = vec(getHouseWorldOrientationRight())  -- X directional normalized vector
local vForw = vec(getHouseWorldOrientationForward()) -- Y directional normalized vector
local vUp = vec(getHouseWorldOrientationUp())        -- Z directional normalized vector

local playerPos = vec(getPlayerWorldPosition())      -- players position in global coordinates

--Now how to get players position in coordinate system relative to housePos, with Z axis going along vUp vector
\$\endgroup\$
2
  • \$\begingroup\$ Sounds like you would be served better using Matrices to represent the location, rotation, scale of your various co-ordinate systems. In that, you have a global matrix for your solar system, a planet matrix for the location, orientation etc, and a local for your house. You then can work in local co-ordinates for the house Z being up i assume.When want to work out the actual Z in the solar system, you combine your solar * planet * house. This means in future, if you want to rotate your solar system, you maintain you calculate your Z in any situation. Vectors probably not the best method. \$\endgroup\$
    – ErnieDingo
    Commented Jan 14, 2019 at 20:53
  • \$\begingroup\$ I'm trying to learn Lua and 3d by creating a small mod for a game. This is the data that is available to me from the game engine \$\endgroup\$ Commented Jan 15, 2019 at 10:23

1 Answer 1

3
\$\begingroup\$

Construct a matrix like so, where each vector is one column of the matrix:

[ House's X+ direction | House's Y+ direction | House's Z+ direction | House's position]

The fourth row should be [0, 0, 0, 1]

Since you're in Unreal with its right-handed coordinate system

  • x -> right
  • y -> back
  • z -> up

we can write this as:

$$M = \begin{bmatrix} houseRight.x & -houseForward.x & houseUp.x & housePosition.x\\ houseRight.y & -houseForward.y & houseUp.y & housePosition.y\\ houseRight.z & -houseForward.z & houseUp.z & housePosition.z\\ 0 & 0 & 0 & 1 \end{bmatrix}$$

Multiplying a vector \$v\$ like this:

$$v = \begin{bmatrix}v.x\\v.y\\v.z\\1\end{bmatrix}$$

by this matrix gives us...

$$M v = \begin{bmatrix} houseRight \cdot v.xyz &+& housePosition.x \\ -houseForward \cdot v.xyz &+& housePosition.y \\ houseUp \cdot v.xyz &+& housePosition.z \\ &1& \end{bmatrix}^T$$

...which takes a coordinate v.xyz from house-local coordinates to global coordinates. You can verify that...

  • When v = [0, 0, 0, 1] (the origin), this matrix maps it to the center of the house - the v.w = 1 coordinate gets multiplied by the house position column in the matrix, and the rest get zero'd-out

  • As we increase v.x, the result v' moves along the house's X+ (right) direction, and so on for the Y (back) & Z (up)

To convert back from world coordinates to house-local coordinates, take the inverse of this matrix.

\$\endgroup\$
8
  • \$\begingroup\$ I'm a bit confused about what exactly is the direction \$\endgroup\$ Commented Jan 14, 2019 at 13:19
  • 2
    \$\begingroup\$ "I have the global coordinate of my house and directional vectors for where is up/forward/right for my house" They're those three direction vectors you described. They form what's called a basis. \$\endgroup\$
    – DMGregory
    Commented Jan 14, 2019 at 13:23
  • \$\begingroup\$ hmm, but those are normalised vectors of direction. I should pick the Z axis direction vector and add it to house position vector ? \$\endgroup\$ Commented Jan 14, 2019 at 13:27
  • 2
    \$\begingroup\$ No. You need exactly those three normalized direction vectors to make the first three columns of the matrix. That top-left 3x3 block describes how space has been rotated / stretched / sheared, so using an orthonormal basis ensures you get the desired rotation with no stretch or shear. \$\endgroup\$
    – DMGregory
    Commented Jan 14, 2019 at 13:33
  • 2
    \$\begingroup\$ No. The first column is one direction vector, pointing along house's positive x axis (denoted X+). The second column is another direction vector, pointing along house's positive y axis (denoted Y+). The third column is the last direction vector, pointing along house's positive z axis (denoted Z+). The final column is the house's position in the world, with a 1 in the fourth row. Which one of X+/Y+/Z+ corresponds to "forward/right/up" depends on the conventions you've used for labelling your coordinate axes, so I've stuck with X/Y/Z labels since I don't know your conventions. \$\endgroup\$
    – DMGregory
    Commented Jan 14, 2019 at 14:03

You must log in to answer this question.

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