Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

今製作中のもので、丸影を地面に添わせて地面の法線方向に向かせる、というのをやりたかった。
法線自体はすぐに取れたのだけど、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を使うとクォータニオンとかその他もろもろのめんどくさい計算をやってくれるクラスがあるので、これくらいの行数で簡単にできちゃいます。

edo_m18
現在はUnity ARエンジニア。 主にARのコンテンツ制作をしています。 最近は機械学習にも興味が出て勉強中です。 Unityに関するブログは別で書いています↓ https://edom18.hateblo.jp/
http://edom18.hateblo.jp/
unity-game-dev-guild
趣味・仕事問わずUnityでゲームを作っている開発者のみで構成されるオンラインコミュニティです。Unityでゲームを開発・運用するにあたって必要なあらゆる知見を共有することを目的とします。
https://unity-game-dev-guild.github.io/
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした