1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-01 06:20:52 +02:00

localize wiji links/ add 07 (#89)

* localize wiki links/add 07

* Revert "localize wiki links/add 07"

This reverts commit 9156b32601.

revert

* localize wiki links/add 07
This commit is contained in:
thrillerist
2017-03-25 06:32:37 +08:00
committed by Mike Kamermans
parent abad38ecd6
commit 4a29eee0fd
3 changed files with 56 additions and 2 deletions

View File

@@ -0,0 +1,54 @@
# de Casteljau's 算法
要绘制贝塞尔曲线,我们可以从`0``1`遍历`t`的所有值,计算权重函数,得到需要画的`x/y`值。但曲线越复杂计算量也变得越大。我们可以利用“de Casteljau算法",这是一种几何画法,并且易于实现。实际上,你可以轻易地用笔和尺画出曲线。
我们用以下步骤来替代用`t`计算`x/y`的微积分算法:
-`t`看做一个比例(实际上它就是),`t=0`代表线段的0%`t=1`代表线段的100%。
- 画出所有点的连线,对`n`阶曲线来说可以画出`n`条线。
- 在每条线的`t`处做一个记号。比如`t`是0.2就在离起点20%离终点80%)的地方做个记号。
- 连接`这些`点,得到`n-1`条线。
- 在这些新得到的线上同样用`t`为比例标记。
- 把相邻的`那些`点连线,得到`n-2`条线。
- 取记号,连线,取记号,等等。
- 重复这些步骤,直到剩下一条线。这条线段上的`t`点就是原始曲线在`t`处的点。
<div className="howtocode">
### 如何实现de Casteljau算法
让我们使用刚才描述过的算法,并实现它:
```
function drawCurve(points[], t):
if(points.length==1):
draw(points[0])
else:
newpoints=array(points.size-1)
for(i=0; i<newpoints.length; i++):
newpoints[i] = (1-t) * points[i] + t * points[i+1]
drawCurve(newpoints, t)
```
好了,这就是算法的实现。一般来说你不能随意重载“+”操作符,因此我们给出计算`x``y`坐标的实现:
```
function drawCurve(points[], t):
if(points.length==1):
draw(points[0])
else:
newpoints=array(points.size-1)
for(i=0; i<newpoints.length; i++):
x = (1-t) * points[i].x + t * points[i+1].x
y = (1-t) * points[i].y + t * points[i+1].y
newpoints[i] = new point(x,y)
drawCurve(newpoints, t)
```
以上算法做了什么如果参数points列表只有一个点 就画出一个点。如果有多个点,就生成以<i>t</i>为比例的一系列点(例如,以上算法中的"标记点"),然后为新的点列表调用绘制函数。
</div>
我们通过实际操作来观察这个过程。在以下的图表中移动鼠标来改变用de Casteljau算法计算得到的曲线点左右移动鼠标可以实时看到曲线是如何生成的。
<Graphic preset="simple"title="用de Casteljau算法来遍历曲线" setup={this.setup} draw={this.draw}/>

View File

@@ -25,4 +25,4 @@
<Graphic preset="simple" title="二次无限区间贝塞尔曲线" setup={this.setupQuadratic} draw={this.draw} />
<Graphic preset="simple" title="三次无限区间贝塞尔曲线" setup={this.setupCubic} draw={this.draw} />
实际上,图形设计和计算机建模中还用了一些和贝塞尔曲线相反的曲线,这些曲线没有固定区间和自由的坐标,相反,它们固定座标但给你自由的区间。["Spiro"曲线](http://levien.com/phd/phd.html)就是一个很好的例子,它的构造是基于[羊角螺线,也就是欧拉螺线](https://en.wikipedia.org/wiki/Euler_spiral)的一部分。这是在美学上很令人满意的曲线,你可以在一些图形包中看到它,比如[FontForge](https://fontforge.github.io)和[Inkscape](https://inkscape.org)它也被用在一些字体设计中比如Inconsolata字体
实际上,图形设计和计算机建模中还用了一些和贝塞尔曲线相反的曲线,这些曲线没有固定区间和自由的坐标,相反,它们固定座标但给你自由的区间。["Spiro"曲线](http://levien.com/phd/phd.html)就是一个很好的例子,它的构造是基于[羊角螺线,也就是欧拉螺线](https://zh.wikipedia.org/wiki/%E7%BE%8A%E8%A7%92%E8%9E%BA%E7%BA%BF)的一部分。这是在美学上很令人满意的曲线,你可以在一些图形包中看到它,比如[FontForge](https://fontforge.github.io)和[Inkscape](https://inkscape.org)它也被用在一些字体设计中比如Inconsolata字体

View File

@@ -2,7 +2,7 @@
操作点的移动,看看曲线的变化,可能让你感受到了贝塞尔曲线是如何表现的。但贝塞尔曲线究竟*是*什么呢?有两种方式来解释贝塞尔曲线,并且可以证明它们完全相等,但是其中一种用到了复杂的数学,另外一种比较简单。所以...我们先从简单的开始吧:
贝塞尔曲线是[线性插值](https://en.wikipedia.org/wiki/Linear_interpolation)的结果。这听起来很复杂,但你在很小的时候就做过线性插值:当你指向两个物体中的另外一个物体时,你就用到了线性插值。它就是很简单的“选出两点之间的一个点”。
贝塞尔曲线是[线性插值](https://zh.wikipedia.org/wiki/%E7%BA%BF%E6%80%A7%E6%8F%92%E5%80%BC)的结果。这听起来很复杂,但你在很小的时候就做过线性插值:当你指向两个物体中的另外一个物体时,你就用到了线性插值。它就是很简单的“选出两点之间的一个点”。
如果我们知道两点之间的距离并想找出离第一个点20%间距的一个新的点(也就是离第二个点80%的间距),我们可以通过简单的计算来得到: