断断续续的分析了很长一段时间终于如愿以偿,自己完成了基于3D矢量和3D矩阵的3D空间的转换代码:坐标由父空间转换到子空间以及由子空间转换到父空间
一个应用就是将一个顶点坐标由世界坐标系转换到摄像机的观察坐标系,或者将摄像机观察坐标系中的一个坐标转换到世界坐标系中
转换类的代码如下(说明一点,这个类中的Vector_3D和Matrix_3D的运作原理和常见的绝大多数3D引擎的3D矢量及3D矩阵的基本实现是一样的):
Code
//SpaceTransition
package public3D.vily.core.utils.trans
{
//public3D.vily.core.utils.trans.SpaceTransition
/**
实现3D空间中的坐标在父坐标系和对应的子坐标系见间转换(是直接的"父"包含"子"关系)
*/
import public3D.vily.core.math.Matrix_3D;
import public3D.vily.primitives.Vector_3D;
public class SpaceTransition
{
//临时矢量
private var temp_v3:Vector_3D = null;
private var m3:Matrix_3D = null;
private var inverseM3:Matrix_3D = null;
//临时矢量
private var v_x_3D:Vector_3D = null;
private var v_y_3D:Vector_3D = null;
private var v_z_3D:Vector_3D = null;
public function SpaceTransition()
{
init();
}
private function init():void{
m3 = new Matrix_3D();
inverseM3 = new Matrix_3D();
v_x_3D = new Vector_3D();
v_y_3D = new Vector_3D();
v_z_3D = new Vector_3D();
}
/**
父空间到子空间的坐标转换: parent sapce -> sub space
@param pV 父空间中的坐标的矢量表示
@param sSCoorNXV 在此父空间中的自空间的坐标空间x轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSCoorNYV 在此父空间中的自空间的坐标空间y轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSCoorNZV 在此父空间中的自空间的坐标空间z轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSPV 子空间的坐标原点位于父空间中的坐标的矢量表示
*/
public function pSToSS(pV:Vector_3D, sSCoorNXV:Vector_3D, sSCoorNYV:Vector_3D,sSCoorNZV:Vector_3D,sSPV:Vector_3D):Vector_3D{
//trace("init A: "+ pV);
var v_3D:Vector_3D = new Vector_3D();
//平移
temp_v3 = pV.minusNew(sSPV);
//旋转
v_3D.x = temp_v3.dot(sSCoorNXV);
v_3D.y = temp_v3.dot(sSCoorNYV);
v_3D.z = temp_v3.dot(sSCoorNZV);
//test
//sSCToPS(v_3D, sSCoorNXV, sSCoorNYV,sSCoorNZV,sSPV);
return v_3D;
}
/**
子空间到父空间的坐标转换
@param v 准备转换到父空间坐标系的子空间坐标的矢量表示
@param sSCoorNXV 在此父空间中的自空间的坐标空间x轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSCoorNYV 在此父空间中的自空间的坐标空间y轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSCoorNZV 在此父空间中的自空间的坐标空间z轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSPV 子空间的坐标原点位于父空间中的坐标的矢量表示
*/
public function sSCToPS(pV:Vector_3D, sSCoorNXV:Vector_3D, sSCoorNYV:Vector_3D,sSCoorNZV:Vector_3D, sSPV:Vector_3D):Vector_3D{
//创建子坐标空间的矩阵
m3.sxx = sSCoorNXV.x, m3.sxy = sSCoorNXV.y, m3.sxz = sSCoorNXV.z;
m3.syx = sSCoorNYV.x, m3.syy = sSCoorNYV.y, m3.syz = sSCoorNYV.z;
m3.szx = sSCoorNZV.x, m3.szy = sSCoorNZV.y, m3.szz = sSCoorNZV.z;
//取得矩阵m3的逆
inverseM3.inverse(m3);
v_x_3D.x = inverseM3.sxx, v_x_3D.y = inverseM3.sxy, v_x_3D.z = inverseM3.sxz;
v_y_3D.x = inverseM3.syx, v_y_3D.y = inverseM3.syy, v_y_3D.z = inverseM3.syz;
v_z_3D.x = inverseM3.szx, v_z_3D.y = inverseM3.szy, v_z_3D.z = inverseM3.szz;
var v_3D:Vector_3D = new Vector_3D();
temp_v3 = pV.clone();
//将子坐标空间内的v_3D变换到世界坐标系
//通过逆矩阵变换
v_3D.x = temp_v3.dot(v_x_3D);
v_3D.y = temp_v3.dot(v_y_3D);
v_3D.z = temp_v3.dot(v_z_3D);
//平移
v_3D = v_3D.plusNew(sSPV);
//trace("init B: "+ v_3D);
return v_3D;
}
}
}
//SpaceTransition
package public3D.vily.core.utils.trans
{
//public3D.vily.core.utils.trans.SpaceTransition
/**
实现3D空间中的坐标在父坐标系和对应的子坐标系见间转换(是直接的"父"包含"子"关系)
*/
import public3D.vily.core.math.Matrix_3D;
import public3D.vily.primitives.Vector_3D;
public class SpaceTransition
{
//临时矢量
private var temp_v3:Vector_3D = null;
private var m3:Matrix_3D = null;
private var inverseM3:Matrix_3D = null;
//临时矢量
private var v_x_3D:Vector_3D = null;
private var v_y_3D:Vector_3D = null;
private var v_z_3D:Vector_3D = null;
public function SpaceTransition()
{
init();
}
private function init():void{
m3 = new Matrix_3D();
inverseM3 = new Matrix_3D();
v_x_3D = new Vector_3D();
v_y_3D = new Vector_3D();
v_z_3D = new Vector_3D();
}
/**
父空间到子空间的坐标转换: parent sapce -> sub space
@param pV 父空间中的坐标的矢量表示
@param sSCoorNXV 在此父空间中的自空间的坐标空间x轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSCoorNYV 在此父空间中的自空间的坐标空间y轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSCoorNZV 在此父空间中的自空间的坐标空间z轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSPV 子空间的坐标原点位于父空间中的坐标的矢量表示
*/
public function pSToSS(pV:Vector_3D, sSCoorNXV:Vector_3D, sSCoorNYV:Vector_3D,sSCoorNZV:Vector_3D,sSPV:Vector_3D):Vector_3D{
//trace("init A: "+ pV);
var v_3D:Vector_3D = new Vector_3D();
//平移
temp_v3 = pV.minusNew(sSPV);
//旋转
v_3D.x = temp_v3.dot(sSCoorNXV);
v_3D.y = temp_v3.dot(sSCoorNYV);
v_3D.z = temp_v3.dot(sSCoorNZV);
//test
//sSCToPS(v_3D, sSCoorNXV, sSCoorNYV,sSCoorNZV,sSPV);
return v_3D;
}
/**
子空间到父空间的坐标转换
@param v 准备转换到父空间坐标系的子空间坐标的矢量表示
@param sSCoorNXV 在此父空间中的自空间的坐标空间x轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSCoorNYV 在此父空间中的自空间的坐标空间y轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSCoorNZV 在此父空间中的自空间的坐标空间z轴的单位失量表示,这个矢量是位于此父空间的矢量
@param sSPV 子空间的坐标原点位于父空间中的坐标的矢量表示
*/
public function sSCToPS(pV:Vector_3D, sSCoorNXV:Vector_3D, sSCoorNYV:Vector_3D,sSCoorNZV:Vector_3D, sSPV:Vector_3D):Vector_3D{
//创建子坐标空间的矩阵
m3.sxx = sSCoorNXV.x, m3.sxy = sSCoorNXV.y, m3.sxz = sSCoorNXV.z;
m3.syx = sSCoorNYV.x, m3.syy = sSCoorNYV.y, m3.syz = sSCoorNYV.z;
m3.szx = sSCoorNZV.x, m3.szy = sSCoorNZV.y, m3.szz = sSCoorNZV.z;
//取得矩阵m3的逆
inverseM3.inverse(m3);
v_x_3D.x = inverseM3.sxx, v_x_3D.y = inverseM3.sxy, v_x_3D.z = inverseM3.sxz;
v_y_3D.x = inverseM3.syx, v_y_3D.y = inverseM3.syy, v_y_3D.z = inverseM3.syz;
v_z_3D.x = inverseM3.szx, v_z_3D.y = inverseM3.szy, v_z_3D.z = inverseM3.szz;
var v_3D:Vector_3D = new Vector_3D();
temp_v3 = pV.clone();
//将子坐标空间内的v_3D变换到世界坐标系
//通过逆矩阵变换
v_3D.x = temp_v3.dot(v_x_3D);
v_3D.y = temp_v3.dot(v_y_3D);
v_3D.z = temp_v3.dot(v_z_3D);
//平移
v_3D = v_3D.plusNew(sSPV);
//trace("init B: "+ v_3D);
return v_3D;
}
}
}