如何绘制线性曲线
来源:互联网 发布:centos nginx yum 安装 编辑:程序博客网 时间:2024/04/28 12:03
绘制curveTO单曲线很简单 但是复杂的线性弯曲曲线该如何绘制,如果硬连的话,中间的过渡很不协调弯弯曲曲的和 线性 似乎不是很对应......
连接平滑曲线通常是两个方法:两个curveTo拼在一起,或者使用lineTo。前者的效率比较好,效果也好,但是我不是很理解计算方法。后者的话:
有一个公式可以算是cubicBerzier曲线的定义,如下:^是乘方
P(u)=A0+(3u^2-2u^3)(A1-A0)+(u-2u^2+u^3)T0+(u^3-u^2)T1
则根据这个定义可以写出下面的代码:
function cubicCurve(lstX:int,lstY:int,
ctrlX1:int,ctrlY1:int,
ctrlX2:int,ctrlY2:int,
x:int,y:int,
u:Number):Point{
var a0:Point = new Point(lstX,lstY);
var t0:Point = new Point(ctrlX1,ctrlY1);
var t1:Point = new Point(ctrlX2,ctrlY2);
var a1:Point = new Point(x,y);
var m2:Number = (3-2*u)*u*u;
var m3:Number = 3*u*(1-u)*(1-u);
var m4:Number = 3*u*u*(u-1);
var c:Point = a1.subtract(a0);
var d:Point = t0.subtract(a0);
var e:Point = a1.subtract(t1);
var f:Point
c.x *= m2;
c.y *= m2;
c = c.add(a0);
d.x *= m3;
d.y *= m3;
e.x *= m4;
e.y *= m4;
return c.add(e).add(d);
}
这样就得到了一个 u 对应的点。用合适的步长在(0,1)取得不同的 u 就得到了点的集合,用lineTo连接到一起即可。
drawCubicCurve(ax1,ay1,cx1,cy1,cx2,cy2,ax2,ay2){
moveTo(ax1,ay1);
for(var i =0;i<1;i+=0.05){
var p = cubicCurve(ax1,ay1,cx1,cy1,cx2,cy2,ax2,ay2,i);
lineTo(p.x,p.y)
}
}
没有测试
=======================================================================
参考:
一下参考来自http://math.ntnu.edu.tw/~cyc/ 國立台灣師範大學數學系 陳創義
利用Bezier曲線及F曲線畫平滑曲線
國立台灣師範大學數學系 陳創義
E-mail:cyc@math.ntnu.edu.tw
網頁:http://math.ntnu.edu.tw/~cyc/
Bezier曲線及F曲線是畫平滑曲線常用到的曲線,例如:小畫家及word等裡頭的繪圖工具,畫平滑曲線是採用Bezier曲線,我們只要點出起點及終點,然到點出一、兩個控制彎曲程度的控制點後,一條平滑曲線就完成。Bezier曲線就是控制起點、終點及中間彎曲部分的幾個控制點來繪出平滑曲線。至於F曲線是利用三次曲線,控制起點、終點及它們的切向量,來繪出平滑曲線,它的好處是一段一段的F曲線連接起來在連接處可以較平滑,有些繪圖軟體也使用此種曲線。事實上,Bezier曲線也可以做到連接處能夠平滑的過渡到另一段曲線。我們將把這兩種曲線利用GSP軟體做成巨集,使用起來比在小畫家或word方便很多,而且可隨時調整,甚至可做成動態效果。在GSP裡你可以作更多的控制點以控制更多的彎曲。
Bezier曲線的作法如下(我們以5個控制點為例):
1. 給5個點A0,A1,A2,A3,A4,並畫線段A0A1,然後在線段A0A1上取一動點B;
2. 依序選取點A0,A1,B,在Transform功能表內,標定比值A0B/A0A1;
3. 依序以點A1,A2,A3為伸縮中心,A0B/A0A1為比值,分別將點A2,A3,A4作伸縮變換,產生點B1,B2,B3;
4. 再依序以點B,B1,B2為伸縮中心,A0B/A0A1為比值,分別將點B1,B2,B3作伸縮變換,產生點C0,C1,C2;
5. 再依序以點C0,C1為伸縮中心,A0B/A0A1為比值,分別將點C1,C2作伸縮變換,產生點D0,D1;
6. 再依序以點D0為伸縮中心,A0B/A0A1為比值,將點D1作伸縮變換,產生點E0;
7. 選取點E0及點B作軌跡,產生當B在線段A0A1上變動時點E0的軌跡【就是五個控制點的Bezier曲線】;
8. 只留下控制點A0,A1,A2,A3,A4及軌跡,其餘都隱藏,然後選取這五個控制點及軌跡作巨集(5bezier.gss)。
※ 上述共作了9次伸縮變換,如果作n+1個點A0,A1,A2,...,An-1,An,共要作 次的伸縮變換。
※ 作n+1個點A0,A1,A2,...,An-1,An的Bezier曲線的參數式α(t)為
因此,在t=0時的切向量α'(0)=n(A1-A0);在t=1時的切向量α'(1)=n(An-1-An)。
由這個訊息,我們可以作另一個巨集,把兩段Bezier曲線平滑的接在一起,也就是把前一段曲線的終點An作為後一段曲線的起點A0,將前一段的控制點An-1作對稱於An所產生的點作為後一段曲線的控制點A1。(例如:5_bezier.gss)
令P(u),0£u£1是一條起點在A0、終點在A1、在A0的切向量為T0、在A1的切向量為T1的三次參數曲線,也就是 且P(0)=A0,P'(0)=T0,P(1)=A1,P'(1)=T1,所以
P(u)=A0+(3u2-2u3)(A1-A0)+(u-2u2+u3)T0+(u3-u2)T1, 0£u£1.
稱此曲線為F曲線。
F曲線巨集作法如下:
1. 給出四個點A0、T0、A1、T1,畫線段A0T0,並在線段A0T0上取一動點B;
【向量A0T0表切向量T0,向量A1T1表切向量T1】
2. 依序選取A0、T0、B,並測量其比值[m1]=A0B/A0T0;
【參數u=[m1]】
3. 計算[m2]=3u2-2u3,[m3]=u-2u2+u3,[m4]=u3-u2;
4. 以為A0伸縮中心,分別以比值[m2]、[m3],將點A1、點T0作伸縮變換,產生點C、點D,再以A1伸縮中心,比值[m4],將點T1作伸縮變換,產生點E;
5. 將點C以向量A0D作平移,產生點F,再將點F以向量A1E作平移,產生點G;
6. 作當點B在線段A0T0上移動時,點G的軌跡;
7. 留下點A0、點T0、點A1、點T1及軌跡,其餘全部隱藏,再取點A0、T0、A1、T1及軌跡作巨集。(f_curve.gss)
※ 兩條F曲線相接連的地方只是到切向量相同,若要更平滑,可用5次的參數式,要求曲率中心相同。
※ 上述的兩種曲線,都可以用在三維直角坐標檔案上。
練習:
1. 作其他數的Bezier曲線巨集。
2. 利用這些曲線來畫臉譜並加入動態。
出错是有可能的,我原来使用8.5写的。发上来时又改了改。整个代码是不方便发上来的,抱歉。
err,看出来为什么出错了,lineTo在as3中是graphics的方法。
两个curve的算法我不是很确定,大概是这个样子:
如果两个curveTo,他们在控制点连线的中间处连接,则是平滑的(2阶berzier曲线的对称性)
于是:
moveTo(a1.x,a1.y);
var c1:Point = new Point(controlX1,controlY1);
var c2:Point = new Point(controlX2,controlY2);
var m:Point = Point.interpolate(c1,c2,0.5);
curveTo(c1.x,c1.y,m.x,m.y);
curveTo(c2.x,c2.y,a2.x,a2.y);
经过一定研究.弄出来了封闭平滑过渡曲线
- 如何绘制线性曲线
- 如何绘制并行曲线
- 如何绘制动态曲线
- 如何绘制动态曲线
- 如何绘制ROC曲线
- OpenGL中如何绘制Bezier曲线和NURBS曲线
- OpenGL中如何绘制Bezier曲线和NURBS曲线
- 如何绘制贝塞尔样条曲线和基数样条曲线[C#]
- 如何使用MATLAB绘制平滑曲线
- 使用ChemDraw Std 14如何绘制曲线
- 如何绘制caffe网络训练曲线
- 如何绘制三次B样条曲线
- 绘制曲线
- 曲线绘制
- 绘制曲线
- 曲线绘制
- 如何在VC 6.0下实现贝济埃曲线的绘制
- 如何绘制precision——recall曲线和confusion矩阵
- c#开机程序
- 多线程程序里不准使用fork ?
- 关于中文分词
- DC.Web.HttpCompress (采用原作者最新版,修复2处Bug,增加缓存功能)
- MBX编译调试指南
- 如何绘制线性曲线
- 当前国内时间管理软件产业(二)
- 计算机科学国际刊物排名
- servlet在tomcat下工作原理和小例子
- Spring中IoC的入门实例
- 多线程编程指南[中文完整翻译版] – Threading Programming Guide
- 解压缩后为0个字节
- suse linux 下JDK安装
- Android 文件系统分析