| 首页 | 新闻 | 网页 | 设计 | 色彩 | 原创 | 视觉 | 素材 | 动漫 | 酷站 | 策划 | 文案 | 访谈 | 运营 | 编程 | 数据库 | 服务器 | 下载 | 图库 | 
您的位置: 幽幽天空 > 网页 > 网页制作 > Flash教程 > ActionScript教程 > 文章正文 用户登录
一个站点要运营成
迅雷联盟:个人站
迅雷联盟,个人站
一个失败者的网站
从名片看到一个小
一个大学生的网页
网络新生领域扫描
一个站长建站经历
一个网络创业者的
广捷居 一个永不言

一个菜鸟是如何用curveTo画出双曲线的           

一个菜鸟是如何用curveTo画出双曲线的

作者:佚名 来源:闪吧 作者: Leon000 更新:2007-1-13 20:46:16 错误报告 我要投稿
点击浏览该文件

我以前画曲线都是用lineTo画很短很短的直线连接的,这样机子跑起来有点慢,于是很想知道怎么用curveTo画曲线,在论坛上搜了一下(版主说问问题前先搜索的,呵呵),正好搜到egg61620048月贴的一个帖子,上面详细的阐述了怎么用curveTo画圆、抛物线的方法,呵呵,帖子太长,我没看完(其实我看下去也看不懂),于是我自己想。

curveTo画出来的是一条二次贝赛尔曲线,curveTo里面的4个参数就是那个贝赛尔曲线的控制点和一个端点的xy坐标,这样,只要我们知道端点和控制点的坐标是什么,用curveTo画曲线就很容易了。

例如:已知一段线的端点是a(axay)b(bxby),控制点是c(bxby),那么只要:

_root.createEmptyMovieClip(“aaa”,1);
aaa.lineStyle(1,0x000000,100);
aaa.moveTo(ax,ay);
aaa.curveTo(cx,cy,bx,by);

就画出了一条二次贝赛尔曲线了。那么,要用curveTo画曲线关键就是获得相应的端点和控制点了。

端点坐标很容易得到的,在你要画的曲线(圆、双曲线、指数函数曲线、对数函数曲线等等)上任取一点Pxy),x自己选,y可以根据方程式算出来,这就是端点了,然后只要知道控制点的坐标值,就可以利用curveTo画线了。

其实以一条二次贝赛尔曲线的两个端点为切点作切线,其交点就是那个控制点(自己算一下8条贝赛尔曲线画圆的里面那些点的坐标就能得出这个结论的)。那么我们需要先得到切线,双曲线的切线方程是这样的:

已知双曲线 上有一点Px1y1),那么过P作的切线方程就是: ,换算一下就是: (看看有没有错,我很粗心的,最好大家自己也算一下啊)。

这样,如果取两点P1P2就会得到两个切线方程了,然后根据这两个方程算出交点(直线交点大家都会求的哦),这个交点就是控制点了,然后,多取几个端点,算出交点,哈哈,^_^,就可以写代码,画双曲线了。

我的思路是这样的(这里声明一下,我不是程序员,我学flash之前学过的最深奥的关于编程的东东就是c语言里的数组,高手们不要鄙视我啊):我们要用到用xy坐标表示的点,于是我写一个Point()类,这些点有端点和控制点,端点都是在双曲线上的,所以我们需要一个函数sqxfz(双曲线赋值的缩写,哈哈)来根据点的x坐标按照双曲线方程算y坐标,然后,我们需要计算切线方程,所以我写了个函数sqxqx(双曲线切线的缩写),有了直线,要求交点,于是,再写一个函数qxjd(切线交点),然后,写一个类Shuangquxian(),里面有一些属性,都是画线需要的,最后,这些都准备好了,那么,可以画线了,我的代码是这样的(我好紧张!怕被鄙视啊!各位大侠贴下留情啊!可以跳过不看的,最重要的是自己写出代码):

var mousedown = false;//用于判断鼠标是否被按下
function Point(x, y) {//创建Point类
this.x = x;
this.y = y;
}
function Shuangquxian(a, b) {//创建双曲线类
this.a = a;
this.b = b;//a、b就是双曲线的a、b咯
//下面的dd是贝赛尔曲线的端点,jd是贝赛尔曲线的控制点(即通过dd作切线后切线的 交点)
this.dd = [];
this.jd = [];
for (var i = 0; i<=3; i++) {
this.dd[i] = new Point(0, 0);
this.jd[i] = new Point(0, 0);
}
with (this) {//给各端点的x坐标赋值
c = 320-a;//这里减去320是因为场景是640×480的
dd[0].x = a;
dd[1].x = a+c/12;
dd[2].x = a+c/6;
dd[3].x = a+c;
}
for (var j = 0; j<=3; j++) {
this.dd[j].sqxfz(this.a, this.b);//按双曲线方程计算端点的y坐标值
}
with (this) {//计算出各控制点的坐标,用的是sqxjd方法
jd[1].x = dd[0].x;
jd[1].y = sqxqx(dd[1]).k*dd[0].x+sqxqx(dd[1]).t;
jd[2] = qxjd(dd[1], dd[2]);
jd[3] = qxjd(dd[2], dd[3]);
}
}
Point.prototype.sqxfz = function(a, b) {//双曲线赋值方法,用于计算已知x坐标的点的y坐标值
this.y = Math.sqrt(this.x*this.x*b*b/(a*a)-b*b);
};
Shuangquxian.prototype.sqxqx = function(p) {//求双曲线切线的方法,参数p是双曲线上任意一点
var a = this.a, b = this.b;
return {k:b*b*p.x/(a*a*p.y), t:-b*b/p.y};
};
Shuangquxian.prototype.qxjd = function(a, b) {//求两条切线的交点,a、b是两个切线的切点
var fc1 = this.sqxqx(a);
var fc2 = this.sqxqx(b);
var x = (fc2.t-fc1.t)/(fc1.k-fc2.k);
var y = fc1.k*x+fc1.t;
return new Point(x, y);
};
_root.createEmptyMovieClip("aaa", 1);//创建一个空mc用来放整个图形,这样容易把图的原点放到场景中心
aaa.createEmptyMovieClip("xzhou", 1);
aaa.createEmptyMovieClip("yzhou", 2);
with (aaa) {//画出坐标系,并把原点放到场景中间
xzhou.lineStyle(1, 0x000000, 100);
yzhou.lineStyle(1, 0x000000, 100);
xzhou.moveTo(-320, 0);
xzhou.lineTo(320, 0);
yzhou.moveTo(0, -240);
yzhou.lineTo(0, 240);
_x = 320;
_y = 240;
}
aaa.huaxian = function(a, b) {
this.sqx = new Shuangquxian(a, b);
this.createEmptyMovieClip("ab", 3);
with (this) {//下面就是画双曲线了,用了8段贝赛尔曲线,控制点就是双曲线对象的jd属性,端点就是dd属性
ab.lineStyle(1, 0xFF0000, 100);
ab.moveTo(sqx.dd[0].x, sqx.dd[0].y);
for (var k = 1; k<=3; k++) {
ab.curveTo(sqx.jd[k].x, sqx.jd[k].y, sqx.dd[k].x, sqx.dd[k].y);
}
ab.moveTo(sqx.dd[0].x, sqx.dd[0].y);
for (var k = 1; k<=3; k++) {
ab.curveTo(sqx.jd[k].x, -sqx.jd[k].y, sqx.dd[k].x, -sqx.dd[k].y);
}
ab.moveTo(-sqx.dd[0].x, sqx.dd[0].y);
for (var k = 1; k<=3; k++) {
ab.curveTo(-sqx.jd[k].x, sqx.jd[k].y, -sqx.dd[k].x, sqx.dd[k].y);
}
ab.moveTo(-sqx.dd[0].x, sqx.dd[0].y);
for (var k = 1; k<=3; k++) {
ab.curveTo(-sqx.jd[k].x, -sqx.jd[k].y, -sqx.dd[k].x, -sqx.dd[k].y);
}
}
};
//下面的代码用鼠标控制双曲线的a值和b值,这里设置的a=b
onMouseDown = function () {
_root.mousedown = true;
};
onMouseMove = function () {
if (mousedown) {
aaa.huaxian(Math.abs(_xmouse-320), Math.abs(_xmouse-320));
updateAfterEvent();
}
};
onMouseUp = function () {
_root.mousedown = false;
if (_ymouse<=250 && _ymouse>=230) {
aaa.huaxian(Math.abs(_xmouse-320), Math.abs(_xmouse-320));
}
};
把代码放到第一帧就可以画双曲线了。

我觉得通过这个例子可以得出这样的结论:用curveTo画曲线关键是得出曲线的切线方程,我记得用导数可以很容易求出切线方程的,那么,是不是可以写一个方法专门求切线呢?或者专门求导数呢?高等数学和编程的高手可以利用一点点时间研究一下子啊!
文章录入:skyuu    责任编辑:skyuu 
  • 上一篇文章:

  • 下一篇文章:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    发表评论:
    姓名:  评 分: 1分 2分 3分 4分 5分
     
  • 严禁发表危害国家安全、政治、黄色淫秽等内容的评论。
  • 用户需对自己在使用幽幽天空服务过程中的行为承担法律责任。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表机友个人观点,与本网站立场无关。