# VirtualCast

### Sidebar

#### wiki editors only

en:vci:script:reference:quaternion

# Quaternion

Quaternion is a class with three values: X, Y, Z and W.
It is a class to describe rotation. However, we do not specify Quaternion directly to change the values directly.
In most cases, we use methods listed below to change the values.

## List of methods

For the latest list of the methods, refer to “types.lua” file in “EmbeddedScriptWorkspace” folder.
To shorten the description, `Vector3 type` is abbreviated as `Vec` and `number type` is abbreviated as `num`.
Arguments are shown in `()` and return values are shown after semicolons `:`.

 Method name Description _new fun(x: num, y: num, z: num, w: num): Quaternion Initialization FromToRotation fun(fromDirection: Vec3, toDirection: Vec3): Quaternion Rotate from the `fromDirection` to the `toDirection`. Inverse fun(rotation: Quaternion): Quaternion Create a Quaternion that is the opposite of the rotation. Slerp fun(a: Quaternion, b: Quaternion, t: num): Quaternion Spherically interpolates between a and b by the coefficient t. The range of t is [0, 1]. SlerpUnclamped fun(a: Quaternion, b: Quaternion, t: num): Quaternion Same as Slerp, but doesn't restrict the t range to [0, 1]. Used for things like springs. Lerp fun(a: Quaternion, b: Quaternion, t: num): Quaternion Linearly interpolates between a and b by the coefficient t. The range of t is [0, 1]. LerpUnclamped fun(a: Quaternion, b: Quaternion, t: num): Quaternion Same as Lerp, but doesn't restrict the t range to [0, 1]. Used for things like springs. AngleAxis fun(angle: num, axis: Vec3): Quaternion Create a rotation of `angle` degrees, using vector of the `axis` as the center LookRotation fun(forward: Vec3, upwards: Vec3): Quaternion Turn towards forward direction and upwards direction. Dot fun(a: Quaternion, b: Quaternion): num Returns the inner product of two rotations: a and b. Angle fun(a: Quaternion, b: Quaternion): num Returns the angle of two rotations: a and b. Euler fun(x: num, y: num, z: num): Quaternion Create a Quaternion by specifying Euler angle ToAngleAxis fun(angle: usertype, axis: usertype) Convert the rotation to a value of angle against the axis (AngleAxis). RotateTowards fun(from: Quaternion, to: Quaternion, maxDegreesDelta: num): Quaternion Interpolate the largest rotation between the two Quaternions. Normalize fun(q: Quaternion): Quaternion GetHashCode fun(): num Not to be used. ToString fun(): string ToEuler fun(): Vec3 ToEulerAngles fun(): Vec3 identity Quaternion Create a basic Quaternion of (0.0, 0.0, 0.0, 1.0). eulerAngles Vec3 Return rotation in value of Euler angle. normalized Quaternion x num In most cases, do not change Quaternion directly. y num In most cases, do not change Quaternion directly. z num In most cases, do not change Quaternion directly. w num In most cases, do not change Quaternion directly. kEpsilon num

Example

main.lua
```rotate = Quaternion.identity
print(rotate)```

The result

`(0.0, 0.0, 0.0, 1.0)`

Basically, use `Quaternion.identity` to initialize a Quaternion.
You can also use `__new()` to declare, but it is very rare to handle a Quaternion directly. Also, in the example above, you can access each element directly like `rotate.x = 1`, but it is recommended to use methods provided to manipulate a quaternion.

Example

main.lua
```-- The name of the SubItem game object and the argument string in GetTransform("") must match.
Subitem = vci.assets.GetTransform("Subitem")
function onUngrab()
local rotate = Quaternion.identity
local velocity = Vector3.zero
Subitem.SetLocalRotation(rotate)
Subitem.SetVelocity(velocity)
end```

The result

`(When you release the VCI from the grabbed state, its rotation will be set to the initial state (x = 0, y = 0, z = 0).)`

By using `SetLocalRotation()`, you can set the attitude to the Quaternion created.
When doing so, after setting the attitude, `SetVelocity()` to 0 to avoid the attitude from being updated by Rigidbody.

## Euler()

Euler fun(x: number, y: number, z: number): Quaternion

Example

main.lua
```--- The name of the SubItem game object and the argument string in GetTransform("") must match.
Subitem = vci.assets.GetTransform("Subitem")
function onUngrab()
local rotate = Quaternion.Euler(30, 45, 60)
local velocity = Vector3.zero
Subitem.SetLocalRotation(rotate)
Subitem.SetVelocity(velocity)
end```

The result

`(When you release the VCI from grabbed state, its rotation will be set to (x = 30, y = 45, z = 60).)`

Specify the rotation with Euler angle value (0 ~ 360 degrees) to create Quaternion.
Specification of elements shall be done in order of X, Y and Z.

## eulerAngles

eulerAngles Vector3

Example

main.lua
```euler = Quaternion.Euler(30, 45, 60)
print(euler)
print(euler.eulerAngles)
print(euler.eulerAngles.x)
print(euler.eulerAngles.y)
print(euler.eulerAngles.z)```

The result

```(0.4, 0.2, 0.4, 0.8)
(30.0, 45.0, 60.0)
30.0000019073486
45
60.0000038146973```

Return a Quaternion value in form of Euler angle value. By specifying individual element after `eulerAngles.`, you can access each element of the angles.

## AxisAngle()

AngleAxis fun(angle: number, axis: Vector3): Quaternion

Example

main.lua
```-- The name of the SubItem game object and the argument string in GetTransform("") must match.
Subitem = vci.assets.GetTransform("Subitem")
angle = 0
function onUngrab()
angle = angle + math.pi / 180
if angle > (2 * math.pi) then
angle = 0
end
print(angle)

local axis = Vector3.up
local rotate = Quaternion.AxisAngle(axis, angle)
Subitem.SetLocalRotation(rotate)

local velocity = Vector3.zero
Subitem.SetVelocity(velocity)
end```

The result

`(When you release the VCI from grabbed state, the y-axis rotation (Rotation.y) is incremented by 1 degree.)`

Specify a direction with Vector3 to use as an axis of rotation and rotate by the value of “angle”.
In the example, `axis = Vector3.up` creates an axis that goes from down to up, which then is used as the axis of rotation.
The “angle” specifying the degrees of rotation, shall be specified with a value between `0～6.28318530718(2π)`.
2π divided by 360 is `0.01745329251`. So by adding this value to the “angle,” the object will rotate by 1 degree.
To express π in Lua, use `math.pi`.

## LookRotation()

LookRotation fun(forward: Vector3, upwards: Vector3): Quaternion

Example

main.lua
```function onUngrab(target)
local forward = vci.assets.GetTransform(target).GetForward()
local up = vci.assets.GetTransform(target).GetUp()
local rotate = Quaternion.LookRotation(forward, up)
print(rotate)
print(vci.assets.GetTransform(target).GetRotation())
end```

The result

```(0.0, -0.3, -0.1, 1.0)
(0.0, -0.3, -0.1, 1.0)
(0.0, 0.9, 0.0, 0.4)
(0.0, 0.9, 0.0, 0.4)```

Create a Quaternion using an up vector and a forward vector.
In the example,`rotate` and `vci.assets.GetTransform(target).GetRotation()` take the same value.

## Lerp()

Lerp fun(a: Quaternion, b: Quaternion, t: number): Quaternion

Example

main.lua
```-- The name of the SubItem game object and the argument string in GetTransform("") must match.
Subitem = vci.assets.GetTransform("Subitem")
base = Quaternion.identity
target = Quaternion.Euler(0, 90, 0)
function update()
local time = math.abs(math.sin((vci.me.FrameCount / 60)))
local lerp = Quaternion.Lerp(base, target, time)
Subitem.SetRotation(lerp)
end```

The result

`(The SubItem slowly oscillates by 90 degrees.)`

Creates a Quaternion that interpolates between the base Quaternion and the target Quaternion.
By specifying a value in the range of 0-1, you get a Quaternion that corresponds to the quotient.
By changing it gradually, its attitude slowly changes from one attitude to the another.

## Angle()

Angle fun(a: Quaternion, b: Quaternion): number

Example

main.lua
` `

The result

` `

Description

## Dot

Dot fun(a: Quaternion, b: Quaternion): number

Example

main.lua
```function onUngrab(target)
local rotate = vci.assets.GetTransform(target).GetRotation()
local base = Quaternion.identity
print(Quaternion.Dot(rotate, base))
end```

The result

```0.886427819728851
-0.289039075374603
(When you release your hand from VCI, it acquires the inner product of the grabbed item and the base)```

Compare two Quaternions and acquires the inner product.
The return value is in the range of `-1～1`.

## Method name

Example

main.lua
` `

The result

` `

Description 