LoginSignup
32
27

More than 3 years have passed since last update.

three.jsで学ぶベクトル演算

Last updated at Posted at 2019-11-09

ベクトル演算についてまとめながら、three.jsのベクトルクラスの実装を見ていきたいと思います。

three.jsには2次元ベクトルを表すVector2クラス、3次元ベクトルを表すVector3クラス、4次元ベクトルを表すVector4クラスが存在します。それぞれVector2.jsVector3.jsVector4.jsで実装されています。

基本的にはベクトルの演算は次元数によらず同じなので3D CGで最もよく使用する3次元ベクトル(Vector3)について見ていきます。

three.jsは現時点(2019/11/09)において最新のバージョンであるr110を参考にしています。
ベクトルは特に断りのない限り、列ベクトルです。実数は小文字(e.g. $x$)、ベクトルは上付き矢印(e.g. $\vec{v}$)、行列は大文字(e.g. $M$)、クォータニオンは上付きハット(e.g. $\hat{q}$)で表します。

ベクトルの要素

3次元ベクトルは3つの実数を持つベクトルです。各要素を順に$x$、$y$、$z$で表します。

\vec{v} = \left(\begin{array}{c}x \\ y\\ z \end{array}\right)

Vector3クラスでは、インスタンス変数xyzで各要素を保持します。引数として値が与えられない場合はデフォルト値として0を設定しています。

function Vector3( x, y, z ) {

    this.x = x || 0;
    this.y = y || 0;
    this.z = z || 0;

}

setsetScalarメソッドでVector3インスタンスの要素を変更できるほか、setXsetYsetZメソッドで一つの要素のみを変更することも可能です。

    set: function ( x, y, z ) {

        this.x = x;
        this.y = y;
        this.z = z;

        return this;

    },

    setScalar: function ( scalar ) {

        this.x = scalar;
        this.y = scalar;
        this.z = scalar;

        return this;

    },

    setX: function ( x ) {

        this.x = x;

        return this;

    },

    setY: function ( y ) {

        this.y = y;

        return this;

    },

    setZ: function ( z ) {

        this.z = z;

        return this;

    },

そのほかにインデックス値で各要素を取得・設定できるgetComponentメソッドとsetCompoenntメソッドがVector3クラスには存在しています。

    setComponent: function ( index, value ) {

        switch ( index ) {

            case 0: this.x = value; break;
            case 1: this.y = value; break;
            case 2: this.z = value; break;
            default: throw new Error( 'index is out of range: ' + index );

        }

        return this;

    },

    getComponent: function ( index ) {

        switch ( index ) {

            case 0: return this.x;
            case 1: return this.y;
            case 2: return this.z;
            default: throw new Error( 'index is out of range: ' + index );

        }

    },

cloneメソッドで同じ値を持つ新たなVector3インスタンスを生成でき、copyメソッドで引数に与えたVector3インスタンスと同じ値を持つようにすることができます。

    clone: function () {

        return new this.constructor( this.x, this.y, this.z );

    },

    copy: function ( v ) {

        this.x = v.x;
        this.y = v.y;
        this.z = v.z;

        return this;

    },

ベクトルの和

2つのベクトルの和は各要素同士の和になります。

\vec{v_1} + \vec{v_2} =
\left(\begin{array}{c}x_1 \\ y_1\\ z_1 \end{array}\right) + 
\left(\begin{array}{c}x_2 \\ y_2\\ z_2 \end{array}\right) =
\left(\begin{array}{c}x_1 + x_2 \\ y_1 + y_2\\ z_1 + z_2 \end{array}\right)

Vector3クラスでは2つのベクトルの和を求めるaddメソッドとaddVectorsメソッドが存在しています。

    add: function ( v, w ) {

        if ( w !== undefined ) {

            console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
            return this.addVectors( v, w );

        }

        this.x += v.x;
        this.y += v.y;
        this.z += v.z;

        return this;

    },

    addVectors: function ( a, b ) {

        this.x = a.x + b.x;
        this.y = a.y + b.y;
        this.z = a.z + b.z;

        return this;

    },

ベクトルとスカラーの和は数学的には定義されていませんが、Vector3にはベクトルの各要素にスカラー値を足すaddScalarメソッドとaddScaledVectorメソッドが利便性のために存在しています。

    addScalar: function ( s ) {

        this.x += s;
        this.y += s;
        this.z += s;

        return this;

    },

    addScaledVector: function ( v, s ) {

        this.x += v.x * s;
        this.y += v.y * s;
        this.z += v.z * s;

        return this;

    },

ベクトルの差

2つのベクトルの差は各要素同士の差になります。

\vec{v_1} - \vec{v_2} =
\left(\begin{array}{c}x_1 \\ y_1\\ z_1 \end{array}\right) -
\left(\begin{array}{c}x_2 \\ y_2\\ z_2 \end{array}\right) =
\left(\begin{array}{c}x_1 - x_2 \\ y_1 - y_2\\ z_1 - z_2 \end{array}\right)

Vector3には2つのベクトルの差を求めるsubメソッドとsubVectorsメソッドが存在しています。

    sub: function ( v, w ) {

        if ( w !== undefined ) {

            console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
            return this.subVectors( v, w );

        }

        this.x -= v.x;
        this.y -= v.y;
        this.z -= v.z;

        return this;

    },

    subVectors: function ( a, b ) {

        this.x = a.x - b.x;
        this.y = a.y - b.y;
        this.z = a.z - b.z;

        return this;

    },

和と同様にベクトルとスカラーの差は数学的に定義されていませんが、Vector3にはsubScalarメソッドが利便性のために存在しています。

    subScalar: function ( s ) {

        this.x -= s;
        this.y -= s;
        this.z -= s;

        return this;

    },

ベクトルの積

2つのベクトルの積はベクトルの各要素の積になります。

\vec{v_1}\vec{v_2} =
\left(\begin{array}{c}x_1 \\ y_1\\ z_1 \end{array}\right)
\left(\begin{array}{c}x_2 \\ y_2\\ z_2 \end{array}\right) =
\left(\begin{array}{c}x_1x_2 \\ y_1y_2\\ z_1z_2 \end{array}\right)

Vector3には2つのベクトルの積を求めるmultiplyメソッドと multiplyVectorsメソッドが存在しています。

    multiply: function ( v, w ) {

        if ( w !== undefined ) {

            console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
            return this.multiplyVectors( v, w );

        }

        this.x *= v.x;
        this.y *= v.y;
        this.z *= v.z;

        return this;

    },

    multiplyVectors: function ( a, b ) {

        this.x = a.x * b.x;
        this.y = a.y * b.y;
        this.z = a.z * b.z;

        return this;

    },

ベクトルとスカラーの積はベクトルの各要素にスカラーをかけることで求まります。

a\vec{v} =
a\left(\begin{array}{c}x \\ y\\ z \end{array}\right) =
\left(\begin{array}{c}ax \\ ay\\ az \end{array}\right)

Vector3にはベクトルとスカラーの積を求めるmultiplyScalarメソッドが存在しています。

    multiplyScalar: function ( scalar ) {

        this.x *= scalar;
        this.y *= scalar;
        this.z *= scalar;

        return this;

    },

ベクトルの商

2つのベクトルの商はベクトルの各要素の商になります。

\vec{v_1} / \vec{v_2} =
\left(\begin{array}{c}x_1 \\ y_1\\ z_1 \end{array}\right) / 
\left(\begin{array}{c}x_2 \\ y_2\\ z_2 \end{array}\right) =
\left(\begin{array}{c}x_1 / x_2 \\ y_1 / y_2\\ z_1 / z_2 \end{array}\right)

Vector3には2つのベクトルを商を求めるdivideメソッドが存在します。

    divide: function ( v ) {

        this.x /= v.x;
        this.y /= v.y;
        this.z /= v.z;

        return this;

    },

ベクトルとスカラーの商はベクトルの各要素をスカラーで割ることで求まります。

\vec{v} / a =
\left(\begin{array}{c}x \\ y\\ z \end{array}\right) / a =
\left(\begin{array}{c}x / a \\ y / a\\ z / a \end{array}\right)

Vector3にはベクトルとスカラーの商を求めるdivideScalarメソッドが存在します。

    divideScalar: function ( scalar ) {

        return this.multiplyScalar( 1 / scalar );

    },

逆ベクトル

ベクトル${\vec{v}}$に対して大きさが同じで向きが逆のベクトルを逆ベクトルと呼びます。逆ベクトルは以下のように$-1$を掛けることで求まります。

-\vec{v} = \left(\begin{array}{c}-x \\ -y\\ -z \end{array}\right)

Vector3ではnegateメソッドで逆ベクトルを求めることができます。

    negate: function () {

        this.x = - this.x;
        this.y = - this.y;
        this.z = - this.z;

        return this;

    },

ベクトルのドット積 (内積)

2つのベクトルのドット積は各要素同士の積の和になります。

\vec{v_1} \cdot \vec{v_2} =
\left(\begin{array}{c}x_1 \\ y_1\\ z_1 \end{array}\right) \cdot 
\left(\begin{array}{c}x_2 \\ y_2\\ z_2 \end{array}\right) =
x_1x_2 + y_1y_2 + z_1z_2

Vector3ではdotメソッドで求めることができます。

    dot: function ( v ) {

        return this.x * v.x + this.y * v.y + this.z * v.z;

    },

3次元ベクトルのクロス積 (外積)

3次元ベクトルのクロス積は以下の方法で求めることができます。
クロス積は3次元ベクトルのみで定義されており、2次元ベクトルや4次元ベクトルには存在ません。

\vec{v_1} \times \vec{v_2} =
\left(\begin{array}{c}x_1 \\ y_1\\ z_1 \end{array}\right) \times
\left(\begin{array}{c}x_2 \\ y_2\\ z_2 \end{array}\right) =
\left(\begin{array}{c}y_1z_2 - z_1y_2 \\ z_1x_2 - x_1z_2\\ x_1y_2 - y_1x_2 \end{array}\right)

Vector3にはクロス積を求めるcrossメソッドとcrossVectorsメソッドが存在しています。

    cross: function ( v, w ) {

        if ( w !== undefined ) {

            console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
            return this.crossVectors( v, w );

        }

        return this.crossVectors( this, v );

    },

    crossVectors: function ( a, b ) {

        var ax = a.x, ay = a.y, az = a.z;
        var bx = b.x, by = b.y, bz = b.z;

        this.x = ay * bz - az * by;
        this.y = az * bx - ax * bz;
        this.z = ax * by - ay * bx;

        return this;

    },

ベクトルの大きさ

ベクトル$\vec{v}$の大きさ$|\vec{v}|$は以下の式で求めることができます。

|\vec{v}| = \sqrt{xx + yy + zz}

Vector3ではlengthメソッドで求めることができます。
2つのベクトルの大きさを比較する場合などには平方根を計算する必要がないため、効率化のためにベクトルの大きさの2乗を返すlengthSqメソッドも存在しています。

    length: function () {

        return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );

    },

    lengthSq: function () {

        return this.x * this.x + this.y * this.y + this.z * this.z;

    },

ベクトルの正規化

ベクトルの向きを変更せずに大きさのみを$1$にすることをベクトルの正規化と呼びます。ベクトル$\vec{v}$を正規化したベクトル$\vec{v_{norm}}$は以下のように求めることができます。

\vec{v_{norm}} = \frac{\vec{v}}{|\vec{v}|} 

Vector3ではnormalizeメソッドで正規化を行うことができます。ゼロ除算が発生しないようにthis.length()0のときは1で割るようになっています。

    normalize: function () {

        return this.divideScalar( this.length() || 1 );

    },

2つのベクトルの距離

2つのベクトルの距離は2つのベクトルの差の大きさになります。

\vec{v_1} = \left(\begin{array}{c}x_1 \\ y_1\\ z_1 \end{array}\right),
\vec{v_2} = \left(\begin{array}{c}x_2 \\ y_2\\ z_2 \end{array}\right)\\
\vec{v'} = \vec{v_1} - \vec{v_2}\\
d = |\vec{v'}|

Vector3ではdistanceToメソッドで2つのベクトルの距離を求めることがあります。ベクトルの大きさと同様に平方根を取る必要がない場合があるので、2つのベクトルの距離の2乗を返すdistanceToSquaredも存在しています。

    distanceTo: function ( v ) {

        return Math.sqrt( this.distanceToSquared( v ) );

    },

    distanceToSquared: function ( v ) {

        var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;

        return dx * dx + dy * dy + dz * dz;

    },

2つのベクトルのなす角

ドット積の定義より2つのベクトルのなす角$\theta$は以下のように求めることができます。

\vec{v_1}\cdot\vec{v_2} = |\vec{v_1}||\vec{v_2}|cos\theta\\
\theta = acos(\frac{\vec{v_1}\cdot\vec{v_2}}{|\vec{v_1}||\vec{v_2}|})

Vector3ではangleToメソッドが対応しています。

    angleTo: function ( v ) {

        var denominator = Math.sqrt( this.lengthSq() * v.lengthSq() );

        if ( denominator === 0 ) console.error( 'THREE.Vector3: angleTo() can\'t handle zero length vectors.' );

        var theta = this.dot( v ) / denominator;

        // clamp, to handle numerical problems

        return Math.acos( _Math.clamp( theta, - 1, 1 ) );

    },

ベクトルの正射影

ベクトル$\vec{v_1}$をベクトル$\vec{v_2}$に正射影したベクトル$\vec{v_{proj}}$は以下のように求めることができあます。

\vec{v_{proj}} = \frac{\vec{v_1}\cdot\vec{v_2}}{|\vec{v_2}|}\vec{v_2}

またベクトル$\vec{v}$を法線ベクトル$\vec{n}$を持つ平面に対して正射影する場合には、$\vec{v}$を平面に平行な成分$\vec{v_{\parallel}}$と平面に垂直な成分$\vec{v_{\perp}}$に分けて考えます。まず、$\vec{v}$を$\vec{n}$に正射影することで$\vec{v_{\perp}}$を求め、その後$\vec{v}$から$\vec{v_{\perp}}$を引くことで$\vec{v_{\parallel}}$を求めることができます。

\vec{v} = \vec{v_{\parallel}} + \vec{v_{\perp}}\\
\vec{v_{\perp}} = \frac{\vec{v}\cdot\vec{n}}{|\vec{n}|}\vec{n}\\
\vec{v_{\parallel}} = \vec{v} - \vec{v_{\perp}} = \vec{v} - \frac{\vec{v}\cdot\vec{n}}{|\vec{n}|}\vec{n}

Vector3ではprojectOnVectorメソッドでベクトルへの正射影を、projectOnPlaneメソッドで平面への正射影を求めることができます。

    projectOnVector: function ( v ) {

        // v cannot be the zero v

        var scalar = v.dot( this ) / v.lengthSq();

        return this.copy( v ).multiplyScalar( scalar );

    },

    projectOnPlane: function ( planeNormal ) {

        _vector.copy( this ).projectOnVector( planeNormal );

        return this.sub( _vector );

    },

反射ベクトル

入射ベクトル$\vec{v}$、法線ベクトル$\vec{n}$としたときに反射ベクトル$\vec{r}$は以下のように求まります。

\vec{r} = \vec{v} - 2(\vec{v}\cdot\vec{n})\vec{n}

Vector3ではreflectメソッドで自身(this)を入射ベクトルにしたときの反射ベクトルを求めることができます。

    reflect: function ( normal ) {

        // reflect incident vector off plane orthogonal to normal
        // normal is assumed to have unit length

        return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );

    },

行列とベクトルの積

3x3行列と3次元列ベクトルの積は以下のようになります。

M\vec{v} =
\left(
    \begin{array}{ccc}
      e_{11} & e_{12} & e_{13} \\
      e_{21} & e_{22} & e_{23} \\
      e_{31} & e_{32} & e_{33}
    \end{array}
\right)
\left(\begin{array}{c}x \\ y\\ z \end{array}\right) =
\left(\begin{array}{c}
    e_{11}x + e_{12}y + e_{13}z\\
    e_{21}x + e_{22}y + e_{23}z\\
    e_{31}x + e_{32}y + e_{33}z \end{array}\right)

Three.jsではapplyMatrix3メソッドが定義されているほか、最後に正規化を行うtransformDirectionメソッドがあります。
Three.jsの行列は列オーダーなのでm.elementsには$[e_{11}, e_{21}, e_{31}, e_{12}, e_{22}, e_{32}, e_{13}, e_{23}, e_{33}]$という順番で要素が入っていることに注意してください。

    applyMatrix3: function ( m ) {

        var x = this.x, y = this.y, z = this.z;
        var e = m.elements;

        this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
        this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
        this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;

        return this;

    },

    transformDirection: function ( m ) {

        // input: THREE.Matrix4 affine matrix
        // vector interpreted as a direction

        var x = this.x, y = this.y, z = this.z;
        var e = m.elements;

        this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
        this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
        this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;

        return this.normalize();

    },

4x4行列と3次元ベクトルの積は数学的には定義できませんが、Three.jsには3次元ベクトルを同次座標系に拡張して4x4行列との積を求めるapplyMatrix4メソッドがあります。
具体的には引数として与えられた3次元ベクトルの$w$要素を$1$として4次元ベクトルに拡張して4x4行列との積(次式の$\vec{v'}$)を求めます。その後、各要素を$w$の値で割って3次元ベクトル(次式の$\vec{v''}$)に戻します。

\vec{v'} = \left(\begin{array}{c}x' \\ y'\\ z' \\w' \end{array}\right) = M\vec{v} =
\left(
    \begin{array}{ccc}
      e_{11} & e_{12} & e_{13} & e_{14} \\
      e_{21} & e_{22} & e_{23} & e_{24} \\
      e_{31} & e_{32} & e_{33} & e_{34} \\
      e_{41} & e_{42} & e_{43} & e_{44} \\
    \end{array}
\right)
\left(\begin{array}{c}x \\ y\\ z\\ 1 \end{array}\right) =
\left(\begin{array}{c}
    e_{11}x + e_{12}y + e_{13}z + e_{14}\\
    e_{21}x + e_{22}y + e_{23}z + e_{24}\\
    e_{31}x + e_{32}y + e_{33}z + e_{34}\\
    e_{41}x + e_{42}y + e_{43}z + e_{44} \end{array}\right)\\
\vec{v''} = \left(\begin{array}{c}x' / w' \\ y' / w' \\ z' / w' \end{array}\right)
    applyMatrix4: function ( m ) {

        var x = this.x, y = this.y, z = this.z;
        var e = m.elements;

        var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );

        this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w;
        this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w;
        this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w;

        return this;

    },

クォータニオンによるベクトルの回転

単位クォータニオンは3次元空間での回転を表すことができます。クォータニオン$\hat{q}$の逆クォータニオンを$\hat{q^{-1}}$とすると$\hat{q}$によるベクトル$\vec{v}$の回転は以下のように表すことができます。ベクトルを一度クォータニオンと見なして演算していることに注意してください。

\vec{v} = \left(\begin{array}{c}x \\ y\\ z \end{array}\right)\\
\hat{v} = (x, y, z, 0)\\
\hat{v'} = (x', y', z', 0) = \hat{q}\hat{v}\hat{q}^{-1}\\
\vec{v'} = \left(\begin{array}{c}x' \\ y'\\ z' \end{array}\right)

2つのクォータニオンの積は以下のようになります。

\hat{p} = (p_x, p_y, p_z, p_w)\\
\hat{q} = (q_x, q_y, q_z, q_w)\\
\hat{p}\hat{q} = \left(\begin{array}{c}
p_wq_x - p_zq_y + p_yq_z + p_xq_w,\\
p_zq_x + p_wq_y - p_xq_z + p_yq_w,\\
p_yq_x + p_xq_y + p_wq_z + p_zq_w,\\
-p_xq_x - p_yq_y - p_zq_z + p_wq_w
 \end{array}\right)

Vector3ではapplyQuaternionメソッドでクォータニオンによりベクトルを回転させることができます。applyEulerメソッドとapplyAxisAngleメソッドも内部的にはapplyQuaternionメソッドを使用しています。

    applyQuaternion: function ( q ) {

        var x = this.x, y = this.y, z = this.z;
        var qx = q.x, qy = q.y, qz = q.z, qw = q.w;

        // calculate quat * vector

        var ix = qw * x + qy * z - qz * y;
        var iy = qw * y + qz * x - qx * z;
        var iz = qw * z + qx * y - qy * x;
        var iw = - qx * x - qy * y - qz * z;

        // calculate result * inverse quat

        this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
        this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
        this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;

        return this;

    },

    applyEuler: function ( euler ) {

        if ( ! ( euler && euler.isEuler ) ) {

            console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );

        }

        return this.applyQuaternion( _quaternion.setFromEuler( euler ) );

    },

    applyAxisAngle: function ( axis, angle ) {

        return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) );

    },

球座標系からの直交座標系への変換

動径$r$と2つの偏角$\phi$、$\theta$で表された球座標を直交座標に変換するには以下のようにします。

\vec{v} = \left(\begin{array}{c}
rsin\phi sin\theta \\
rcos\phi \\
rsin\phi cos\theta \end{array}\right)

Vector3クラスではsetFromSphericalメソッドとsetFromSphericalCoordsメソッドで球座標から直交座標を求めることができます。

    setFromSpherical: function ( s ) {

        return this.setFromSphericalCoords( s.radius, s.phi, s.theta );

    },

    setFromSphericalCoords: function ( radius, phi, theta ) {

        var sinPhiRadius = Math.sin( phi ) * radius;

        this.x = sinPhiRadius * Math.sin( theta );
        this.y = Math.cos( phi ) * radius;
        this.z = sinPhiRadius * Math.cos( theta );

        return this;

    },

円柱座標系から直交座標系への変換

動径$r$、偏角$\theta$でy方向に延びる円柱座標を直交座標に変換するには以下のようにします。

\vec{v} = \left(\begin{array}{c}
rsin\theta \\
y \\
rcos\theta \end{array}\right)

Vector3ではsetFromCylindricalメソッドとsetFromCylindricalCoordsメソッドで円柱座標から直交座標を求めることができます。

    setFromCylindrical: function ( c ) {

        return this.setFromCylindricalCoords( c.radius, c.theta, c.y );

    },

    setFromCylindricalCoords: function ( radius, theta, y ) {

        this.x = radius * Math.sin( theta );
        this.y = y;
        this.z = radius * Math.cos( theta );

        return this;

    },

その他数学メソッド

Vector3では利便性のためにJavaScriptのMath内のメソッドをベクトルの各要素に適用するようなメソッドが存在しています。

    min: function ( v ) {

        this.x = Math.min( this.x, v.x );
        this.y = Math.min( this.y, v.y );
        this.z = Math.min( this.z, v.z );

        return this;

    },

    max: function ( v ) {

        this.x = Math.max( this.x, v.x );
        this.y = Math.max( this.y, v.y );
        this.z = Math.max( this.z, v.z );

        return this;

    },

    floor: function () {

        this.x = Math.floor( this.x );
        this.y = Math.floor( this.y );
        this.z = Math.floor( this.z );

        return this;

    },

    ceil: function () {

        this.x = Math.ceil( this.x );
        this.y = Math.ceil( this.y );
        this.z = Math.ceil( this.z );

        return this;

    },

    round: function () {

        this.x = Math.round( this.x );
        this.y = Math.round( this.y );
        this.z = Math.round( this.z );

        return this;

    },

    roundToZero: function () {

        this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
        this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
        this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );

        return this;

    },

終わりに

ベクトル演算についてまとめながら、three.jsのVector3クラスを見てきました。Vector3クラスの一部のメソッドには今回は触れていません。個人的にはすべてのメソッドがインスタンスメソッドとして定義されており、クラスメソッドがないのが特徴的に感じました。

32
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
27