Difference between revisions of "Oolite JavaScript Reference: Vector3D"
(→rotationTo: Noted that both vectors must be normal, and cleaned up.) |
(clarified descriptions of distanceTo and squaredDistanceTo and emphasized that both the source and the target must be vectors) |
||
Line 58: | Line 58: | ||
=== <code>distanceTo</code> === | === <code>distanceTo</code> === | ||
function '''distanceTo'''(v : [[#Vector Expressions|vectorExpression]]) : Number | function '''distanceTo'''(v : [[#Vector Expressions|vectorExpression]]) : Number | ||
− | Returns the distance between the | + | Returns the distance between the source vector and vector <code>v</code>. |
<code>u.distanceTo(v)</code> is equivalent to <code>u.[[#subtract|subtract]](v).[[#magnitude|magnitude]]()</code>. | <code>u.distanceTo(v)</code> is equivalent to <code>u.[[#subtract|subtract]](v).[[#magnitude|magnitude]]()</code>. | ||
+ | |||
+ | '''CAUTION:''' If passed a non-vector, the return code will be zero (no error will be raised). A common mistake is <code>this.ship.position.distanceTo(thatShip)</code>, which will always return zero! To fix it, change <code>thatShip</code> to <code>thatShip.position</code>. Similarly, <code>this.ship.distanceTo(thatShip.position)</code> is incorrect! It is missing <code>position</code> before <code>distanceTo</code>. | ||
'''See Also:''' <code>[[#squaredDistanceTo|squaredDistanceTo]]()</code> | '''See Also:''' <code>[[#squaredDistanceTo|squaredDistanceTo]]()</code> | ||
Line 112: | Line 114: | ||
=== <code>squaredDistanceTo</code> === | === <code>squaredDistanceTo</code> === | ||
function '''squaredDistanceTo'''(v: [[#Vector Expressions|vectorExpression]]) : Number | function '''squaredDistanceTo'''(v: [[#Vector Expressions|vectorExpression]]) : Number | ||
− | Returns the square of the distance between the | + | Returns the square of the distance between the source vector and vector <code>v</code>. |
<code>u.squaredDistanceTo(v)</code> is equivalent to <code>u.[[#distanceTo|distanceTo]](v) * u.[[#distanceTo|distanceTo]](v)</code>, or <code>u.[[#subtract|subtract]](v).[[#squaredMagnitude|squaredMagnitude]]()</code>. | <code>u.squaredDistanceTo(v)</code> is equivalent to <code>u.[[#distanceTo|distanceTo]](v) * u.[[#distanceTo|distanceTo]](v)</code>, or <code>u.[[#subtract|subtract]](v).[[#squaredMagnitude|squaredMagnitude]]()</code>. | ||
+ | |||
+ | '''CAUTION:''' If passed a non-vector, the return code will be zero (no error will be raised). A common mistake is <code>this.ship.position.squaredDistanceTo(thatShip)</code>, which will always return zero! To fix it, change <code>thatShip</code> to <code>thatShip.position</code>. Similarly, <code>this.ship.squaredDistanceTo(thatShip.position)</code> is incorrect! It is missing <code>position</code> before <code>squaredDistanceTo</code>. | ||
+ | |||
+ | '''See Also:''' <code>[[#distanceTo|distanceTo]]()</code> | ||
=== <code>squaredMagnitude</code> === | === <code>squaredMagnitude</code> === |
Revision as of 21:16, 18 June 2020
Prototype: Object
Subtypes: none
The Vector3D
class represents a geometrical vector in three-dimensional space, in cartesian representation. It is used to represent positions, headings and velocities. Explaining vector geometry is beyond the scope of this document, but there are numerous tutorials on the web.
Vector Expressions
All Oolite-provided functions which take a vector as an argument may instead be passed an array of three numbers, or an Entity (in which case the entity’s position
is used). In specifications, this is represented by arguments typed vectorExpression
. For example, if a
and b
are vectors whose values are (0, 1, 0) and (1, 0, 0) respectively, the following are equivalent:
var c = a.add(b); var d = a.add(Vector3D(1, 0, 0)); var e = a.add([1, 0, 0]); // c, d and e are now all (1, 1, 0).
Properties
x
x : Number (read/write)
The x co-ordinate of the vector.
y
y : Number (read/write)
The y co-ordinate of the vector.
z
z : Number (read/write)
The z co-ordinate of the vector.
Methods
Constructor
new Vector3D([value : vectorExpression]) : Vector3D
Create a new vector with the specified value. If no value is provided, the vector is initialized to (0, 0, 0).
add
function add(v : vectorExpression) : Vector3D
Returns the vector sum of the target and v
.
See Also: subtract()
angleTo
function angleTo(v : vectorExpression) : Number
Returns the angle (in radians) between the target and vectorExpression
. This is always a positive value between 0 and π.
v.angleTo(u)
is equivalent to Math.acos(v.direction().dot(u.direction()))
.
cross
function cross(v : vectorExpression) : Vector3D
Returns the cross product of the target and vectorExpression
.
See Also: dot()
direction
function direction() : Vector3D
Returns the unit vector with the same direction as the target.
v.direction()
is equivalent to v.multiply(1 / v.magnitude())
.
See Also: magnitude()
distanceTo
function distanceTo(v : vectorExpression) : Number
Returns the distance between the source vector and vector v
.
u.distanceTo(v)
is equivalent to u.subtract(v).magnitude()
.
CAUTION: If passed a non-vector, the return code will be zero (no error will be raised). A common mistake is this.ship.position.distanceTo(thatShip)
, which will always return zero! To fix it, change thatShip
to thatShip.position
. Similarly, this.ship.distanceTo(thatShip.position)
is incorrect! It is missing position
before distanceTo
.
See Also: squaredDistanceTo()
dot
function dot(v : vectorExpression) : Number
Returns the dot product of the target and v
.
The dot product of two vectors says something how well they are aligned to each other. The dot product of two identical vectors is 1 while two vectors pointing in opposite direction result in a -1 result. Also you can't reliably compare two vectors with each other to see if they are identical. To to check if vector1 == vector2
you need the dot product :
vector1.dot(vector2) > 0.999
See Also: cross()
fromCoordinateSystem
function fromCoordinateSystem(system : String) : Vector3D
Convert a vector from an abstract coordinate system to absolute coordinates. system
must be a three-letter string specifying an abstract coordinate system.
Important: Vectors do not “know” which coordinate system they’re in. The script must keep track of that. If you add together vectors in different coordinate systems the result will be nonsense, just as if you added measurements in different units without appropriate conversions.
Example:
this.halfway = Vector3D(0, 0, 0.5).fromCoordinateSystem("wpu"); // Equivalent: Vector3D.interpolate([0, 0, 0], S.mainPlanet, 0.5)
See Also: toCoordinateSystem()
magnitude
function magnitude() : Number
Returns the magnitude (or length) of the vector.
See Also: squaredMagnitude()
, direction()
multiply
function multiply(f : Number) : Vector3D
Returns the product of the target and f
. This has the effect of scaling the vector by the factor f
.
rotateBy
function rotateBy(q : quaternionExpression) : Vector3D
Apply the rotation specified by q
to the target vector.
rotationTo
function rotationTo(v : vectorExpression [, maxArc : Number]) : Quaternion
Returns a quaternion corresponding to a rotation from the target vector to v
. The optional parameter maxArc
specifies a maximum rotation angle; if the angle between the target and v
is greater than maxArc
radians, a rotation of maxArc
radians towards vectorExpression
is generated instead.
Both the target and v
must be normalized. The vectors must not be antiparallel (180° apart), since the axis of rotation is undefined in this case.
Example:
var orientation = myVector.rotationTo([0, 0, 1])
This will generate a quaternion were the forwardVector
is pointing in the same direction as myVector
. ([0, 0, 1]
is equal to the forwardVector
of the identity quaternion.)
squaredDistanceTo
function squaredDistanceTo(v: vectorExpression) : Number
Returns the square of the distance between the source vector and vector v
.
u.squaredDistanceTo(v)
is equivalent to u.distanceTo(v) * u.distanceTo(v)
, or u.subtract(v).squaredMagnitude()
.
CAUTION: If passed a non-vector, the return code will be zero (no error will be raised). A common mistake is this.ship.position.squaredDistanceTo(thatShip)
, which will always return zero! To fix it, change thatShip
to thatShip.position
. Similarly, this.ship.squaredDistanceTo(thatShip.position)
is incorrect! It is missing position
before squaredDistanceTo
.
See Also: distanceTo()
squaredMagnitude
function squaredMagnitude() : Number
Returns the square of the magnitude of the vector.
v.squaredMagnitude()
is equivalent to v.magnitude() * v.magnitude()
.
subtract
function subtract(v : vectorExpression) : Vector3D
Returns the vector difference between the target and v
.
See Also: add()
toArray
function toArray() : Array
Returns an array of the vector’s components, in the order [x, y, z]
. v.toArray()
is equivalent to [v.x, v.y, v.z]
.
toCoordinateSystem
function toCoordinateSystem(system : String) : Vector3D
Convert a vector from absolute coordinates to an abstract coordinate system. system
must be a three-letter string specifying an abstract coordinate system. The target of the method must be a vector in absolute coordinates. (To convert a vector from one abstract coordinate system to another, you must first call code>fromCoordinateSystem(), then toCoordinateSystem()
.)
Important: Vectors do not “know” which coordinate system they’re in. The script must keep track of that. If you add together vectors in different coordinate systems the result will be nonsense, just as if you added measurements in different units without appropriate conversions.
Example:
Vector3D(0, 0, 226380).toCoordinateSystem("wpu") // In Lave system, this returns (0, 0, 0.5).
See Also: fromCoordinateSystem()
tripleProduct
function tripleProduct(v : vectorExpression, w : vectorExpression) : Number
Returns the triple product of the target, v
and w
.
u.tripleProduct(v, w)
is equivalent to u.dot(v.cross(w))
.
Static methods
interpolate
function interpolate(u : vectorExpression, v : vectorExpression, where : Number) : Vector3D
Returns a point on the line between u
and v
. If where
is 0, the result is u
. If where
is 1, the result is v
. If where
is 0.5, the result is half way between u
and v
. Values of where
outside the range [0, 1] are valid; for instance, Vector3D.interpolate(u, v, -1)
returns a point as far from u
as v
is, but in the opposite direction.
Vector3D.interpolate(u, v, where)
is equivalent to u.add(v.subtract(u).multiply(where))
, or u.multiply(1 - where).add(v. multiply(where))
.
random
function random([maxLength : Number]) : Vector3D
Returns a vector of random length up to maxLength
, in a random direction. If maxLength
is not specified (or not a number), 1.0 is used. These vectors are uniformly distributed within the unit sphere, which has the effect that longer vectors are more common than shorter ones. Use Vector3D.randomDirectionAndLength()
if an even length distribution is desired.
In the following image, the cloud on the left was made with the 2D equivalent of random()
, and the image on the right was made with the 2D equivalent of randomDirectionAndLength()
.
See Also: randomDirection()
, randomDirectionAndLength()
randomDirection
function randomDirection([scale : Number]) : Vector3D
Returns a vector of length scale
, in a random direction. If scale
is not specified (or not a number), 1.0 is used.
See Also: random()
, randomDirectionAndLength()
randomDirectionAndLength
function randomDirectionAndLength([maxLength : Number]) : Vector3D
Returns a vector of random length up to maxLength
, in a random direction. If maxLength
is not specified (or not a number), 1.0 is used. These vectors have a uniform distribution of magnitude (all lengths are equally likely), but cluster towards the origin. Use Vector3D.random()
if an even spacial distribution is desired.
See Also: random()
, randomDirection()