ベクトルが正規化され他のベクトルと直交するようにします
normal
を正規化します
接線 ( tangent
) を正規化し、normal
に直交しているか確認します(つまり、間の角度は 90 度です)
関連項目: Normalize 関数
ベクトルが正規化され他のベクトルと直交するようにします
normal
を正規化します
接線 ( tangent
) を正規化し、normal
に直交しているか確認します
接線 ( binormal
) を正規化し、normal
と tangent
両方に直交しているか確認します
空間の位置は、通常標準的な XYZ 軸システムの座標で指定されています。しかしながら、
正規化(すなわち大きさを 1 としたもの)や直交(すなわち他と垂直)である場合、3 つのベクトルの軸として
解釈することができます。
自分で座標軸を作成するときに役に立ちます。例えば、単に XYZ 軸に沿ってというよりむしろ任意の方向でメッシュのスケールをしたい場合、
自身の座標系に頂点を変換することができ、
それら頂点の値をスケールした後、変換を元に戻します。このような場面は、多くの場合
他の2つの軸は無視するか等しく扱うかのどちらかで扱いながら 1 つの軸のみに沿って実行されます。
例えば、他の2つの軸に比例して縮小していく一方、引き伸ばし効果は、ひとつの軸を拡大してメッシュに適用することができます。
いったん最初の軸のベクトルが指定されるならば、
直交と正規化されているベクトルである限り他の2つのベクトルが何でも大きな問題ではありません。
OrthoNormalize は、最初のベクトルが正常であることを確認し、他の2つの軸の直交ベクトル、2つの正規化されたベクトルを
生成するのに使用することができます。
// Mesh "stretch" effect along a chosen axis. // The axis and amount of scaling. var stretchAxis: Vector3; var stretchFactor = 1.0; // MeshFilter component and arrays for the original and transformed vertices. private var mf: MeshFilter; private var origVerts: Vector3[]; private var newVerts: Vector3[]; // Our new basis vectors. private var basisA: Vector3; private var basisB: Vector3; private var basisC: Vector3; function Start() { // Get the Mesh Filter, then make a copy of the original vertices // and a new array to calculate the transformed vertices. mf = GetComponent.<MeshFilter>(); origVerts = mf.mesh.vertices; newVerts = new Vector3[origVerts.Length]; } function Update() { // BasisA is just the specified axis for stretching - the // other two are just arbitrary axes generated by OrthoNormalize. basisA = stretchAxis; Vector3.OrthoNormalize(basisA, basisB, basisC); // Copy the three new basis vectors into the rows of a matrix // (since it is actually a 4x4 matrix, the bottom right corner // should also be set to 1). var toNewSpace: Matrix4x4 = new Matrix4x4(); toNewSpace.SetRow(0, basisA); toNewSpace.SetRow(1, basisB); toNewSpace.SetRow(2, basisC); toNewSpace[3, 3] = 1.0; // The scale values are just the diagonal entries of the scale // matrix. The vertices should be stretched along the first axis // and squashed proportionally along the other two. var scale: Matrix4x4 = new Matrix4x4(); scale[0, 0] = stretchFactor; scale[1, 1] = 1.0 / stretchFactor; scale[2, 2] = 1.0 / stretchFactor; scale[3, 3] = 1.0; // The inverse of the first matrix transforms the vertices back to // the original XYZ coordinate space(transpose is the same as inverse // for an orthogonal matrix, which this is). var fromNewSpace: Matrix4x4 = toNewSpace.transpose; // The three matrices can now be combined into a single symmetric matrix. var trans: Matrix4x4 = toNewSpace * scale * fromNewSpace; // Transform each of the mesh's vertices by the symmetric matrix. for (var i = 0; i < origVerts.Length; i++) { newVerts[i] = trans.MultiplyPoint3x4(origVerts[i]); } // ...and finally, update the mesh with the new vertex array. mf.mesh.vertices = newVerts; }
using UnityEngine; using System.Collections;
public class ExampleClass : MonoBehaviour { public Vector3 stretchAxis; public float stretchFactor = 1.0F; private MeshFilter mf; private Vector3[] origVerts; private Vector3[] newVerts; private Vector3 basisA; private Vector3 basisB; private Vector3 basisC; void Start() { mf = GetComponent<MeshFilter>(); origVerts = mf.mesh.vertices; newVerts = new Vector3[origVerts.Length]; } void Update() { basisA = stretchAxis; Vector3.OrthoNormalize(ref basisA, ref basisB, ref basisC); Matrix4x4 toNewSpace = new Matrix4x4(); toNewSpace.SetRow(0, basisA); toNewSpace.SetRow(1, basisB); toNewSpace.SetRow(2, basisC); toNewSpace[3, 3] = 1.0F; Matrix4x4 scale = new Matrix4x4(); scale[0, 0] = stretchFactor; scale[1, 1] = 1.0F / stretchFactor; scale[2, 2] = 1.0F / stretchFactor; scale[3, 3] = 1.0F; Matrix4x4 fromNewSpace = toNewSpace.transpose; Matrix4x4 trans = toNewSpace * scale * fromNewSpace; int i = 0; while (i < origVerts.Length) { newVerts[i] = trans.MultiplyPoint3x4(origVerts[i]); i++; } mf.mesh.vertices = newVerts; } }
関連項目: Normalize 関数