Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
35
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@edo_m18

[Three.js] クォータニオンを使って任意の方向にオブジェクトを向ける

今製作中のもので、丸影を地面に添わせて地面の法線方向に向かせる、というのをやりたかった。
法線自体はすぐに取れたのだけど、Planeをどうやってその法線方向に向かせるか、というのをこちらの記事を参考にして作ってみた。

テスト用に法線方向とオブジェクトの方向をテストするものを作ったので、それをベースにメモを残しておく。

サンプル

tfJW.jpg
http://jsdo.it/edo_m18/tfJW

サンプルはこんな感じで、頭を任意のベクトルに沿わせる、というもの。
x, y, zの軸の位置のスライダーをいじるとそれに応じてオブジェクトが回転します。

フロー

先にフローを書くと、

  1. 向かせたいベクトルと「上」方向のベクトルを取得
  2. 上記2つのベクトルとの外積を取る(これが回転軸となる)
  3. 上記2つのベクトルの角度を、内積を使って取得
  4. これら情報を元に、回転用のクォータニオンを生成
  5. 生成したクォータニオンをオブジェクトに適用

という流れ。
「上」と書いたのは必ずしも空方向ではなく、オブジェクトの「上」となるベクトル。
Three.jsを用いたサンプルコードを抜粋すると以下になる。

サンプルコード

Threejs-sample.js
//「上」方向のベクトルを生成。サンプルでは「空」方向。
var up = new THREE.Vector3(0, 1, 0);

//法線ベクトルを取得。サンプルではinput要素から取得。
var normalAxis = new THREE.Vector3(+xInp.value, +yInp.value, +zInp.value).normalize();

//回転軸用のベクトルを生成
var dir = new THREE.Vector3();

//「上」方向と法線ベクトルとの外積を計算。正規化。
dir.crossVectors(up, normalAxis).normalize();

//上記ベクトルとの内積(cosθ)
var dot = up.dot(normalAxis);// / (up.length() * normalAxis.length());

//acos関数を使ってラジアンに変換。
var rad = Math.acos(dot);

//クォータニオンオブジェクトを生成
var q = new THREE.Quaternion();

//計算した回転軸と角度を元にクォータニオンをセットアップ
q.setFromAxisAngle(dir, rad);

//適用したいオブジェクトに回転を適用
mesh.rotation.setFromQuaternion(q);

Three.jsを使うとクォータニオンとかその他もろもろのめんどくさい計算をやってくれるクラスがあるので、これくらいの行数で簡単にできちゃいます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
35
Help us understand the problem. What are the problem?