工程家园's Archiver

紫色流星 发表于 2005-10-7 16:09

[原创]面向对象的程序设计方法在Flash中的体现

面向对象的程序设计方法是当前程序设计的一个主流思想。他可以极大的提高代码的利用率和可读性。缩短调试周期和调试难度,所以,现在的主流软件都采用了这种方法,Flash也不例外。今天就以我自己编写的一个三维类来说明这个方法吧。:)

紫色流星 发表于 2005-10-7 16:15

首先要建立一个构造函数

我们定名字为:v3d,而且定义为全局变量

[code]// v3d 类构造函数
_global.v3d = function(x, y, z) {
        this.x = x;
        this.y = y;
        this.z = z;
};[/code]

紫色流星 发表于 2005-10-7 16:18

由于我们经常用的功能不多,所以我只是写出一部分。

有了构造函数,我们需要一个检测方法,以检查我们的变量值。

一般使用一个返回字符串的方法:

[code]// v3d 返回字符串方法
v3d.prototype.string = function() {
        return ("("+this.x+","+this.y+","+this.z+")");
};[/code]

紫色流星 发表于 2005-10-7 16:21

我们现在还需要向量的加法和减法

相信大家的数学知识能看懂

[code]// v3d 向量加法方法
v3d.prototype.plus = function(v) {
        return new this.constructor(this.x+v.x, this.y+v.y, this.z+v.z);
};
// v3d 向量减法方法
v3d.prototype.minus = function(v) {
        return new this.constructor(this.x-v.x, this.y-v.y, this.z-v.z);
};[/code]

紫色流星 发表于 2005-10-7 16:29

向量的点乘和叉乘

[code]// v3d 向量点积方法
v3d.prototype.dot = function(v) {
        return (this.x*v.x+this.y*v.y+this.z*v.z);
};
// v3d 向量叉乘方法
v3d.prototype.cross = function(v) {
        var cx = this.y*v.z-this.z*v.y;
        var cy = this.z*v.x-this.x*v.z;
        var cz = this.x*v.y-this.y*v.x;
        return new this.constructor(cx, cy, cz);
};[/code]

紫色流星 发表于 2005-10-7 16:38

这个是三维类中应用最多的方法,他是将三维向量投影到平面来的方法。

[code]// v3d 向量的平面的投影方法
v3d.prototype.v3dtov2d = function(d) {
        var nx = this.y*d/(d-this.x);
        var ny = this.z*d/(d-this.x);
        return new v2d(nx, ny);
};[/code]

紫色流星 发表于 2005-10-7 16:45

下面是向量旋转的公式方法,有点数学基础的人都可以看懂吧?

[code]// v3d 向量按照给定角度围绕X轴旋转的方法
v3d.prototype.Xrotate = function(xw, b) {
        if (b) {
                xw *= (Math.PI/180);
        }
        var ny = this.y*Math.cos(xw)+this.z*Math.sin(xw);
        var nz = this.z*Math.cos(xw)-this.y*Math.sin(xw);
        return new this.constructor(this.x, ny, nz);
};
// v3d 向量按照给定角度围绕Y轴旋转的方法
v3d.prototype.Yrotate = function(yw, b) {
        if (b) {
                yw *= (Math.PI/180);
        }
        var nz = this.z*Math.cos(yw)+this.x*Math.sin(yw);
        var nx = this.x*Math.cos(yw)-this.z*Math.sin(yw);
        return new this.constructor(nx, this.y, nz);
};
// v3d 向量按照给定角度围绕Z轴旋转的方法
v3d.prototype.Zrotate = function(zw, b) {
        if (b) {
                zw *= (Math.PI/180);
        }
        var nx = this.x*Math.cos(zw)+this.y*Math.sin(zw);
        var ny = this.y*Math.cos(zw)-this.x*Math.sin(zw);
        return new this.constructor(nx, ny, this.z);
};[/code]

紫色流星 发表于 2005-10-7 16:56

当然,如果在一个物体整体旋转的时候,每个点都计算三角函数是很占用资源的事情,而且他们的函数值都是一样的,所以完全可以把三角函数值作为参数。

[code]// v3d 向量按照给定三角函数值围绕X轴旋转的方法
v3d.prototype.Xrotate2 = function(c, s) {
        var ny = this.y*c+this.z*s;
        var nz = this.z*c-this.y*s;
        return new this.constructor(this.x, ny, nz);
};
// v3d 向量按照给定三角函数值围绕Y轴旋转的方法
v3d.prototype.Yrotate2 = function(c, s) {
        var nz = this.z*c+this.x*s;
        var nx = this.x*c-this.z*s;
        return new this.constructor(nx, this.y, nz);
};
// v3d 向量按照给定三角函数值围绕Z轴旋转的方法
v3d.prototype.Zrotate2 = function(c, s) {
        var nx = this.x*c+this.y*s;
        var ny = this.y*c-this.x*s;
        return new this.constructor(nx, ny, this.z);
};[/code]

紫色流星 发表于 2005-10-7 16:57

今天暂时编写到这里,改天有机会讲解下这个类的应用。

风中落叶 发表于 2005-10-7 18:37

学习了
期待着继续

紫色流星 发表于 2005-10-8 09:20

[quote]Originally posted by [i]第八个孩子[/i] at 2005-10-8 09:04:
嗯,不错
希望你继续下去
好好弄个系列的 [/quote]
呵呵~~有了老八的支持,那今天我就把剩下的方法都写出来吧~:P

紫色流星 发表于 2005-10-8 09:22

创立副本的方法,其实就是复制自己的方法。

重设方法,其实我感觉还不如直接初始化的方便。

[code]// v3d 创建副本方法
v3d.prototype.clone = function() {
        return new this.constructor(this.x, this.y, this.z);
};
// v3d 重设方法
v3d.prototype.reset = function(x, y, z) {
        this.constructor(x, y, z);
};[/code]

紫色流星 发表于 2005-10-8 09:26

求已知向量的逆向量的方法。

[code]// v3d 向量求逆方法
v3d.prototype.negate = function() {
        return new this.constructor(-this.x, -this.y, -this.z);
};[/code]

紫色流星 发表于 2005-10-8 09:26

对已知向量设置缩放倍数的方法

[code]// v3d 向量缩放方法
v3d.prototype.scale = function(s) {
        return new this.constructor(this.x*s, this.y*s, this.z*s);
};[/code]

紫色流星 发表于 2005-10-8 09:27

对已知向量求模和设置模的方法

[code]// v3d 向量求模方法
v3d.prototype.getmod = function() {
        return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);
};
// v3d 向量设模方法
v3d.prototype.setmod = function(len) {
        var r = this.getmod();
        if (r) {
                var n = this.scale(len/r);
                this.x = n.x;
                this.y = n.y;
                this.z = n.z;
        } else {
                this.x = len;
        }
};[/code]

紫色流星 发表于 2005-10-8 09:29

两个向量之间求夹角

[code]// v3d 向量夹角方法
v3d.prototype.angle = function(v, b) {
        var dp = this.dot(v);
        var cosAngle = dp/(this.getmod()*v.getmod());
        var angle = Math.acos(cosAngle);
        if (b) {
                return angle*180/Math.PI;
        } else {
                return angle;
        }
};[/code]

紫色流星 发表于 2005-10-8 09:32

所有的方法都发完了,下面给出语法规则参考使用:

[code]/*
Vector 3D 功能语法列表
my3d=new v3d(x,y,z); //创建构造函数
my3d.string(); //返回my3d的字符串
my3d.reset(); //重设my3d的x,y坐标
your3d=my3d.clone(); //返回my3d的副本给your3d
your3d.equal(my3d); //返回布尔值,比较两个向量是否相等
his3d=your3d.plus(my3d); //返回两个向量的和
his3d=your3d.minus(my3d); //返回两个向量的差
your3d=my3d.negate(); //返回my3d的逆向量
your3d=my3d.scale(s); //返回my3d的s倍放缩
my3d.getmod(); //返回向量的模
my3d.setmod(len); //设置向量的模
my3d.dot(your3d); //返回两个向量的点积
my3d.cross(your3d); //返回两个向量的叉积
my3d.angle(your3d,boolean); //返回两个向量的差角,true为角度,flase为弧度
my2d=my3d.v3dtov2d(distance); //返回三维向量在距离为distance平面投影的二维向量
your3d=my3d.Xrotate(xw,boolean); //将向量绕X轴旋转xw并返回,true为角度,flase为弧度
your3d=my3d.Yrotate(yw,boolean); //将向量绕Y轴旋转yw并返回,true为角度,flase为弧度
your3d=my3d.Zrotate(zw,boolean); //将向量绕Z轴旋转zw并返回,true为角度,flase为弧度
your3d=my3d.Xrotate2(cos,sin); //将向量绕X轴旋转并返回,cos sin 分别为旋转角度的三角函数值
your3d=my3d.Yrotate2(cos,sin); //将向量绕Y轴旋转并返回,cos sin 分别为旋转角度的三角函数值
your3d=my3d.Zrotate2(cos,sin); //将向量绕Z轴旋转并返回,cos sin 分别为旋转角度的三角函数值
*/[/code]

紫色流星 发表于 2005-10-8 09:35

下面给出这个源文件的下载

紫色流星 发表于 2005-10-8 09:39

在程序中可以通过下面的命令引用这个三维类,然后像正常的命令一样使用就可以了。

注意,必须和程序保存在一个文件夹下。

[code]#include<Vector3D.as>[/code]

风中落叶 发表于 2005-10-8 12:56

不错不错
我也学习了

页: [1] 2

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.