Board logo

标题: [原创]最新编写的三维类Vxp3 [打印本页]

作者: 紫色流星    时间: 2007-6-27 11:06     标题: [原创]最新编写的三维类Vxp3

为了实现更强大的三维效果,重新改写了更为完善的三维类,命名为Vxp3。

相对于前一个版本,主要做了如下更新:
1、将方法的数量增加到39个,能够实现更多的功能;
2、为了保持向下兼容,很多不再推荐的方法仍然保留;
3、按照计算机图形学的通常情况更改了坐标系,修改旋转的方向为逆时针;
4、新增向量分解和坐标系变换两种方法编写的任意轴旋转问题,不过从效率上讲,推荐前者;
5、扩展向量的缩放方法,可沿坐标轴缩放,全坐标轴缩放和任意向量缩放;
6、更新了向屏幕投影的算法,以观察距离为缩放度量,使立体感更强;
7、新增正交投影方法;
8、新增镜像变换方法;
9、新增错切方法。

整个类的源文件分为以下十个部分:
1、基本属性;
2、构造函数
3、基本方法;
4、数值计算;
5、旋转方法;
6、缩放方法;
7、屏幕投影;
8、正交投影;
9、镜像变换;
10、错切变换。

作者: 紫色流星    时间: 2007-6-27 11:09

全部源代码如下:
  1. class Vxp3 {
  2. //---------------------------
  3. //三维向量的40个基本方法
  4. //最后更新:2007-06-14
  5. //版本:1.00_alpha
  6. //作者:las
  7. //E-mail:ilovelassie@163.com
  8. //版权:遵守GNU协议,任何人都可以自由复制修改传播,但不得用于商业用途。
  9. //----------------------------
  10. //定义三个坐标作为共有属性。
  11. public var ix:Number;
  12. public var iy:Number;
  13. public var iz:Number;
  14. //构造函数。
  15. public function Vxp3(param_x:Number, param_y:Number, param_z:Number) {
  16.   this.ix = param_x;
  17.   this.iy = param_y;
  18.   this.iz = param_z;
  19. }
  20. //基本方法:
  21. //1.输出向量到输出窗口。
  22. public function toString(s:String):Void {
  23.   trace(s+":  x:"+this.ix+"  y:"+this.iy+"  z:"+this.iz);
  24. }
  25. //2.向量的重设。
  26. public function reset(param_x:Number, param_y:Number, param_z:Number):Void {
  27.   this.ix = param_x;
  28.   this.iy = param_y;
  29.   this.iz = param_z;
  30. }
  31. //3.向量的复制。
  32. public function clone():Vxp3 {
  33.   return (new Vxp3(this.ix, this.iy, this.iz));
  34. }
  35. //计算方法:
  36. //1.向量比较。
  37. public function equal(v:Vxp3):Boolean {
  38.   return (this.ix == v.ix && this.iy == v.iy && this.iz == v.iz);
  39. }
  40. //2.向量加法。
  41. public function plus(v:Vxp3):Vxp3 {
  42.   return (new Vxp3(this.ix+v.ix, this.iy+v.iy, this.iz+v.iz));
  43. }
  44. //3.向量减法。
  45. public function minus(v:Vxp3):Vxp3 {
  46.   return (new Vxp3(this.ix-v.ix, this.iy-v.iy, this.iz-v.iz));
  47. }
  48. //4.向量求模。
  49. public function get mod():Number {
  50.   return (Math.sqrt(this.ix*this.ix+this.iy*this.iy+this.iz*this.iz));
  51. }
  52. //5.向量设模。
  53. public function set mod(l:Number):Void {
  54.   var r = this.mod;
  55.   if (r == 0) {
  56.    this.reset(0, 0, 0);
  57.   } else {
  58.    var v = this.scale(l/r);
  59.    this.reset(v.ix, v.iy, v.iz);
  60.   }
  61. }
  62. //6.向量点积。
  63. public function dot(v:Vxp3):Number {
  64.   return (this.ix*v.ix+this.iy*v.iy+this.iz*v.iz);
  65. }
  66. //7.向量叉乘。
  67. public function cross(v:Vxp3):Vxp3 {
  68.   var cx = this.iy*v.iz-this.iz*v.iy;
  69.   var cy = this.iz*v.ix-this.ix*v.iz;
  70.   var cz = this.ix*v.iy-this.iy*v.ix;
  71.   return (new Vxp3(cx, cy, cz));
  72. }
  73. //8.向量夹角。
  74. public function angle(v:Vxp3):Number {
  75.   var dp = this.dot(v);
  76.   var cosAngle = dp/(this.mod*v.mod);
  77.   return (Math.acos(cosAngle));
  78. }
  79. //9.向量的X轴方向角。
  80. public function angleX():Number {
  81.   return (Math.acos(this.ix/this.mod));
  82. }
  83. //10.向量的Y轴方向角。
  84. public function angleY():Number {
  85.   return (Math.acos(this.iy/this.mod));
  86. }
  87. //11.向量的Z轴方向角。
  88. public function angleZ():Number {
  89.   return (Math.acos(this.iz/this.mod));
  90. }
  91. //旋转方法
  92. //12.围绕X轴旋转,参数为逆时针角速度。
  93. public function rotateX1(a:Number):Vxp3 {
  94.   return (this.rotateX2(Math.cos(a), Math.sin(a)));
  95. }
  96. //13.围绕Y轴旋转,参数为逆时针角速度。
  97. public function rotateY1(a:Number):Vxp3 {
  98.   return (this.rotateY2(Math.cos(a), Math.sin(a)));
  99. }
  100. //14.围绕Z轴旋转,参数为逆时针角速度。
  101. public function rotateZ1(a:Number):Vxp3 {
  102.   return (this.rotateZ2(Math.cos(a), Math.sin(a)));
  103. }
  104. //15.围绕X轴旋转,参数为逆时针角速度的余弦值和正弦值。
  105. public function rotateX2(c:Number, s:Number):Vxp3 {
  106.   var ny = this.iy*c-this.iz*s;
  107.   var nz = this.iz*c+this.iy*s;
  108.   return (new Vxp3(this.ix, ny, nz));
  109. }
  110. //16.围绕Y轴旋转,参数为逆时针角速度的余弦值和正弦值。
  111. public function rotateY2(c:Number, s:Number):Vxp3 {
  112.   var nz = this.iz*c-this.ix*s;
  113.   var nx = this.ix*c+this.iz*s;
  114.   return (new Vxp3(nx, this.iy, nz));
  115. }
  116. //17.围绕Z轴旋转,参数为逆时针角速度的余弦值和正弦值。
  117. public function rotateZ2(c:Number, s:Number):Vxp3 {
  118.   var nx = this.ix*c-this.iy*s;
  119.   var ny = this.iy*c+this.ix*s;
  120.   return (new Vxp3(nx, ny, this.iz));
  121. }
  122. //18.使用向量分解法的扩展旋转方法,参数为基准向量和要旋转角度值。
  123. public function rotateN1(param_n:Vxp3, a:Number):Vxp3 {
  124.   return (this.rotateN2(param_n, Math.cos(a), Math.sin(a)));
  125. }
  126. //19.使用向量分解法的扩展旋转方法,参数为基准向量和要旋转角度的余弦和正弦值。
  127. public function rotateN2(param_n:Vxp3, c:Number, s:Number):Vxp3 {
  128.   var n = param_n.clone();
  129.   n.mod = 1;
  130.   var v = n.scale(this.dot(n));
  131.   return (((this.minus(v)).scale(c)).plus((n.cross(this)).scale(s)).plus(v));
  132. }
  133. //20.使用局部坐标系法的扩展旋转方法。
  134. public function rotateN3(v:Vxp3, a:Number):Vxp3 {
  135.   var vi:Vxp3 = new Vxp3();
  136.   var vj:Vxp3 = new Vxp3();
  137.   var vk:Vxp3 = new Vxp3();
  138.   var vc:Vxp3 = new Vxp3();
  139.   var vs:Vxp3 = new Vxp3();
  140.   vi = v.clone();
  141.   if (vi.iy == 0 && vi.iz == 0) {
  142.    vj.reset(0, 1, 0);
  143.   } else {
  144.    vj.reset(1, 0, 0);
  145.   }
  146.   vk = vj.cross(vi);
  147.   vj = vk.cross(vi);
  148.   vi.mod = 1;
  149.   vj.mod = 1;
  150.   vk.mod = 1;
  151.   var vc = new Vxp3(this.dot(vi), this.dot(vj), this.dot(vk));
  152.   vc = vc.rotateX1(a);
  153.   var vs = vc.clone();
  154.   vs.ix = vc.ix*vi.ix+vc.iy*vj.ix+vc.iz*vk.ix;
  155.   vs.iy = vc.ix*vi.iy+vc.iy*vj.iy+vc.iz*vk.iy;
  156.   vs.iz = vc.ix*vi.iz+vc.iy*vj.iz+vc.iz*vk.iz;
  157.   return vs;
  158. }
  159. //缩放方法
  160. //21.同比例缩放。
  161. public function scale(s:Number):Vxp3 {
  162.   return (new Vxp3(this.ix*s, this.iy*s, this.iz*s));
  163. }
  164. //22.X轴缩放。
  165. public function scaleX(s:Number):Vxp3 {
  166.   return (new Vxp3(this.ix*s, this.iy, this.iz));
  167. }
  168. //23.Y轴缩放。
  169. public function scaleY(s:Number):Vxp3 {
  170.   return (new Vxp3(this.ix, this.iy*s, this.iz));
  171. }
  172. //24.Z轴缩放。
  173. public function scaleZ(s:Number):Vxp3 {
  174.   return (new Vxp3(this.ix, this.iy, this.iz*s));
  175. }
  176. //25.任意轴缩放,参数为基准向量和缩放系数。
  177. public function scaleN(param_n:Vxp3, s:Number):Vxp3 {
  178.   var n = param_n.clone();
  179.   n.mod = 1;
  180.   var v = n.scale(this.dot(n)*(s-1));
  181.   return (this.plus(v));
  182. }
  183. //屏幕投影
  184. //26.使用远点投影法返回X轴坐标。
  185. public function translateX(l:Number):Number {
  186.   return (l*this.ix/(l-this.iz));
  187. }
  188. //27.使用远点投影法返回Y轴坐标。
  189. public function translateY(l:Number):Number {
  190.   return (l*this.iy/(l-this.iz));
  191. }
  192. //28.新投影法,返回屏幕X坐标。
  193. public function tranToX(v:Vxp3):Number {
  194.   var l:Number = v.mod;
  195.   return (l*this.ix/(l-this.iz));
  196. }
  197. //29.新投影法,返回屏幕Y坐标
  198. public function tranToY(v:Vxp3):Number {
  199.   var l:Number = v.mod;
  200.   return (l*this.iy/(l-this.iz));
  201. }
  202. //正交投影
  203. //30.任意过原点直线上的投影。
  204. public function projectL(param_n:Vxp3):Vxp3 {
  205.   var n = param_n.clone();
  206.   n.mod = 1;
  207.   return (n.scale(this.dot(n)));
  208. }
  209. //31.任意过原点平面上的投影,参数为平面的法向量。
  210. public function projectS(param_n:Vxp3):Vxp3 {
  211.   var n = param_n.clone();
  212.   n.mod = 1;
  213.   return (this.minus(n.scale(this.dot(n))));
  214. }
  215. //镜像变换
  216. //32.向量关于X轴的镜像。
  217. public function mirrorX():Vxp3 {
  218.   return (this.scaleX(-1));
  219. }
  220. //33.向量关于Y轴的镜像。
  221. public function mirrorY():Vxp3 {
  222.   return (this.scaleY(-1));
  223. }
  224. //34.向量关于Z轴的镜像。
  225. public function mirrorZ():Vxp3 {
  226.   return (this.scaleZ(-1));
  227. }
  228. //35.向量关于原点的镜像。
  229. public function mirrorO():Vxp3 {
  230.   return (this.scale(-1));
  231. }
  232. //36.向量关于任意过原点直线的镜像。
  233. public function mirrorN(param_n:Vxp3):Vxp3 {
  234.   var n = param_n.clone();
  235.   n.mod = 1;
  236.   return (this.minus(n.scale(2*this.dot(n))));
  237. }
  238. //错切变换
  239. //37.X轴Y轴方向的切变,参数为X轴方向的切变系数xs和Y轴方向的切变系数ys。
  240. public function shareXY(xs:Number, ys:Number):Vxp3 {
  241.   return (new Vxp3(this.ix+this.iz*xs, this.iy+this.iz*ys, this.iz));
  242. }
  243. //38.Y轴Z轴方向的切变,参数为Y轴方向的切变系数ys和Z轴方向的切变系数zs。
  244. public function shareYZ(ys:Number, zs:Number):Vxp3 {
  245.   return (new Vxp3(this.ix, this.iy+this.ix*ys, this.iz+this.ix*zs));
  246. }
  247. //39.Z轴X轴方向的切变,参数为Z轴方向的切变系数xs和X轴方向的切变系数xs。
  248. public function shareZX(zs:Number, xs:Number):Vxp3 {
  249.   return (new Vxp3(this.ix+this.iy*xs, this.iy, this.iz+this.ix*zs));
  250. }
  251. }
复制代码

作者: hrbeu    时间: 2007-6-27 11:09

不错
流星做这个1年多了啊,现在应该是这方面专家了
有前途
作者: 紫色流星    时间: 2007-6-27 11:11     标题: 附:编程随想一篇

为了编写更新更高级的三维效果,特意重新编写了原来的三维类。在此期间参考阅读了《3D数学基础:图形与游戏开发》,这本书着重讲解了数学知识。其实编程到了一定程度,所困扰的或者说所称为水平提高的瓶颈其实就是数学。所以应该多看一些数学书,学习一些数学知识。

说到这里我不得不扯些,数学真的可以称得上是关于方法的学科,其中所蕴含的思想是终身受益的。可是现在我们的教育是那种填鸭式的教育,不管你愿不愿意,不管你有没有兴趣,我的任务就是把这些强制性添装到你的脑子里去,考试的时候你能写在卷子上就OK了。这样我老师可以获得所谓的“教育质量”,学生也可以获得所谓的“学习成绩”,往往忽略了知识的本质。学生掌握了大量的知识,却不知道如何应用。

当我在这本书上看到了我所需要的问题的解决方法。这里面的数学知识正是我所学过的《线性代数》和《矩阵论》,比如向量的分解,向量的正交化——施密特正交化,向量的标准正交基,坐标系的相互转换,还有矩阵的一些性质——单位正交阵的逆等于它的转置等。这时候我才知道我们学的知识是干什么用的,我只能说,这是教育的悲哀……

以上随想纯属无聊,呵呵
作者: 紫色流星    时间: 2007-6-27 11:12

原帖由 hrbeu 于 2007-6-27 11:09 发表
不错
流星做这个1年多了啊,现在应该是这方面专家了
有前途

专家谈不上,也就是闲着无聊的时候编写点小代码玩玩而已。

已经没有刚开始的那种钻研的激情了,呵呵




欢迎光临 工程家园 (http://heubbs.com./) Powered by Discuz! 7.2