Skip to content

⬅️ Back to Table of Contents

📄 Euler.js

📊 Analysis Summary

Metric Count
🔧 Functions 13
🧱 Classes 1
📦 Imports 3
📊 Variables & Constants 12

📚 Table of Contents

🛠️ File Location:

📂 src/math/Euler.js

📦 Imports

Name Source
Quaternion ./Quaternion.js
Matrix4 ./Matrix4.js
clamp ./MathUtils.js

Variables & Constants

Name Type Kind Value Exported
_matrix Matrix4 let/var new Matrix4()
_quaternion Quaternion let/var new Quaternion()
te number[] let/var m.elements
m11 number let/var te[ 0 ]
m12 number let/var te[ 4 ]
m13 number let/var te[ 8 ]
m21 number let/var te[ 1 ]
m22 number let/var te[ 5 ]
m23 number let/var te[ 9 ]
m31 number let/var te[ 2 ]
m32 number let/var te[ 6 ]
m33 number let/var te[ 10 ]

Functions

Euler.set(x: number, y: number, z: number, order: string): Euler

JSDoc:

/**
     * Sets the Euler components.
     *
     * @param {number} x - The angle of the x axis in radians.
     * @param {number} y - The angle of the y axis in radians.
     * @param {number} z - The angle of the z axis in radians.
     * @param {string} [order] - A string representing the order that the rotations are applied.
     * @return {Euler} A reference to this Euler instance.
     */

Parameters:

  • x number
  • y number
  • z number
  • order string

Returns: Euler

Calls:

  • this._onChangeCallback
Code
set( x, y, z, order = this._order ) {

        this._x = x;
        this._y = y;
        this._z = z;
        this._order = order;

        this._onChangeCallback();

        return this;

    }

Euler.clone(): Euler

JSDoc:

/**
     * Returns a new Euler instance with copied values from this instance.
     *
     * @return {Euler} A clone of this instance.
     */

Returns: Euler

Code
clone() {

        return new this.constructor( this._x, this._y, this._z, this._order );

    }

Euler.copy(euler: Euler): Euler

JSDoc:

/**
     * Copies the values of the given Euler instance to this instance.
     *
     * @param {Euler} euler - The Euler instance to copy.
     * @return {Euler} A reference to this Euler instance.
     */

Parameters:

  • euler Euler

Returns: Euler

Calls:

  • this._onChangeCallback
Code
copy( euler ) {

        this._x = euler._x;
        this._y = euler._y;
        this._z = euler._z;
        this._order = euler._order;

        this._onChangeCallback();

        return this;

    }

Euler.setFromRotationMatrix(m: Matrix4, order: string, update: boolean): Euler

JSDoc:

/**
     * Sets the angles of this Euler instance from a pure rotation matrix.
     *
     * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled).
     * @param {string} [order] - A string representing the order that the rotations are applied.
     * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
     * @return {Euler} A reference to this Euler instance.
     */

Parameters:

  • m Matrix4
  • order string
  • update boolean

Returns: Euler

Calls:

  • Math.asin
  • clamp (from ./MathUtils.js)
  • Math.abs
  • Math.atan2
  • console.warn
  • this._onChangeCallback
Code
setFromRotationMatrix( m, order = this._order, update = true ) {

        const te = m.elements;
        const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
        const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
        const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];

        switch ( order ) {

            case 'XYZ':

                this._y = Math.asin( clamp( m13, - 1, 1 ) );

                if ( Math.abs( m13 ) < 0.9999999 ) {

                    this._x = Math.atan2( - m23, m33 );
                    this._z = Math.atan2( - m12, m11 );

                } else {

                    this._x = Math.atan2( m32, m22 );
                    this._z = 0;

                }

                break;

            case 'YXZ':

                this._x = Math.asin( - clamp( m23, - 1, 1 ) );

                if ( Math.abs( m23 ) < 0.9999999 ) {

                    this._y = Math.atan2( m13, m33 );
                    this._z = Math.atan2( m21, m22 );

                } else {

                    this._y = Math.atan2( - m31, m11 );
                    this._z = 0;

                }

                break;

            case 'ZXY':

                this._x = Math.asin( clamp( m32, - 1, 1 ) );

                if ( Math.abs( m32 ) < 0.9999999 ) {

                    this._y = Math.atan2( - m31, m33 );
                    this._z = Math.atan2( - m12, m22 );

                } else {

                    this._y = 0;
                    this._z = Math.atan2( m21, m11 );

                }

                break;

            case 'ZYX':

                this._y = Math.asin( - clamp( m31, - 1, 1 ) );

                if ( Math.abs( m31 ) < 0.9999999 ) {

                    this._x = Math.atan2( m32, m33 );
                    this._z = Math.atan2( m21, m11 );

                } else {

                    this._x = 0;
                    this._z = Math.atan2( - m12, m22 );

                }

                break;

            case 'YZX':

                this._z = Math.asin( clamp( m21, - 1, 1 ) );

                if ( Math.abs( m21 ) < 0.9999999 ) {

                    this._x = Math.atan2( - m23, m22 );
                    this._y = Math.atan2( - m31, m11 );

                } else {

                    this._x = 0;
                    this._y = Math.atan2( m13, m33 );

                }

                break;

            case 'XZY':

                this._z = Math.asin( - clamp( m12, - 1, 1 ) );

                if ( Math.abs( m12 ) < 0.9999999 ) {

                    this._x = Math.atan2( m32, m22 );
                    this._y = Math.atan2( m13, m11 );

                } else {

                    this._x = Math.atan2( - m23, m33 );
                    this._y = 0;

                }

                break;

            default:

                console.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order );

        }

        this._order = order;

        if ( update === true ) this._onChangeCallback();

        return this;

    }

Euler.setFromQuaternion(q: Quaternion, order: string, update: boolean): Euler

JSDoc:

/**
     * Sets the angles of this Euler instance from a normalized quaternion.
     *
     * @param {Quaternion} q - A normalized Quaternion.
     * @param {string} [order] - A string representing the order that the rotations are applied.
     * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
     * @return {Euler} A reference to this Euler instance.
     */

Parameters:

  • q Quaternion
  • order string
  • update boolean

Returns: Euler

Calls:

  • _matrix.makeRotationFromQuaternion
  • this.setFromRotationMatrix
Code
setFromQuaternion( q, order, update ) {

        _matrix.makeRotationFromQuaternion( q );

        return this.setFromRotationMatrix( _matrix, order, update );

    }

Euler.setFromVector3(v: Vector3, order: string): Euler

JSDoc:

/**
     * Sets the angles of this Euler instance from the given vector.
     *
     * @param {Vector3} v - The vector.
     * @param {string} [order] - A string representing the order that the rotations are applied.
     * @return {Euler} A reference to this Euler instance.
     */

Parameters:

  • v Vector3
  • order string

Returns: Euler

Calls:

  • this.set
Code
setFromVector3( v, order = this._order ) {

        return this.set( v.x, v.y, v.z, order );

    }

Euler.reorder(newOrder: string): Euler

JSDoc:

/**
     * Resets the euler angle with a new order by creating a quaternion from this
     * euler angle and then setting this euler angle with the quaternion and the
     * new order.
     *
     * Warning: This discards revolution information.
     *
     * @param {string} [newOrder] - A string representing the new order that the rotations are applied.
     * @return {Euler} A reference to this Euler instance.
     */

Parameters:

  • newOrder string

Returns: Euler

Calls:

  • _quaternion.setFromEuler
  • this.setFromQuaternion
Code
reorder( newOrder ) {

        _quaternion.setFromEuler( this );

        return this.setFromQuaternion( _quaternion, newOrder );

    }

Euler.equals(euler: Euler): boolean

JSDoc:

/**
     * Returns `true` if this Euler instance is equal with the given one.
     *
     * @param {Euler} euler - The Euler instance to test for equality.
     * @return {boolean} Whether this Euler instance is equal with the given one.
     */

Parameters:

  • euler Euler

Returns: boolean

Code
equals( euler ) {

        return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );

    }

Euler.fromArray(array: number[]): Euler

JSDoc:

/**
     * Sets this Euler instance's components to values from the given array. The first three
     * entries of the array are assign to the x,y and z components. An optional fourth entry
     * defines the Euler order.
     *
     * @param {Array<number,number,number,?string>} array - An array holding the Euler component values.
     * @return {Euler} A reference to this Euler instance.
     */

Parameters:

  • array number[]

Returns: Euler

Calls:

  • this._onChangeCallback
Code
fromArray( array ) {

        this._x = array[ 0 ];
        this._y = array[ 1 ];
        this._z = array[ 2 ];
        if ( array[ 3 ] !== undefined ) this._order = array[ 3 ];

        this._onChangeCallback();

        return this;

    }

Euler.toArray(array: number[], offset: number): number[]

JSDoc:

/**
     * Writes the components of this Euler instance to the given array. If no array is provided,
     * the method returns a new instance.
     *
     * @param {Array<number,number,number,string>} [array=[]] - The target array holding the Euler components.
     * @param {number} [offset=0] - Index of the first element in the array.
     * @return {Array<number,number,number,string>} The Euler components.
     */

Parameters:

  • array number[]
  • offset number

Returns: number[]

Code
toArray( array = [], offset = 0 ) {

        array[ offset ] = this._x;
        array[ offset + 1 ] = this._y;
        array[ offset + 2 ] = this._z;
        array[ offset + 3 ] = this._order;

        return array;

    }

Euler._onChange(callback: any): this

Parameters:

  • callback any

Returns: this

Code
_onChange( callback ) {

        this._onChangeCallback = callback;

        return this;

    }

Euler._onChangeCallback(): void

Returns: void

Code
_onChangeCallback() {}

Euler.[ Symbol.iterator ](): Generator<string | number, void, unknown>

Returns: Generator<string | number, void, unknown>

Code
*[ Symbol.iterator ]() {

        yield this._x;
        yield this._y;
        yield this._z;
        yield this._order;

    }

Classes

Euler

Class Code
class Euler {

    /**
     * Constructs a new euler instance.
     *
     * @param {number} [x=0] - The angle of the x axis in radians.
     * @param {number} [y=0] - The angle of the y axis in radians.
     * @param {number} [z=0] - The angle of the z axis in radians.
     * @param {string} [order=Euler.DEFAULT_ORDER] - A string representing the order that the rotations are applied.
     */
    constructor( x = 0, y = 0, z = 0, order = Euler.DEFAULT_ORDER ) {

        /**
         * This flag can be used for type testing.
         *
         * @type {boolean}
         * @readonly
         * @default true
         */
        this.isEuler = true;

        this._x = x;
        this._y = y;
        this._z = z;
        this._order = order;

    }

    /**
     * The angle of the x axis in radians.
     *
     * @type {number}
     * @default 0
     */
    get x() {

        return this._x;

    }

    set x( value ) {

        this._x = value;
        this._onChangeCallback();

    }

    /**
     * The angle of the y axis in radians.
     *
     * @type {number}
     * @default 0
     */
    get y() {

        return this._y;

    }

    set y( value ) {

        this._y = value;
        this._onChangeCallback();

    }

    /**
     * The angle of the z axis in radians.
     *
     * @type {number}
     * @default 0
     */
    get z() {

        return this._z;

    }

    set z( value ) {

        this._z = value;
        this._onChangeCallback();

    }

    /**
     * A string representing the order that the rotations are applied.
     *
     * @type {string}
     * @default 'XYZ'
     */
    get order() {

        return this._order;

    }

    set order( value ) {

        this._order = value;
        this._onChangeCallback();

    }

    /**
     * Sets the Euler components.
     *
     * @param {number} x - The angle of the x axis in radians.
     * @param {number} y - The angle of the y axis in radians.
     * @param {number} z - The angle of the z axis in radians.
     * @param {string} [order] - A string representing the order that the rotations are applied.
     * @return {Euler} A reference to this Euler instance.
     */
    set( x, y, z, order = this._order ) {

        this._x = x;
        this._y = y;
        this._z = z;
        this._order = order;

        this._onChangeCallback();

        return this;

    }

    /**
     * Returns a new Euler instance with copied values from this instance.
     *
     * @return {Euler} A clone of this instance.
     */
    clone() {

        return new this.constructor( this._x, this._y, this._z, this._order );

    }

    /**
     * Copies the values of the given Euler instance to this instance.
     *
     * @param {Euler} euler - The Euler instance to copy.
     * @return {Euler} A reference to this Euler instance.
     */
    copy( euler ) {

        this._x = euler._x;
        this._y = euler._y;
        this._z = euler._z;
        this._order = euler._order;

        this._onChangeCallback();

        return this;

    }

    /**
     * Sets the angles of this Euler instance from a pure rotation matrix.
     *
     * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled).
     * @param {string} [order] - A string representing the order that the rotations are applied.
     * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
     * @return {Euler} A reference to this Euler instance.
     */
    setFromRotationMatrix( m, order = this._order, update = true ) {

        const te = m.elements;
        const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
        const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
        const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];

        switch ( order ) {

            case 'XYZ':

                this._y = Math.asin( clamp( m13, - 1, 1 ) );

                if ( Math.abs( m13 ) < 0.9999999 ) {

                    this._x = Math.atan2( - m23, m33 );
                    this._z = Math.atan2( - m12, m11 );

                } else {

                    this._x = Math.atan2( m32, m22 );
                    this._z = 0;

                }

                break;

            case 'YXZ':

                this._x = Math.asin( - clamp( m23, - 1, 1 ) );

                if ( Math.abs( m23 ) < 0.9999999 ) {

                    this._y = Math.atan2( m13, m33 );
                    this._z = Math.atan2( m21, m22 );

                } else {

                    this._y = Math.atan2( - m31, m11 );
                    this._z = 0;

                }

                break;

            case 'ZXY':

                this._x = Math.asin( clamp( m32, - 1, 1 ) );

                if ( Math.abs( m32 ) < 0.9999999 ) {

                    this._y = Math.atan2( - m31, m33 );
                    this._z = Math.atan2( - m12, m22 );

                } else {

                    this._y = 0;
                    this._z = Math.atan2( m21, m11 );

                }

                break;

            case 'ZYX':

                this._y = Math.asin( - clamp( m31, - 1, 1 ) );

                if ( Math.abs( m31 ) < 0.9999999 ) {

                    this._x = Math.atan2( m32, m33 );
                    this._z = Math.atan2( m21, m11 );

                } else {

                    this._x = 0;
                    this._z = Math.atan2( - m12, m22 );

                }

                break;

            case 'YZX':

                this._z = Math.asin( clamp( m21, - 1, 1 ) );

                if ( Math.abs( m21 ) < 0.9999999 ) {

                    this._x = Math.atan2( - m23, m22 );
                    this._y = Math.atan2( - m31, m11 );

                } else {

                    this._x = 0;
                    this._y = Math.atan2( m13, m33 );

                }

                break;

            case 'XZY':

                this._z = Math.asin( - clamp( m12, - 1, 1 ) );

                if ( Math.abs( m12 ) < 0.9999999 ) {

                    this._x = Math.atan2( m32, m22 );
                    this._y = Math.atan2( m13, m11 );

                } else {

                    this._x = Math.atan2( - m23, m33 );
                    this._y = 0;

                }

                break;

            default:

                console.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order );

        }

        this._order = order;

        if ( update === true ) this._onChangeCallback();

        return this;

    }

    /**
     * Sets the angles of this Euler instance from a normalized quaternion.
     *
     * @param {Quaternion} q - A normalized Quaternion.
     * @param {string} [order] - A string representing the order that the rotations are applied.
     * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
     * @return {Euler} A reference to this Euler instance.
     */
    setFromQuaternion( q, order, update ) {

        _matrix.makeRotationFromQuaternion( q );

        return this.setFromRotationMatrix( _matrix, order, update );

    }

    /**
     * Sets the angles of this Euler instance from the given vector.
     *
     * @param {Vector3} v - The vector.
     * @param {string} [order] - A string representing the order that the rotations are applied.
     * @return {Euler} A reference to this Euler instance.
     */
    setFromVector3( v, order = this._order ) {

        return this.set( v.x, v.y, v.z, order );

    }

    /**
     * Resets the euler angle with a new order by creating a quaternion from this
     * euler angle and then setting this euler angle with the quaternion and the
     * new order.
     *
     * Warning: This discards revolution information.
     *
     * @param {string} [newOrder] - A string representing the new order that the rotations are applied.
     * @return {Euler} A reference to this Euler instance.
     */
    reorder( newOrder ) {

        _quaternion.setFromEuler( this );

        return this.setFromQuaternion( _quaternion, newOrder );

    }

    /**
     * Returns `true` if this Euler instance is equal with the given one.
     *
     * @param {Euler} euler - The Euler instance to test for equality.
     * @return {boolean} Whether this Euler instance is equal with the given one.
     */
    equals( euler ) {

        return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );

    }

    /**
     * Sets this Euler instance's components to values from the given array. The first three
     * entries of the array are assign to the x,y and z components. An optional fourth entry
     * defines the Euler order.
     *
     * @param {Array<number,number,number,?string>} array - An array holding the Euler component values.
     * @return {Euler} A reference to this Euler instance.
     */
    fromArray( array ) {

        this._x = array[ 0 ];
        this._y = array[ 1 ];
        this._z = array[ 2 ];
        if ( array[ 3 ] !== undefined ) this._order = array[ 3 ];

        this._onChangeCallback();

        return this;

    }

    /**
     * Writes the components of this Euler instance to the given array. If no array is provided,
     * the method returns a new instance.
     *
     * @param {Array<number,number,number,string>} [array=[]] - The target array holding the Euler components.
     * @param {number} [offset=0] - Index of the first element in the array.
     * @return {Array<number,number,number,string>} The Euler components.
     */
    toArray( array = [], offset = 0 ) {

        array[ offset ] = this._x;
        array[ offset + 1 ] = this._y;
        array[ offset + 2 ] = this._z;
        array[ offset + 3 ] = this._order;

        return array;

    }

    _onChange( callback ) {

        this._onChangeCallback = callback;

        return this;

    }

    _onChangeCallback() {}

    *[ Symbol.iterator ]() {

        yield this._x;
        yield this._y;
        yield this._z;
        yield this._order;

    }

}

Methods

set(x: number, y: number, z: number, order: string): Euler
Code
set( x, y, z, order = this._order ) {

        this._x = x;
        this._y = y;
        this._z = z;
        this._order = order;

        this._onChangeCallback();

        return this;

    }
clone(): Euler
Code
clone() {

        return new this.constructor( this._x, this._y, this._z, this._order );

    }
copy(euler: Euler): Euler
Code
copy( euler ) {

        this._x = euler._x;
        this._y = euler._y;
        this._z = euler._z;
        this._order = euler._order;

        this._onChangeCallback();

        return this;

    }
setFromRotationMatrix(m: Matrix4, order: string, update: boolean): Euler
Code
setFromRotationMatrix( m, order = this._order, update = true ) {

        const te = m.elements;
        const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
        const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
        const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];

        switch ( order ) {

            case 'XYZ':

                this._y = Math.asin( clamp( m13, - 1, 1 ) );

                if ( Math.abs( m13 ) < 0.9999999 ) {

                    this._x = Math.atan2( - m23, m33 );
                    this._z = Math.atan2( - m12, m11 );

                } else {

                    this._x = Math.atan2( m32, m22 );
                    this._z = 0;

                }

                break;

            case 'YXZ':

                this._x = Math.asin( - clamp( m23, - 1, 1 ) );

                if ( Math.abs( m23 ) < 0.9999999 ) {

                    this._y = Math.atan2( m13, m33 );
                    this._z = Math.atan2( m21, m22 );

                } else {

                    this._y = Math.atan2( - m31, m11 );
                    this._z = 0;

                }

                break;

            case 'ZXY':

                this._x = Math.asin( clamp( m32, - 1, 1 ) );

                if ( Math.abs( m32 ) < 0.9999999 ) {

                    this._y = Math.atan2( - m31, m33 );
                    this._z = Math.atan2( - m12, m22 );

                } else {

                    this._y = 0;
                    this._z = Math.atan2( m21, m11 );

                }

                break;

            case 'ZYX':

                this._y = Math.asin( - clamp( m31, - 1, 1 ) );

                if ( Math.abs( m31 ) < 0.9999999 ) {

                    this._x = Math.atan2( m32, m33 );
                    this._z = Math.atan2( m21, m11 );

                } else {

                    this._x = 0;
                    this._z = Math.atan2( - m12, m22 );

                }

                break;

            case 'YZX':

                this._z = Math.asin( clamp( m21, - 1, 1 ) );

                if ( Math.abs( m21 ) < 0.9999999 ) {

                    this._x = Math.atan2( - m23, m22 );
                    this._y = Math.atan2( - m31, m11 );

                } else {

                    this._x = 0;
                    this._y = Math.atan2( m13, m33 );

                }

                break;

            case 'XZY':

                this._z = Math.asin( - clamp( m12, - 1, 1 ) );

                if ( Math.abs( m12 ) < 0.9999999 ) {

                    this._x = Math.atan2( m32, m22 );
                    this._y = Math.atan2( m13, m11 );

                } else {

                    this._x = Math.atan2( - m23, m33 );
                    this._y = 0;

                }

                break;

            default:

                console.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order );

        }

        this._order = order;

        if ( update === true ) this._onChangeCallback();

        return this;

    }
setFromQuaternion(q: Quaternion, order: string, update: boolean): Euler
Code
setFromQuaternion( q, order, update ) {

        _matrix.makeRotationFromQuaternion( q );

        return this.setFromRotationMatrix( _matrix, order, update );

    }
setFromVector3(v: Vector3, order: string): Euler
Code
setFromVector3( v, order = this._order ) {

        return this.set( v.x, v.y, v.z, order );

    }
reorder(newOrder: string): Euler
Code
reorder( newOrder ) {

        _quaternion.setFromEuler( this );

        return this.setFromQuaternion( _quaternion, newOrder );

    }
equals(euler: Euler): boolean
Code
equals( euler ) {

        return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );

    }
fromArray(array: number[]): Euler
Code
fromArray( array ) {

        this._x = array[ 0 ];
        this._y = array[ 1 ];
        this._z = array[ 2 ];
        if ( array[ 3 ] !== undefined ) this._order = array[ 3 ];

        this._onChangeCallback();

        return this;

    }
toArray(array: number[], offset: number): number[]
Code
toArray( array = [], offset = 0 ) {

        array[ offset ] = this._x;
        array[ offset + 1 ] = this._y;
        array[ offset + 2 ] = this._z;
        array[ offset + 3 ] = this._order;

        return array;

    }
_onChange(callback: any): this
Code
_onChange( callback ) {

        this._onChangeCallback = callback;

        return this;

    }
_onChangeCallback(): void
Code
_onChangeCallback() {}
[ Symbol.iterator ](): Generator<string | number, void, unknown>
Code
*[ Symbol.iterator ]() {

        yield this._x;
        yield this._y;
        yield this._z;
        yield this._order;

    }