14
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Spline曲線に沿ってカードを動かす

Last updated at Posted at 2021-09-08

See the Pen Frame Graphic with Spline path by iizuka (@112KA) on CodePen.

↑3D空間上のSpline曲線に沿ってオブジェクトを動かすというのを実装する機会があったので、記事化しておく。

See the Pen Spline path by iizuka (@112KA) on CodePen.

1スプライン1カードのサンプルはこれ↑
白線 - Spline曲線
緑点 - Spline分割点
緑線 - Splineの外向きベクトル

実装手順

1. Spline曲線を分割

THREE.CatmullRomCurve3では、getPointsで分割してくれる
サンプルでは25分割している

let curve = new THREE.CatmullRomCurve3([...])
this.points = curve.getPoints(N_DIVIDE);

2. 各分割点で、外向きベクトルを算出

下図、点Bでの外向きベクトルを求めるために、線分ABと線分CBを足してnormalizeしている
img1.jpg

3. 各分割点で、外向きベクターの方向に回転するためのQuaternionを算出

山場の実装。
参考にしたのはこのページ
方向をあわせる回転角度が時計回りかどうかを求める必要があったのがわからなくて、そこでほまって時間かかった。

カード(ローカルオブジェクト)のベクトル

姿勢を合わせるためのカードの法線(0,0,1)と進行方向(0,1,0)

let cardNormal = new THREE.Vector3(0, 0, 1)
  , cardDirection = new THREE.Vector3(0, 1, 0)

姿勢合わせ回転

verticalVector = cardNormal.clone().cross(pB.outward)  //カード面の法線と点Bの外向きベクトルに垂直なベクトル
verticalVector.normalize()
radians = Math.acos(cardNormal.dot(pB.outward))  //回転角度

attitudeQuaternion.setFromAxisAngle(verticalVector, radians)

方向合わせ回転

//点Bの外向きベクトルをカード平面に射影
//参考) http://www.thothchildren.com/chapter/5b670e772787593b86356103
pB.targetDirection = lineBC.clone()
pB.targetDirection.sub(pB.outward.clone().multiplyScalar(pB.outward.dot(lineBC)))
pB.targetDirection.normalize()
let localDirection = cardDirection.clone()

localDirection.applyQuaternion(attitudeQuaternion)

radians = Math.acos(pB.targetDirection.dot(localDirection))  //回転角度
      
//このときの回転角度が時計回りかどうかを調べる
localDirection.cross(pB.targetDirection);
let code = localDirection.dot(pB.outward) > 0 ? 1 : -1;

//点Bの外向きベクトルを軸に回転
directionQuaternion.setFromAxisAngle(pB.outward, code*radians)

姿勢と方向、それぞれのQuaternionを1つのQuaternionに合成

pB.quaternion = new THREE.Quaternion()
pB.quaternion.multiply(directionQuaternion)
pB.quaternion.multiply(attitudeQuaternion)

4. 各分割点の”位置”、”Quaternion”の補間値を移動させたいオブジェクトに設定する

  • THREE.Vector3のlerpVectors
  • THREE.QuaternionのslerpQuaternions

で、”位置”、”Quaternion”をそれぞれ補間してくれるので、それをカードオブジェクトのmatrixに設定する

終わり!

参考

14
18
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
14
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?