Vertor3d类

 一个描述三维空间最基本的类,掌握这个类的原理和用法将能使你在构造3D模型中游刃有余
  1. package {
  2.   public class Vertor3d {
  3.   //定义三维空间的点[x,y,z]
  4.   public var x:Number=0;
  5.   public var y:Number=0;
  6.   public var z:Number=0;
  7.   /**
  8.   * 构造函数
  9.   * @param dx 代表三维空间x轴上的点
  10.   * @param dy 代表三维空间y轴上的点
  11.   * @param dz 代表三维空间z轴上的点
  12.   */
  13.   function Vertor3d(dx:Number, dy:Number, dz:Number) {
  14.     x = dx;
  15.     y = dy;
  16.     z = dz;
  17.   }
  18.   /**
  19.   * 将类实例对象绕x轴旋转
  20.   * @param angle 一个以度表示的角度(不是弧度)
  21.   */
  22.   public function rotateX(angle:Number) {
  23.     var ca:Number = acosD(angle);
  24.     var sa:Number = asinD(angle);
  25.     var tempY:Number = y*ca-z*sa;
  26.     var tempZ:Number = y*sa+z*ca;
  27.     y = tempY;
  28.     z = tempZ;
  29.   }
  30.   /**
  31.   * 将类实例对象绕x轴旋转
  32.   * @param ca 一个角度的余弦值
  33.   * @param sa 一个角度的正弦值
  34.   * 这个方法和rotateX的方法的作用是一样的,是为了提高效率而设置的
  35.   */
  36.   public function rotateXTrig(ca:Number, sa:Number) {
  37.     var tempY:Number = y*ca+z*sa;
  38.     var tempZ:Number = y*sa+z*ca;
  39.     y = tempY;
  40.     z = tempZ;
  41.   }
  42.   /**
  43.   * 将类实例对象绕Y轴旋转
  44.   * @param angle 一个以度表示的角度(不是弧度)
  45.   */
  46.   public function rotateY(angle:Number) {
  47.     var ca:Number = acosD(angle);
  48.     var sa:Number = asinD(angle);
  49.     var tempX:Number = x*ca+z*sa;
  50.     var tempZ:Number = x*-sa+z*ca;
  51.     x = tempX;
  52.     z = tempZ;
  53.   }
  54.   /**
  55.   * 将类实例对象绕Y轴旋转
  56.   * @param ca 一个角度的余弦值
  57.   * @param sa 一个角度的正弦值
  58.   * 这个方法和rotateY的方法的作用是一样的,是为了提高效率而设置的
  59.   */
  60.   public function rotateYTrig(ca:Number, sa:Number) {
  61.     var tempX:Number = x*ca+z*sa;
  62.     var tempZ:Number = x*-sa+z*ca;
  63.     x = tempX;
  64.     z = tempZ;
  65.   }
  66.   /**
  67.   * 将类实例对象绕Z轴旋转
  68.   * @param angle 一个以度表示的角度(不是弧度)
  69.   */
  70.   public function rotateZ(angle:Number) {
  71.     var ca:Number = acosD(angle);
  72.     var sa:Number = asinD(angle);
  73.     var tempX:Number = x*ca+y*sa;
  74.     var tempY:Number = x*-sa+y*ca;
  75.     x = tempX;
  76.     y = tempY;
  77.   }
  78.   /**
  79.   * 将类实例对象绕Z轴旋转
  80.   * @param ca 一个角度的余弦值
  81.   * @param sa 一个角度的正弦值
  82.   * 这个方法和rotateZ的方法的作用是一样的,是为了提高效率而设置的
  83.   */
  84.   public function rotateZTrig(ca:Number, sa:Number) {
  85.     var tempX:Number = x*ca+y*sa;
  86.     var tempY:Number = x*sa+y*ca;
  87.     x = tempX;
  88.     y = tempY;
  89.   }
  90.   /**
  91.   * 将类实例对象同时绕X轴和Y轴旋转
  92.   * @param angleX 绕X轴旋转的角度(一个以度表示的角度,不是弧度)
  93.   * @param angleY 绕Y轴旋转的角度(一个以度表示的角度,不是弧度)
  94.   */
  95.   public function rotateXY(angleX:Number, angleY:Number) {
  96.     var ca:Number = acosD(angleX);
  97.     var sa:Number = asinD(angleX);
  98.     var cb:Number = acosD(angleY);
  99.     var sb:Number = asinD(angleY);
  100.     var rz:Number = y*sa+z*ca;
  101.     y = y*ca-z*sa;
  102.     z = x*-sb+rz*cb;
  103.     x = x*cb+rz*sb;
  104.   }
  105.   /**
  106.    * 将类实例对象同时绕X轴和Y轴旋转
  107.    * @param ca 绕X轴旋转角度的余弦值
  108.    * @param sa 绕X轴旋转角度的正弦值
  109.    * @param cb  绕Y轴旋转角度的余弦值
  110.    * @param sb 绕Y轴旋转角度的正弦值
  111.    */
  112.   public function rotateXYTrig(ca:Number, sa:Number, cb:Number, sb:Number) {
  113.     var rz:Number = y*sa+z*ca;
  114.     y = y*ca-z*sa;
  115.     z = x*-sb+rz*cb;
  116.     x = x*cb+rz*sb;
  117.   }
  118.   /**
  119.   * 将类实例对象同时绕X轴,Y轴和Z轴旋转
  120.   * @param angleX 绕X轴旋转的角度(一个以度表示的角度,不是弧度)
  121.   * @param angleY 绕Y轴旋转的角度(一个以度表示的角度,不是弧度)
  122.   * @param angleZ 绕Z轴旋转的角度(一个以度表示的角度,不是弧度)
  123.   */
  124.   public function rotateXYZ(angleX:Number, angleY:Number,angleZ:Number) {
  125.     rotateX(angleX);
  126.     rotateY(angleY);
  127.     rotateZ(angleZ);
  128.   }
  129.   /**
  130.    * 将类实例对象同时绕X轴,Y轴和Z轴旋转
  131.    * @param ca 绕X轴旋转角度的余弦值
  132.    * @param sa 绕X轴旋转角度的正弦值
  133.    * @param cb  绕Y轴旋转角度的余弦值
  134.    * @param sb 绕Y轴旋转角度的正弦值
  135.    * @param cc 绕Z轴旋转角度的余弦值
  136.    * @param sc 绕Z轴旋转角度的正弦值
  137.    */
  138.   public function rotateXYZTrig(ca:Number, sa:Number, cb:Number, sb:Number, cc:Number, sc:Number) {
  139.     var ry:Number = y*ca-z*sa;
  140.     var rz:Number = y*sa+z*ca;
  141.     var rx:Number = x*cb+rz*sb;
  142.     z = x*-sb+rz*cb;
  143.     x = rx*cc-ry*sc;
  144.     y = rx*sc+ry*cc;
  145.   }
  146.   /**
  147.   * 重新设置点属性
  148.   * @param dx 代表三维空间x轴上的点
  149.   * @paramdy:代表三维空间y轴上的点
  150.   * @paramdz:代表三维空间z轴上的点
  151.   */
  152.   public function reset(dx:Number, dy:Number, dz:Number) {
  153.     this.x = dx;
  154.     this.y = dy;
  155.     this.z = dz;
  156.   }
  157.   /**
  158.   * 复制类自身并返回一个新类
  159.   * @return   Vertor3d类实例对象
  160.   */
  161.   public function getClone():Vertor3d {
  162.     return new Vertor3d(x,y,z);
  163.   }
  164.   /**
  165.   * 比较两个Vertor3d类实例对象属性是否相等,即两个点是否处于三维空间的同一个位置
  166.   * @param obj Vertor3d类实例对象
  167.   * @return   Boolean
  168.   */
  169.   public function equals(obj:Vertor3d):Boolean {
  170.     return (x == obj.x && y == obj.y && z == obj.z);
  171.   }
  172.   /**
  173.   * 将类对象实例属性与另一个Vertor3d类实例对象属性相加(即x,y,z属性值)并返回新的类对象实例属性
  174.   * @param obj Vertor3d类实例对象
  175.   */
  176.   public function plus(obj:Vertor3d) {
  177.     x += obj.x;
  178.     y += obj.y;
  179.     z += obj.z;
  180.   }
  181.   /**
  182.   * 将类对象实例属性与另一个Vertor3d类实例对象属性相加(即x,y,z属性值)并返回一个新的Vertor3d类实例对象(不改变原类对象实例)
  183.   * @param obj Vertor3d类实例对象
  184.   * @return   Vertor3d类实例对象
  185.   */
  186.   public function plusNew(obj:Vertor3d):Vertor3d {
  187.     return new Vertor3d(x + obj.x,y + obj.y,z + obj.z);
  188.   }
  189.   /**
  190.   * 将类对象实例属性与另一个Vertor3d类实例对象属性相减(即x,y,z属性值)并返回新的类对象实例属性
  191.   * @param obj Vertor3d类实例对象
  192.   */
  193.   public function minus(obj:Vertor3d) {
  194.     x -= obj.x;
  195.     y -= obj.y;
  196.     z -= obj.z;
  197.   }
  198.   /**
  199.   * 将类对象实例属性与另一个Vertor3d类实例对象属性相减(即x,y,z属性值)并返回一个新的Vertor3d类实例对象(不改变原类对象实例)
  200.   * @param obj Vertor3d类实例对象
  201.   * @return   Vertor3d类实例对象
  202.   */
  203.   public function minusNew(obj:Vertor3d):Vertor3d {
  204.     return new Vertor3d(x - obj.x,y - obj.y,z - obj.z);
  205.   }
  206.   /**
  207.   * 将类实例对象绕原点旋转180度
  208.   */
  209.   public function negate() {
  210.     x = -x;
  211.     y = -y;
  212.     z = -z;
  213.   }
  214.   /**
  215.   * 返回一个与类实例对象通过原点对称的新的Vertor3d类实例对象(不改变原类对象实例)
  216.   * @return   Vertor3d类实例对象
  217.   */
  218.   public function negateNew():Vertor3d {
  219.     return new Vertor3d(- x,- y,- z);
  220.   }
  221.   /**
  222.   * 将类对象实例属性进行等比例缩放(即x,y,z属性值)并返回新的类对象实例属性
  223.   * @param quo 缩放比例
  224.   */
  225.   public function scale(quo:Number) {
  226.     x *= quo;
  227.     y *= quo;
  228.     z *= quo;
  229.   }
  230.   /**
  231.   * 将类对象实例属性进行等比例缩放(即x,y,z属性值)并返回新的Vertor3d类实例对象(不改变原类对象实例)
  232.   * @param quo 缩放比例
  233.   * @return   Vertor3d类实例对象
  234.   */
  235.   public function scaleNew(quo:Number):Vertor3d {
  236.     return new Vertor3d(x * quo,y * quo,z * quo);
  237.   }
  238.   /**
  239.   * 返回类对象实例与原点的距离
  240.   * @return Number
  241.   */
  242.   public function getLength():Number {
  243.     return Math.sqrt(x * x + y * y + z * z);
  244.   }
  245.   /**
  246.   * 重新设置类对象实例与原点的距离
  247.   * @param len Number(len越大距离越大)
  248.   */
  249.   public function setLength(len:Number) {
  250.     var r:Number = getLength();
  251.     //如果r不为零
  252.     if (r!=0) {
  253.       scale(len/r);
  254.     } else {
  255.       x=len;
  256.     }
  257.     /**
  258.     * 返回两个Vertor3d对象实例的点积
  259.     * @param obj Vertor3d类实例对象
  260.     * @return  Number
  261.     */
  262.   }
  263.   public function dot(obj:Vertor3d):Number {
  264.     return x * obj.x + y * obj.y + z * obj.z;
  265.   }
  266.   /**
  267.   * 返回两个Vertor3d对象实例的叉积并返回新的Vertor3d对象实例
  268.   * @param obj Vertor3d类实例对象
  269.   * @return  Vertor3d类实例对象
  270.   */
  271.   public function cross(obj:Vertor3d) {
  272.     var cx:Number = y*obj.z-z*obj.y;
  273.     var cy:Number = z*obj.x-x*obj.z;
  274.     var cz:Number = x*obj.y-y*obj.x;
  275.     return new Vertor3d(cx,cy,cz);
  276.   }
  277.   /**
  278.   * 计算两个Vertor3d对象实例之间形成的夹角
  279.   * @param obj Vertor3d类实例对象
  280.   * @return  一个角度(Number)
  281.   */
  282.   public function angleBetween(obj:Vertor3d) {
  283.     var dp:Number = dot(obj);
  284.     var cosAngle:Number = dp/(getLength()*obj.getLength());
  285.     return acosD(cosAngle);
  286.   }
  287.   /**
  288.   * 计算一个物体缩放所需的透视比例
  289.   * @param viewDist 默认值300(viewDist值越小产生的透视效果越好)
  290.   * @return   透视值(Number)
  291.   */
  292.   public function getPerspective(viewDist:Number):Number {
  293.     viewDist is Number ?  0: viewDist=300;
  294.     if (z + viewDist<0) {
  295.       return viewDist;
  296.     }
  297.     return viewDist /(z + viewDist);
  298.   }
  299.   /**
  300.   * 产生类实例对象的透视投影点
  301.   * @param p 透视比例值
  302.   */
  303.   public function persProject(p:Number) {
  304.     if (!p is Number) {
  305.       p = getPerspective(NaN);
  306.     }
  307.     x *=p
  308.     y *=p;
  309.     z *=p;
  310.   }
  311.   /**
  312.   * 将类实例对象的透视投影点作为新的Vertor3d类实例对象返回
  313.   * @param p 透视比例值
  314.   * @return  Vertor3d类实例对象
  315.   */
  316.   public function persProjectNew(p:Number):Vertor3d {
  317.     if (!p is Number) {
  318.       p = getPerspective(NaN);
  319.     }
  320.     return new Vertor3d(p * x,p * y,0);
  321.   }
  322.   //重载从object继承的方法toString*/
  323.   public function toString():String {
  324.     var x:Number = Math.round(this.x*10000)/1000;
  325.     var y:Number = Math.round(this.y*10000)/1000;
  326.     var z:Number = Math.round(this.z*10000)/1000;
  327.     return "[" + x + ":" + y + ":" + z + "]";
  328.   }
  329.   /**
  330.   * 私有方法分别计算一个弧度的正弦对应的角度和余弦对象的角度
  331.   * @param radian 一个弧度值
  332.   */
  333.   public function acosD(radian:Number):Number {
  334.     return Math.cos(radian * Math.PI / 180);
  335.   }
  336.   public function asinD(radian:Number):Number {
  337.     return Math.sin(radian * Math.PI / 180);
  338.   }
  339. }
  340. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值