# math + velocity = help me please

## Recommended Posts

need help with some math if anyone is good at it. The solution is probably simple, but I'm not good at it.

-- need to check rotX and rotY to see if the vehicle is upside down to get the correct velocity to move the vehicle front, rear, left, right..

-- when the vehicle is upside down /tilted, the wrong velocities are returned

```function getVelocityRelativeToVehicle(vehicle, direction, increaseFactor)
local velocityX,velocityY,velocityZ = getElementVelocity(vehicle)
local rotX,rotY,rotZ = getVehicleRotation(vehicle)

if direction == "front" then
rotZ = rotZ
elseif direction == "rear" then
rotZ = rotZ + 180
elseif direction == "left" then
rotZ = rotZ + 90
elseif direction == "right" then
rotZ = rotZ - 90
else
outputDebugString("unknown direction: " .. tostring(direction))
end

-- need to check rotX and rotY to see if the vehicle is upside down to get the correct velocity to move the vehicle front, rear, left, right..
-- when the vehicle is upside down /tilted, the wrong velocities are returned

velocityX = (math.sin(rotZ) * -increaseFactor) + velocityX
velocityY = (math.cos(rotZ) * increaseFactor) + velocityY
return velocityX, velocityY, velocityZ
end
```

Just to clarify the purpose of the script, if I am right:

He wants a script that would push the vehicle in a given direction (front, back, left, or right) relative to the vehicle's current rotation.

correct, and it works if the vehicle is right side up, using only on the z rotation. But x and y rotations need to be taken into account and I'm not sure of the math to do so.

Here's a rough idea of how this might work. Maybe I can come up with the code later.

First, take the rotation vector of the vehicle (that you get from getVehicleRotation()) and transform it into the Cartesian frame, such that the vector corresponds to <1,0,0>. Then figure out the desired rotation (<0,1,0> for left, <0,-1,0> for right, <1,0,0> for front, <-1,0,0> for back), and transform this back into the original frame. You now have a new direction vector for the vehicle. Take this vector, multiply it by some scalar to get the magnitude (which corresponds to how greatly you want to push the vehicle), add it to the vehicle's current velocity vector, and apply it to the vehicle using setElementVelocity().

There might also be a much simpler way, as this way involves converting between frames (defining a local frame for the direction vector, converting it to the Cartesian frame, applying the desired rotation, and converting back), but I am just writing this so I don't forget.

EDIT: Here is a simpler way:

The first step is to get the vehicle's direction vector from it's rotation .

For "front", our new vector is the same as the vehicle's direction. For "rear" it's the opposite: <-dirX, -dirY, -dirZ>.

For "left" it's a bit more difficult (and "right" is just the opposite of left):

1. Get the vehicle's heading vector from the direction vector (or could use just direction vector).

2. Get the vehicle's roof vector, which is the direction it's roof is facing (e.g. facing the sky when the car is on a flat road).

3. Take the cross product of the vehicle's roof vector and direction vector to get the left direction.

The problem is I'm not sure how to get the roof vector. I'll think about some more when I have time.

Sorry, maybe I misread the question, but I think you was asking for this:

```M = getElementMatrix( vehicle )
rotZ = math.deg( math.atan2( M[1][2], M[1][1] ) )
```

If I'm correct, being upside-down makes getVehicleRotation() return Z coordinate swapped 180 deg. In this case to get the heading, I'm using getElementMatrix(), and it works just great regardless of vehicle orientation.

UPD: Indeed, I misunderstood. Have a look at code below, handled by timer, this will push your vehicle in a direction you need:

```local velx, vely, velz = getElementVelocity ( vehicle )
local X, Y, Z = 0, 0.1, 0 --try out setting different values here
setElementVelocity( vehicle,	velx + X * M[1][1] + Y * M[2][1] + Z * M[3][1], vely + X * M[1][2] + Y * M[2][2] + Z * M[3][2], velz + X * M[1][3] + Y * M[2][3] + Z * M[3][3] )
```

, where X is relative to "left-right" movement, Y for "forward-backward" and Z for "up-down".

thank you it works! I've had this script for ages that only half worked. I actually have a few other scripts that i have similar problems with hopefully i can figure it out based on this.

I really appreciate both of your efforts and time.

```function setVelocityRelativeToVehicle(vehicle, direction, increaseFactor)
local M = getElementMatrix( vehicle )
local velx,vely,velz = getElementVelocity(vehicle)
local X,Y,Z = 0,0,0

if direction == "front" then
Y = increaseFactor
elseif direction == "rear" then
Y = -increaseFactor
elseif direction == "left" then
X = -increaseFactor
elseif direction == "right" then
X = increaseFactor
else
outputDebugString("unknown direction: " .. tostring(direction))
end

setElementVelocity( vehicle,   velx + X * M[1][1] + Y *  M[2][1] + Z * M[3][1], vely + X * M[1][2] + Y * M[2][2] + Z * M[3][2], velz + X * M[1][3] + Y * M[2][3] + Z * M[3][3] )
end
```

## Create an account

Register a new account