1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-21 16:02:08 +02:00

[ja-JP] Translate decasteljau (#85)

This commit is contained in:
Masaya Nakamura
2017-03-17 23:43:36 +09:00
committed by Mike Kamermans
parent cd9bf5c27a
commit 00854a96ca

View File

@@ -0,0 +1,54 @@
# ド・カステリョのアルゴリズム
ベジエ曲線を描く場合は、`t`の値を0から1まで動かしながら重みつき基底関数を計算し、プロットに必要な`x/y`の値を求めます。しかし、曲線が複雑になればなるほど、計算コストがかかるようになってしまいます。そこでその代わりに、「ド・カステリョのアルゴリズム」を使って曲線を描くこともできます。こちらは幾何学的に曲線を描く方法で、実装も非常に簡単です。実際、鉛筆と定規を使って手描きすることもできるほど、とても簡単な方法なのです。
`x/y`の値を求めるために関数を使うのではなく、次のようにします。
- `t`そのまま比率として考えます。t=0は直線上の0%の位置、t=1は100%の位置です。
- 曲線を定める点同士を結ぶように、それぞれ直線を引きます。`n`次の曲線であれば、`n`本の直線を引きます。
- 各直線上において、距離が`t`となる点にそれぞれ印をつけます。例えば`t`が0.2なら、始点から20%、終点から80%の位置になります。
- 今度は、`それらの`点同士を直線で結びます。`n-1`本の直線が得られます。
- 各直線上において、距離が`t`となる点にそれぞれ印をつけます。
- `それらの`点同士を直線で結びます。`n-2`本の直線が得られます。
- 印をつけ、直線で結び、印をつけ、……
- 1本の直線になるまで繰り返します。その直線上の`t`の点は、元の曲線上で`t`となる点に一致しています。
<div className="howtocode">
### ド・カステリョのアルゴリズムの実装方法
いま説明したアルゴリズムを実装すると、以下のようになります。
```
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)
```
さて、これは何をしているのでしょう関数に渡す点のリストが長さ1であれば、点を1つ描きます。それ以外であれば、比率<i>t</i>の位置の点(すなわち、さきほどの説明に出てきた「印」)のリストを作り、そしてこの新しいリストを引数にして関数を呼び出します。
</div>
下の図にマウスを乗せると、この様子を実際に見ることができます。ド・カステリョのアルゴリズムによって曲線上の点を明示的に計算していますが、マウスを動かすと求める点が変わります。マウスカーソルを左から右へ(もちろん、右から左へでも)動かせば、このアルゴリズムによって曲線が生成される様子がわかります。
<Graphic preset="simple" title="ド・カステリョのアルゴリズムで曲線をたどる" setup={this.setup} draw={this.draw}/>