一个描述三维空间最基本的类,掌握这个类的原理和用法将能使你在构造3D模型中游刃有余
- package {
- public class Vertor3d {
- //定义三维空间的点[x,y,z]
- public var x:Number=0;
- public var y:Number=0;
- public var z:Number=0;
- /**
- * 构造函数
- * @param dx 代表三维空间x轴上的点
- * @param dy 代表三维空间y轴上的点
- * @param dz 代表三维空间z轴上的点
- */
- function Vertor3d(dx:Number, dy:Number, dz:Number) {
- x = dx;
- y = dy;
- z = dz;
- }
- /**
- * 将类实例对象绕x轴旋转
- * @param angle 一个以度表示的角度(不是弧度)
- */
- public function rotateX(angle:Number) {
- var ca:Number = acosD(angle);
- var sa:Number = asinD(angle);
- var tempY:Number = y*ca-z*sa;
- var tempZ:Number = y*sa+z*ca;
- y = tempY;
- z = tempZ;
- }
- /**
- * 将类实例对象绕x轴旋转
- * @param ca 一个角度的余弦值
- * @param sa 一个角度的正弦值
- * 这个方法和rotateX的方法的作用是一样的,是为了提高效率而设置的
- */
- public function rotateXTrig(ca:Number, sa:Number) {
- var tempY:Number = y*ca+z*sa;
- var tempZ:Number = y*sa+z*ca;
- y = tempY;
- z = tempZ;
- }
- /**
- * 将类实例对象绕Y轴旋转
- * @param angle 一个以度表示的角度(不是弧度)
- */
- public function rotateY(angle:Number) {
- var ca:Number = acosD(angle);
- var sa:Number = asinD(angle);
- var tempX:Number = x*ca+z*sa;
- var tempZ:Number = x*-sa+z*ca;
- x = tempX;
- z = tempZ;
- }
- /**
- * 将类实例对象绕Y轴旋转
- * @param ca 一个角度的余弦值
- * @param sa 一个角度的正弦值
- * 这个方法和rotateY的方法的作用是一样的,是为了提高效率而设置的
- */
- public function rotateYTrig(ca:Number, sa:Number) {
- var tempX:Number = x*ca+z*sa;
- var tempZ:Number = x*-sa+z*ca;
- x = tempX;
- z = tempZ;
- }
- /**
- * 将类实例对象绕Z轴旋转
- * @param angle 一个以度表示的角度(不是弧度)
- */
- public function rotateZ(angle:Number) {
- var ca:Number = acosD(angle);
- var sa:Number = asinD(angle);
- var tempX:Number = x*ca+y*sa;
- var tempY:Number = x*-sa+y*ca;
- x = tempX;
- y = tempY;
- }
- /**
- * 将类实例对象绕Z轴旋转
- * @param ca 一个角度的余弦值
- * @param sa 一个角度的正弦值
- * 这个方法和rotateZ的方法的作用是一样的,是为了提高效率而设置的
- */
- public function rotateZTrig(ca:Number, sa:Number) {
- var tempX:Number = x*ca+y*sa;
- var tempY:Number = x*sa+y*ca;
- x = tempX;
- y = tempY;
- }
- /**
- * 将类实例对象同时绕X轴和Y轴旋转
- * @param angleX 绕X轴旋转的角度(一个以度表示的角度,不是弧度)
- * @param angleY 绕Y轴旋转的角度(一个以度表示的角度,不是弧度)
- */
- public function rotateXY(angleX:Number, angleY:Number) {
- var ca:Number = acosD(angleX);
- var sa:Number = asinD(angleX);
- var cb:Number = acosD(angleY);
- var sb:Number = asinD(angleY);
- var rz:Number = y*sa+z*ca;
- y = y*ca-z*sa;
- z = x*-sb+rz*cb;
- x = x*cb+rz*sb;
- }
- /**
- * 将类实例对象同时绕X轴和Y轴旋转
- * @param ca 绕X轴旋转角度的余弦值
- * @param sa 绕X轴旋转角度的正弦值
- * @param cb 绕Y轴旋转角度的余弦值
- * @param sb 绕Y轴旋转角度的正弦值
- */
- public function rotateXYTrig(ca:Number, sa:Number, cb:Number, sb:Number) {
- var rz:Number = y*sa+z*ca;
- y = y*ca-z*sa;
- z = x*-sb+rz*cb;
- x = x*cb+rz*sb;
- }
- /**
- * 将类实例对象同时绕X轴,Y轴和Z轴旋转
- * @param angleX 绕X轴旋转的角度(一个以度表示的角度,不是弧度)
- * @param angleY 绕Y轴旋转的角度(一个以度表示的角度,不是弧度)
- * @param angleZ 绕Z轴旋转的角度(一个以度表示的角度,不是弧度)
- */
- public function rotateXYZ(angleX:Number, angleY:Number,angleZ:Number) {
- rotateX(angleX);
- rotateY(angleY);
- rotateZ(angleZ);
- }
- /**
- * 将类实例对象同时绕X轴,Y轴和Z轴旋转
- * @param ca 绕X轴旋转角度的余弦值
- * @param sa 绕X轴旋转角度的正弦值
- * @param cb 绕Y轴旋转角度的余弦值
- * @param sb 绕Y轴旋转角度的正弦值
- * @param cc 绕Z轴旋转角度的余弦值
- * @param sc 绕Z轴旋转角度的正弦值
- */
- public function rotateXYZTrig(ca:Number, sa:Number, cb:Number, sb:Number, cc:Number, sc:Number) {
- var ry:Number = y*ca-z*sa;
- var rz:Number = y*sa+z*ca;
- var rx:Number = x*cb+rz*sb;
- z = x*-sb+rz*cb;
- x = rx*cc-ry*sc;
- y = rx*sc+ry*cc;
- }
- /**
- * 重新设置点属性
- * @param dx 代表三维空间x轴上的点
- * @paramdy:代表三维空间y轴上的点
- * @paramdz:代表三维空间z轴上的点
- */
- public function reset(dx:Number, dy:Number, dz:Number) {
- this.x = dx;
- this.y = dy;
- this.z = dz;
- }
- /**
- * 复制类自身并返回一个新类
- * @return Vertor3d类实例对象
- */
- public function getClone():Vertor3d {
- return new Vertor3d(x,y,z);
- }
- /**
- * 比较两个Vertor3d类实例对象属性是否相等,即两个点是否处于三维空间的同一个位置
- * @param obj Vertor3d类实例对象
- * @return Boolean
- */
- public function equals(obj:Vertor3d):Boolean {
- return (x == obj.x && y == obj.y && z == obj.z);
- }
- /**
- * 将类对象实例属性与另一个Vertor3d类实例对象属性相加(即x,y,z属性值)并返回新的类对象实例属性
- * @param obj Vertor3d类实例对象
- */
- public function plus(obj:Vertor3d) {
- x += obj.x;
- y += obj.y;
- z += obj.z;
- }
- /**
- * 将类对象实例属性与另一个Vertor3d类实例对象属性相加(即x,y,z属性值)并返回一个新的Vertor3d类实例对象(不改变原类对象实例)
- * @param obj Vertor3d类实例对象
- * @return Vertor3d类实例对象
- */
- public function plusNew(obj:Vertor3d):Vertor3d {
- return new Vertor3d(x + obj.x,y + obj.y,z + obj.z);
- }
- /**
- * 将类对象实例属性与另一个Vertor3d类实例对象属性相减(即x,y,z属性值)并返回新的类对象实例属性
- * @param obj Vertor3d类实例对象
- */
- public function minus(obj:Vertor3d) {
- x -= obj.x;
- y -= obj.y;
- z -= obj.z;
- }
- /**
- * 将类对象实例属性与另一个Vertor3d类实例对象属性相减(即x,y,z属性值)并返回一个新的Vertor3d类实例对象(不改变原类对象实例)
- * @param obj Vertor3d类实例对象
- * @return Vertor3d类实例对象
- */
- public function minusNew(obj:Vertor3d):Vertor3d {
- return new Vertor3d(x - obj.x,y - obj.y,z - obj.z);
- }
- /**
- * 将类实例对象绕原点旋转180度
- */
- public function negate() {
- x = -x;
- y = -y;
- z = -z;
- }
- /**
- * 返回一个与类实例对象通过原点对称的新的Vertor3d类实例对象(不改变原类对象实例)
- * @return Vertor3d类实例对象
- */
- public function negateNew():Vertor3d {
- return new Vertor3d(- x,- y,- z);
- }
- /**
- * 将类对象实例属性进行等比例缩放(即x,y,z属性值)并返回新的类对象实例属性
- * @param quo 缩放比例
- */
- public function scale(quo:Number) {
- x *= quo;
- y *= quo;
- z *= quo;
- }
- /**
- * 将类对象实例属性进行等比例缩放(即x,y,z属性值)并返回新的Vertor3d类实例对象(不改变原类对象实例)
- * @param quo 缩放比例
- * @return Vertor3d类实例对象
- */
- public function scaleNew(quo:Number):Vertor3d {
- return new Vertor3d(x * quo,y * quo,z * quo);
- }
- /**
- * 返回类对象实例与原点的距离
- * @return Number
- */
- public function getLength():Number {
- return Math.sqrt(x * x + y * y + z * z);
- }
- /**
- * 重新设置类对象实例与原点的距离
- * @param len Number(len越大距离越大)
- */
- public function setLength(len:Number) {
- var r:Number = getLength();
- //如果r不为零
- if (r!=0) {
- scale(len/r);
- } else {
- x=len;
- }
- /**
- * 返回两个Vertor3d对象实例的点积
- * @param obj Vertor3d类实例对象
- * @return Number
- */
- }
- public function dot(obj:Vertor3d):Number {
- return x * obj.x + y * obj.y + z * obj.z;
- }
- /**
- * 返回两个Vertor3d对象实例的叉积并返回新的Vertor3d对象实例
- * @param obj Vertor3d类实例对象
- * @return Vertor3d类实例对象
- */
- public function cross(obj:Vertor3d) {
- var cx:Number = y*obj.z-z*obj.y;
- var cy:Number = z*obj.x-x*obj.z;
- var cz:Number = x*obj.y-y*obj.x;
- return new Vertor3d(cx,cy,cz);
- }
- /**
- * 计算两个Vertor3d对象实例之间形成的夹角
- * @param obj Vertor3d类实例对象
- * @return 一个角度(Number)
- */
- public function angleBetween(obj:Vertor3d) {
- var dp:Number = dot(obj);
- var cosAngle:Number = dp/(getLength()*obj.getLength());
- return acosD(cosAngle);
- }
- /**
- * 计算一个物体缩放所需的透视比例
- * @param viewDist 默认值300(viewDist值越小产生的透视效果越好)
- * @return 透视值(Number)
- */
- public function getPerspective(viewDist:Number):Number {
- viewDist is Number ? 0: viewDist=300;
- if (z + viewDist<0) {
- return viewDist;
- }
- return viewDist /(z + viewDist);
- }
- /**
- * 产生类实例对象的透视投影点
- * @param p 透视比例值
- */
- public function persProject(p:Number) {
- if (!p is Number) {
- p = getPerspective(NaN);
- }
- x *=p
- y *=p;
- z *=p;
- }
- /**
- * 将类实例对象的透视投影点作为新的Vertor3d类实例对象返回
- * @param p 透视比例值
- * @return Vertor3d类实例对象
- */
- public function persProjectNew(p:Number):Vertor3d {
- if (!p is Number) {
- p = getPerspective(NaN);
- }
- return new Vertor3d(p * x,p * y,0);
- }
- //重载从object继承的方法toString*/
- public function toString():String {
- var x:Number = Math.round(this.x*10000)/1000;
- var y:Number = Math.round(this.y*10000)/1000;
- var z:Number = Math.round(this.z*10000)/1000;
- return "[" + x + ":" + y + ":" + z + "]";
- }
- /**
- * 私有方法分别计算一个弧度的正弦对应的角度和余弦对象的角度
- * @param radian 一个弧度值
- */
- public function acosD(radian:Number):Number {
- return Math.cos(radian * Math.PI / 180);
- }
- public function asinD(radian:Number):Number {
- return Math.sin(radian * Math.PI / 180);
- }
- }
- }