Directions¶
Direction objects represent a rotation starting from an initial point in KSP’s coordinate system where the initial state was looking down the \(+z\) axis, with the camera “up” being the \(+y\) axis. This exists primarily to enable automated steering.
In your thinking, you can largely think of Directions as being Rotations and Rotations as being Directions. The two concepts can be used interchangeably. Used on its own to steer by, a rotation from the default XYZ axes of the universe into a new rotation does in fact provide an absolute direction, thus the name Direction for these objects even though in reality they are just Rotations. It’s important to know that Directions are just rotations because you can use them to modify other directions or vectors.
Note
When dealing with Directions (which are Rotations) in kOS, it is important to remember that KSP uses a left-handed coordinate system. This affects the convention of which rotation direction is positive when calculating angles.
Creation¶
Method |
Description |
|---|---|
Euler rotation |
|
Quaternion |
|
Compass heading |
|
Looking along vector lookAt, rolled so that lookUp is upward. |
|
A rotation that would rotate the universe around an axis |
|
A rotation that would go from vectors fromVec to toVec |
|
From SHIP or TARGET |
|
From SHIP |
|
From SHIP, TARGET or BODY |
- R(pitch,yaw,roll)¶
A
Directioncan be created out of a Euler Rotation, indicated with theR()function, as shown below where thepitch,yawandrollvalues are in degrees:SET myDir TO R( a, b, c ).
- Q(x,y,z,rot)¶
A
Directioncan also be created out of a Quaternion tuple, indicated with theQ()function, passing it the x, y, z, w values of the Quaternion. The concept of a Quaternion uses complex numbers and is beyond the scope of the kOS documentation, which is meant to be simple to understand. It is best to not use the Q() function unless Quaternions are something you already understand.SET myDir TO Q( x, y, z, w ).
- HEADING(dir,pitch,roll)¶
A
Directioncan be created out of aHEADING()function. The first parameter is the compass heading, and the second parameter is the pitch above the horizon:SET myDir TO HEADING(degreesFromNorth, pitchAboveHorizon).
The third parameter, roll, is optional. Roll indicates rotation about the longitudinal axis.
- LOOKDIRUP(lookAt,lookUp)¶
A
Directioncan be created with the LOOKDIRUP function by using two vectors. This is like converting a vector to a direction directly, except that it also provides roll information, which a single vector lacks. lookAt is a vector describing the Direction’s FORE orientation (its local Z axis), and lookUp is a vector describing the direction’s TOP orientation (its local Y axis). Note that lookAt and lookUp need not actually be perpendicualr to each other - they just need to be non-parallel in some way. When they are not perpendicular, then a vector resulting from projecting lookUp into the plane that is normal to lookAt will be used as the effective lookUp instead:// Aim up the SOI's north axis (V(0,1,0)), rolling the roof to point to the sun. LOCK STEERING TO LOOKDIRUP( V(0,1,0), SUN:POSITION ). // // A direction that aims normal to orbit, with the roof pointed down toward the planet: LOCK normVec to VCRS(SHIP:BODY:POSITION,SHIP:VELOCITY:ORBIT). // Cross-product these for a normal vector LOCK STEERING TO LOOKDIRUP( normVec, SHIP:BODY:POSITION).
- ANGLEAXIS(degrees,axisVector)¶
A
Directioncan be created with the ANGLEAXIS function. It represents a rotation of degrees around an axis of axisVector. To know which way a positive or negative number of degrees rotates, remember this is a left-handed coordinate system:// Pick a new rotation that is pitched 30 degrees from the current one, taking into account // the ship's current orientation to decide which direction is the 'pitch' rotation: // SET pitchUp30 to ANGLEAXIS(-30,SHIP:STARFACING). SET newDir to pitchUp30*SHIP:FACING. LOCK STEERING TO newDir.
Note
The fact that KSP is using a left-handed coordinate system is important to keep in mind when visualizing the meaning of an ANGLEAXIS function call. It affects which direction is positive when calculating angles.
- ROTATEFROMTO(fromVec,toVec)¶
A
Directioncan be created with theROTATEFROMTOfunction. It is one of the infinite number of rotations that could rotate vector fromVec to become vector toVec (or at least pointing in the same direction as toVec, since fromVec and toVec need not be the same magnitude). Note the use of the phrase “infinite number of”. Because there’s no guarantee about the roll information, there are an infinite number of rotations that could qualify as getting you from one vector to another, because there’s an infinite number of roll angles that could result and all still fit the requirement:SET myDir to ROTATEFROMTO( v1, v2 ).
- Suffix terms from other structures
A
Directioncan be made from many suffix terms of other structures, as shown below:SET myDir TO SHIP:FACING. SET myDir TO TARGET:FACING. SET myDir TO SHIP:UP.
Whenever a Direction is printed, it always comes out showing its Euler Rotation, regardless of how it was created:
// Initializes a direction to prograde
// plus a relative pitch of 90
SET X TO SHIP:PROGRADE + R(90,0,0).
// Steer the vessel in the direction
// suggested by direction X.
LOCK STEERING TO X.
// Create a rotation facing northeast,
// 10 degrees above horizon
SET Y TO HEADING(45, 10).
// Steer the vessel in the direction
// suggested by direction X.
LOCK STEERING TO Y.
// Set by a rotation in degrees
SET Direction TO R(0,90,0).
Structure¶
- structure Direction¶
The suffixes of a
Directioncannot be altered, so to get a newDirectionyou must construct a new one.Suffix
Type
Description
Scalar(deg)Rotation around \(x\) axis
Scalar(deg)Rotation around \(y\) axis
Scalar(deg)Rotation around \(z\) axis
This Direction’s forward vector (z axis after rotation).
VECTORAlias synonym for
FOREVECTORThis Direction’s top vector (y axis after rotation).
UPVECTORAlias synonym for
TOPVECTORThis Direction’s starboard vector (z axis after rotation).
RIGHTVECTORAlias synonym for
STARVECTORThe inverse of this direction.
-(unary minus)Using the negation operator
-on a Direction does the same thing as using the :INVERSE suffix on it.The
Directionobject exists primarily to enable automated steering. You can initialize aDirectionusing aVectoror aRotation.Directionobjects represent a rotation starting from an initial point in KSP’s coordinate system where the initial state was looking down the \(+z\) axis, with the camera “up” being the \(+y\) axis. So for example, aDirectionpointing along the \(x\) axis might be represented asR(0,90,0), meaning the initial \(z\)-axis direction was rotated 90 degrees around the \(y\) axis.If you are going to manipulate directions a lot, it’s important to note that the order in which the rotations occur is:
First rotate around \(z\) axis.
Then rotate around \(x\) axis.
Then rotate around \(y\) axis.
What this means is that if you try to
ROLLandYAWin the same tuple, like so:R(0,45,45), you’ll end up rolling first and then yawing, which might not be what you expected. There is little that can be done to change this as it’s the native way things are represented in the underlying Unity engine.Also, if you are going to manipulate directions a lot, it’s important to note how KSP’s native coordinate system works.
- Direction:FOREVECTOR¶
- Type
- Access
Get only
Vectorof length 1 that is in the same direction as the “look-at” of this Direction. Note that it is the same meaning as “what the Z axis of the universe would be rotated to if this rotation was applied to the basis axes of the universe”. When you LOCK STEERING to a direction, that direction’s FOREVECTOR is the vector the nose of the ship will orient to. SHIP:FACING:FOREVECTOR is the way the ship’s nose is aimed right now.
- Direction:TOPVECTOR¶
- Type
- Access
Get only
Vectorof length 1 that is in the same direction as the “look-up” of this Direction. Note that it is the same meaning as “what the Y axis of the universe would be rotated to if this rotation was applied to the basis axes of the universe”. When you LOCK STEERING to a direction, that direction’s TOPVECTOR is the vector the roof of the ship will orient to. SHIP:FACING:TOPVECTOR is the way the ship’s roof is aimed right now.
- Direction:STARVECTOR¶
- Type
- Access
Get only
Vectorof length 1 that is in the same direction as the “starboard side” of this Direction. Note that it is the same meaning as “what the X axis of the universe would be rotated to if this rotation was applied to the basis axes of the universe”. When you LOCK STEERING to a direction, that direction’s STARVECTOR is the vector the right wing of the ship will orient to. SHIP:FACING:STARVECTOR is the way the ship’s right wing is aimed right now.
Operations and Methods¶
You can use math operations on Direction objects as well. The next example uses a rotation of “UP” which is a system variable describing a vector directly away from the celestial body you are under the influence of:
Supported Direction Operators:
- Direction Multiplied by Direction:
Dir1 * Dir2- This operator returns the result of rotating Dir2 by the rotation of Dir1. Note that the order of operations matters here.Dir1*Dir2is not the same asDir2*Dir1. Example:// A direction pointing along compass heading 330, // by rotating NORTH by 30 degrees around UP axis: SET newDir TO ANGLEAXIS(30,SHIP:UP) * NORTH.
- Direction Multiplied by Vector:
Dir * Vec- This operator returns the result of rotating the vector by Dir:// What would the velocity of your ship be // if it was angled 20 degrees to your left? SET Vel to ANGLEAXIS(-20,SHIP:TOPVECTOR) * SHIP:VELOCITY:ORBIT. // At this point Vel:MAG and SHIP:VELOCITY:MAG should be the same, // but they don't point the same way
- Direction Added to Direction:
Dir1 + Dir2- This operator is less reliable because its exact behavior depends on the order of operations of the UnityEngine’s X Y and Z axis rotations, and it can result in gimbal lock.It’s supposed to perform a Euler rotation of one direction by another, but it’s preferred to use
Dir*Dirinstead, as that doesn’t experience gimbal lock, and does not require that you know the exact transformation order of Unity.
For vector operations, you may use the :VECTOR suffix in combination with the regular vector methods:
SET dir TO SHIP:UP.
SET newdir TO VCRS(SHIP:PROGRADE:VECTOR, dir:VECTOR)
The Difference Between Vectors and Directions¶
There are some consequences when converting from a Direction to a Vector and vice versa which should not be overlooked.
A
Vectorand aDirectioncan be represented with the exact same amount of information: a tuple of 3 floating point numbers. So you might wonder why it is that aVectorcan hold information about the magnitude of the line segment, while aDirectioncannot, given that both have the same amount of information. The answer is that aDirectiondoes contain one thing aVectordoes not. ADirectionknows which way is “up”, while aVectordoes not. If you tell kOS toLOCK STEERINGto aVector, it will be able to point the nose of the vessel in the correct direction, but won’t know which way you want the roof of the craft rotated to. This works fine for axial symmetrical rockets but can be a problem for airplanes.
Therefore if you do this:
SET MyVec to V(100,200,300).
SET MyDir to MyVec:DIRECTION.
Then MyDir will be a Direction, but it will be a Direction where you have no control over which way is “up” for it.