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\$
  • \$\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 Jan 14 '19 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\$ – somerandomusername Jan 15 '19 at 10:23
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\$
  • \$\begingroup\$ I'm a bit confused about what exactly is the direction \$\endgroup\$ – somerandomusername Jan 14 '19 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 Jan 14 '19 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\$ – somerandomusername Jan 14 '19 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 Jan 14 '19 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 Jan 14 '19 at 14:03

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.