物体との衝突

物体との衝突


動いている物体が固定された物体と衝突する時、入射角と反射角とは等しくなる
col1.jpg

座標軸に平行な場合のベクトル反射


動く物体の入射ベクトルを[ vix , viy ]として、
固定された物体の境界線が鉛直の場合、vf = [ -vix , viy ]になる
固定された物体の境界線が水平の場合、vf = [ vix , -viy ]になる
(水平に衝突の場合、鉛直成分の符号を逆に。鉛直に衝突の場合、水平成分の符号を逆にしてるだけ)

例.
入射ベクトル[ 4 , 5 ]が鉛直の固定された物体に衝突した場合のベクトル反射は[ -4 , 5]になる


座標軸に平行な場合とそうでない場合のベクトル反射


座標に対して平行でない固定物体の場合、その境界線に対する法線をまず求める必要がある

ある2次元ベクトルに対しての垂直な直線の傾き(法線)を求めるには、ベクトルに対し符号が反対になった逆数を求めればよい
境界線のベクトルが[ Δx Δy ]であった場合、法線の傾きは[ Δy -Δx ]になる

<法線を求めるコード>

using UnityEngine;
using System.Collections;

public class refrectVector : MonoBehaviour {

  Vector3 vec1,refVec1;

  void Start () {
       vec1 = new Vector3(2,6);
       refVec1.x = -vec1.y;
       refVec1.y = vec1.x;
   }
   
   void Update () {
       Debug.DrawLine(Vector3.zero,vec1);
       Debug.DrawLine(Vector3.zero,refVec1);
   }
}

refvector1.jpg

次に求めた法線を下準備として正規化する。この法線に対しviのベクトルを投影した軸Pベクトルを得る P=(-vi・N')×N'
(viは進入ベクトル、N'は正規化した法線)

次に vf = 2×P+vi を求める
これにより投影された軸Pを基準に左右反転したベクトルvf(結果的に反射されたベクトル)を求める事が出来る

<図解>
refrect2.jpg

<ベクトル反射を求めるコード>

using UnityEngine;
using System.Collections;

public class RefVector2 : MonoBehaviour {

  Vector3 baseCol,minusVi,vf,n,vectorP;

  void Start () {
       baseCol=new Vector3(5,2);
       minusVi = new Vector3(-5,3);

      n = new Vector3(-baseCol.y,baseCol.x);    //baseColに対する法線
       Vector3 nDush =  n / Mathf.Sqrt( n.x * n.x + n.y * n.y);    //正規化 → N'
       float minusViDotNorm = minusVi.x * nDush.x + minusVi.y * nDush.y;    //-vi・N'
       vectorP = minusViDotNorm * nDush;    //(-vi・N')×N' 
       vf = 2 * vectorP + (-minusVi);        //vf = 2×P+vi
   }
   
   void Update () {
       Debug.DrawLine(Vector3.zero,baseCol);
       Debug.DrawLine(Vector3.zero,minusVi,Color.green);
       Debug.DrawLine(Vector3.zero,vectorP,Color.blue);
       Debug.DrawLine(Vector3.zero,vf,Color.red);
   }
}

refrect1.jpg

unityには標準で反射ベクトルを得る機能を持った関数が用意されている

using UnityEngine;
using System.Collections;

public class RefVector3 : MonoBehaviour {

  Vector3 baseCol,minusVi,vf,n;
   
   void Start () {
       baseCol=new Vector3(5,2);
       minusVi = new Vector3(-5,3);

      n = new Vector3(-baseCol.y,baseCol.x).normalized;    //baseColに対する正規化された法線
       vf = Vector3.Reflect(-minusVi,n);            //unityの標準関数。第二引数は正規化の必要がある
   }
   
   void Update () {
       Debug.DrawLine(Vector3.zero,baseCol);
       Debug.DrawLine(Vector3.zero,minusVi,Color.green);
       Debug.DrawLine(Vector3.zero,n,Color.blue);
       Debug.DrawLine(Vector3.zero,vf,Color.red);
   }
}


  • 最終更新:2013-12-30 17:58:15

このWIKIを編集するにはパスワード入力が必要です

認証パスワード