From 0f0083ba276be079248ccdd4c64c55ff67abb6c6 Mon Sep 17 00:00:00 2001
From: Pomax raT1G)PzOt2`
z#8D9u5wrFPYOj^Fm+-&~zlM|bLO(1W^0jb+sl;S2HWkb%bGlivI#Vwm5fQPwVR~r*
zCVwTd)!U|J%e*|@;0<+d*duUtb=_ULcS#5KCUuZ2?uzUCWR!5POmBC8e`jy9Fa;&$
zYbduy%h=dcaJRhVW^Y@v4f8UNAl#(kYk6ww{|4X;3)#K1GH`dW8#) GX{Vrk1?erUVU1!#3@)Bz&JX=#^01U@bTCfH6PB`Qb|H+v^m+pQoZ$H
zAuWK(?@rp6&Vypp2GZfj@^Y@b{*sjx6AVPioc|FMNcBg?#v~9RLmuA04*`24b;cr!
z&2rR8m3U?Q!Jh_zd{=+J60THm#U-o{Tlf9<+--VaufgH@2T-}P^YS=kWtjltAq))Y
z>)h8e!IW)MjJPRN#GM}kuF^O1;lXyL(O;uU_z;46(ubI*ckzv``~cKLiN$}|DztTX
zwdVZv$a1+inUIk1zOF7!;8QCo7y@KD4<8?*AcJZxX>cGY)MjIZSM;KE< 4_Kklc!!TAW(+tSflV?SVwqvEyR-*K~
zu$jU|m`=C#v9^jzhO`#O*N{p uM_lw=8EcglPjYuAy(=I)M7>pp)=W!%7S4IhH%9
zSqH;vUHkj4E63&L3L}s5(oefzU?7H+BERW4d3Sgj(_u&N*^fsNl?>t!iWnGW8bAX<
zp6HpHcH24!$JA=q*VnTiJGRK3qHqgnXDiZagLb2Knq1t
So let's look at that in action: the following graphic is
@@ -633,8 +633,8 @@
@@ -649,9 +649,9 @@
There's nothing really remarkable about them, they're just a sine
@@ -664,8 +664,8 @@
@@ -679,8 +679,8 @@
@@ -732,9 +732,9 @@
If the highest order term they have is x³, they're called
@@ -751,8 +751,8 @@
@@ -762,9 +762,9 @@
Notice that 2 is the same as 1+1, and 3 is 2+1 and 1+2, and 6 is
@@ -783,8 +783,8 @@
@@ -796,9 +796,9 @@
And that's the full description for Bézier curves. Σ in this
@@ -977,9 +977,9 @@ function Bezier(3,t):
That looks complicated, but as it so happens, the "weights" are
@@ -992,7 +992,7 @@ function Bezier(3,t):
The function for rational Bézier curves has two more terms:
In this, the first new term represents an additional weight for each
@@ -1202,9 +1202,9 @@ function RationalBezier(3,t,w[],r[]):
The obvious start and end values here need to be
@@ -1221,9 +1221,9 @@ function RationalBezier(3,t,w[],r[]):
With this we can guarantee that we never sum above 100%. By
@@ -1311,35 +1311,35 @@ function RationalBezier(3,t,w[],r[]):
Disregarding our actual coordinates for a moment, we have: We can write this as a sum of four expressions: And we can expand these expressions: Furthermore, we can make all the 1 and 0 factors explicit: If we compact this into a single matrix operation, we get:;^sQ;BZBV
z(ZPZ|=1iJ>kDQ{Iq!T|pRTw4`V}Olra`pkfWM!4Txd
Rk}?576%<
zd&G|EUBe=BwDBMY^)8$N6QSXJZYMY*hYwjLAi>nAFV=N9qPqSX3hVx8`g%cG<%Uz?
z2yDZ-a6}?Lb=qMnaeZS$$oebQpNP$%wV}L4K)h9wEF&AKCQ43vZddHmFU^RM();;=%%uV*K4Z;raZj7wY!W!~|EGE-!pjrC*YQl5h>;
zzB4;>?CGN_j}O67H=u+;RZt%VHjX(^)vIHrEN5qDFOGN3fm4h_Q4k{?fV%TBgM|M-
za_gPSHDFxlkJup|KD0PkAK5)Rs`l!Qh`15*=1p?iIbh9?@(M=mw4Oe-#rVxN`CD{E
z(RGYDIXShO!3o(yYCJX)fqe~b0k()fP_f~TQ&pmdB|~d%cS;-BfjTpkwE^e0FFZW9
zrco4?!9%9Y${8S7zi%ACdTt4tMAf>j(3_qfAK%X#!h^U=rR|xhs9q;yZUd~n%
F8ur}pi24A^XBI}A0l(~OX|&q
zO}anc#)>>8F*P;SHZmd+6co(5|5Z2XOSC$yR&9|5$6Pb5Sypzoyr$-*-^I3J!NK@C
zxoWC70U@no;^JxW7#aCXv+}mNqb7wT+Io5f*#m^{)B
@@ -1065,16 +1065,16 @@ function Bezier(3,t,w[]):
@@ -1349,14 +1349,14 @@ function RationalBezier(3,t,w[],r[]):
@@ -1368,7 +1368,7 @@ function RationalBezier(3,t,w[],r[]):
and
and
Excellent! Now we can form our new quadratic curve:
So, our final second curve looks like:
and
and
@@ -2021,8 +2021,8 @@ function drawCurve(points[], t):
@@ -2034,9 +2034,9 @@ function drawCurve(points[], t):
So, with that seemingly trivial observation, we rewrite that Bézier @@ -2045,9 +2045,9 @@ function drawCurve(points[], t):
So far so good. Now, to see why we did this, let's write out the @@ -2057,9 +2057,9 @@ function drawCurve(points[], t):
So by using this seemingly silly trick, we can suddenly express part @@ -2072,9 +2072,9 @@ function drawCurve(points[], t):
So, with both of those changed from an order @@ -2094,8 +2094,8 @@ function drawCurve(points[], t):
Let's do this:
@@ -2105,9 +2105,9 @@ function drawCurve(points[], t):
where the matrix M is an n+1
by
@@ -2115,9 +2115,9 @@ function drawCurve(points[], t):
That might look unwieldy, but it's really just a mostly-zeroes @@ -2143,9 +2143,9 @@ function drawCurve(points[], t):
The steps taken here are:
Which is hard to work with, so let's expand that properly:
And that's just a summation of lower order curves:
We can rewrite this as a normal summation, and we're done:
@@ -2426,15 +2426,15 @@ function drawCurve(points[], t):
The tangent is very useful for moving along a line, but what if we @@ -2447,9 +2447,9 @@ function drawCurve(points[], t):
@@ -2470,8 +2470,8 @@ function drawCurve(points[], t):
@@ -2480,8 +2480,8 @@ function drawCurve(points[], t):
@@ -2926,7 +2926,7 @@ function drawCurve(points[], t):
@@ -3436,8 +3436,8 @@ function getCubicRoots(pa, pb, pc, pd) {
@@ -3447,15 +3447,15 @@ function getCubicRoots(pa, pb, pc, pd) {
If we drop all the zero-terms, this gives us:
@@ -3577,7 +3577,7 @@ function getCubicRoots(pa, pb, pc, pd) {
What we need to do is solve a simple equation:
And of course the same functions for y:
First, let's look at the function for x(t):
or, more commonly written using Leibnitz notation as:
First, we construct the one-level-of-de-Casteljau-up points:
And then we can compute the new control points:
So we write out the expansion and rearrange:
Which we can then decompose:
Computing T is really more "arranging the numbers":
Thus:
and merge the matrices:
Into something that looks like this:
First we solve for b:
which yields:
which we can then substitute in the expression for a:
Which, worked out for the x and y components, gives:
where "a" is some scaling factor, and:
and
Then the N() function itself. What does it look like?
@@ -597,17 +597,17 @@
注目すべき箇所は特に何もありません。ただの正弦関数と余弦関数です。ただし、入力が別々の名前になっていることに気づくでしょう。仮にaの値を変えたとしても、f(b)の出力の値は変わらないはずです。なぜなら、こちらの関数にはaは使われていないからです。パラメトリック関数は、これを変えてしまうのでインチキなのです。パラメトリック関数においては、どの関数も変数を共有しています。例えば、
@@ -615,8 +615,8 @@
@@ -649,9 +649,9 @@
高校で習った、こんな形の多項式を思い出すかもしれません。
最高次の項がx³であれば3次多項式、x²であれば2次多項式と呼び、xだけの場合は1次多項式――ただの直線です。(そしてxの入った項が何もなければ、多項式ではありません!) @@ -661,7 +661,7 @@
The function for rational Bézier curves has two more terms:
In this, the first new term represents an additional weight for each @@ -1002,7 +1002,7 @@ function RationalBezier(3,t,w[],r[]):
実際の座標を一旦無視すると、次のようになります。
これは、4つの項の和になっています。
それぞれの項を展開します。
これを1つの行列演算にまとめると、以下のようになります。
ならびに
ならびに
いいですね!これで、新しい2次ベジエ曲線が得られます。
よって、後半部分の曲線は結局のところ以下のようになります。
および
および
@@ -1683,8 +1683,8 @@ function drawCurve(points[], t):
@@ -1696,9 +1696,9 @@ function drawCurve(points[], t):
So, with that seemingly trivial observation, we rewrite that Bézier @@ -1707,9 +1707,9 @@ function drawCurve(points[], t):
So far so good. Now, to see why we did this, let's write out the @@ -1719,9 +1719,9 @@ function drawCurve(points[], t):
So by using this seemingly silly trick, we can suddenly express part @@ -1734,9 +1734,9 @@ function drawCurve(points[], t):
So, with both of those changed from an order @@ -1756,8 +1756,8 @@ function drawCurve(points[], t):
Let's do this:
@@ -1767,9 +1767,9 @@ function drawCurve(points[], t):
where the matrix M is an n+1
by
@@ -1777,9 +1777,9 @@ function drawCurve(points[], t):
That might look unwieldy, but it's really just a mostly-zeroes @@ -1805,9 +1805,9 @@ function drawCurve(points[], t):
The steps taken here are:
Which is hard to work with, so let's expand that properly:
And that's just a summation of lower order curves:
We can rewrite this as a normal summation, and we're done:
@@ -2090,15 +2090,15 @@ function drawCurve(points[], t):
The tangent is very useful for moving along a line, but what if we @@ -2111,9 +2111,9 @@ function drawCurve(points[], t):
@@ -2134,8 +2134,8 @@ function drawCurve(points[], t):
@@ -2144,8 +2144,8 @@ function drawCurve(points[], t):
@@ -2598,7 +2598,7 @@ function drawCurve(points[], t):
@@ -3108,8 +3108,8 @@ function getCubicRoots(pa, pb, pc, pd) {
@@ -3119,15 +3119,15 @@ function getCubicRoots(pa, pb, pc, pd) {
If we drop all the zero-terms, this gives us:
@@ -3251,7 +3251,7 @@ function getCubicRoots(pa, pb, pc, pd) {
What we need to do is solve a simple equation:
And of course the same functions for y:
First, let's look at the function for x(t):
or, more commonly written using Leibnitz notation as:
First, we construct the one-level-of-de-Casteljau-up points:
And then we can compute the new control points:
So we write out the expansion and rearrange:
Which we can then decompose:
Computing T is really more "arranging the numbers":
Thus:
and merge the matrices:
Into something that looks like this:
First we solve for b:
which yields:
which we can then substitute in the expression for a:
Which, worked out for the x and y components, gives:
where "a" is some scaling factor, and:
and
Then the N() function itself. What does it look like?
让我们来通过实际操作看一下:下面的图形都是可交互的,因此你可以通过上下键来增加或减少插值距离,来观察图形的变化。我们从三个点构成的两条线段开始。通过对各条线段进行线性插值得到两个点,对点之间的线段再进行线性插值,产生一个新的点。最终这些点——所有的点都可以通过选取不同的距离插值产生——构成了贝塞尔曲线 @@ -565,8 +565,8 @@
@@ -577,17 +577,17 @@
这俩方程没什么让人印象深刻的,只不过是正弦函数和余弦函数,但正如你所见,输入变量有两个不同的名字。如果我们改变了a的值,f(b)的输出不会有变化,因为这个方程没有用到a。参数方程通过改变这点来作弊。在参数方程中,所有不同的方程共用一个变量,如下所示:
@@ -595,8 +595,8 @@
@@ -628,9 +628,9 @@
你可能记得高中所学的多项式,看起来像这样:
如果它的最高次项是x³就称为“三次”多项式,如果最高次项是x²,称为“二次”多项式,如果只含有x的项,它就是一条线(不过不含任何x的项它就不是一个多项式!) @@ -640,8 +640,8 @@
@@ -649,9 +649,9 @@
需要注意的是,2与1+1相同,3相当于2+1或1+2,6相当于3+3...如你所见,每次我们增加一个维度,只要简单地将头尾置为1,中间的操作都是“将上面的两个数字相加”。现在就能很容易地记住了。 @@ -661,8 +661,8 @@
@@ -670,9 +670,9 @@
这就是贝塞尔曲线完整的描述。在这个函数中的Σ表示了这是一系列的加法(用Σ下面的变量,从...=<值>开始,直到Σ上面的数字结束)。 @@ -776,16 +776,16 @@ function Bezier(3,t):
看起来很复杂,但实际上“权重”只是我们想让曲线所拥有的坐标值:对于一条nth阶曲线,w0是起始坐标,wn是终点坐标,中间的所有点都是控制点坐标。假设说一条曲线的起点为(120,160),终点为(220,40),并受点(35,200)和点(220,260)的控制,贝塞尔曲线方程就为:
The function for rational Bézier curves has two more terms:
In this, the first new term represents an additional weight for each @@ -977,9 +977,9 @@ function RationalBezier(3,t,w[],r[]):
很显然,起始值需要a=1, b=0
,混合值就为100%的value
@@ -989,9 +989,9 @@ function RationalBezier(3,t,w[],r[]):
用这个式子我们可以保证相加的值永远不会超过100%。通过将a
限制在区间[0,1],我们将会一直处于这两个值之间(包括这两个端点),并且相加为100%。
@@ -1061,49 +1061,49 @@ function RationalBezier(3,t,w[],r[]):
暂时不用管我们具体的坐标,现在有:
可以将它写成四个表达式之和:
我们可以扩展这些表达式:
更进一步,我们可以加上所有的1和0系数,以便看得更清楚:
现在,我们可以将它看作四个矩阵运算:
如果我们将它压缩到一个矩阵操作里,就能得到:
最终,我们可以加入原始的坐标,作为第三个单独矩阵:
我们可以对二次曲线运用相同的技巧,可以得到:
and
and
Excellent! Now we can form our new quadratic curve:
So, our final second curve looks like:
and
and
@@ -1693,8 +1693,8 @@ function drawCurve(points[], t):
@@ -1706,9 +1706,9 @@ function drawCurve(points[], t):
So, with that seemingly trivial observation, we rewrite that Bézier @@ -1717,9 +1717,9 @@ function drawCurve(points[], t):
So far so good. Now, to see why we did this, let's write out the @@ -1729,9 +1729,9 @@ function drawCurve(points[], t):
So by using this seemingly silly trick, we can suddenly express part @@ -1744,9 +1744,9 @@ function drawCurve(points[], t):
So, with both of those changed from an order @@ -1766,8 +1766,8 @@ function drawCurve(points[], t):
Let's do this:
@@ -1777,9 +1777,9 @@ function drawCurve(points[], t):
where the matrix M is an n+1
by
@@ -1787,9 +1787,9 @@ function drawCurve(points[], t):
That might look unwieldy, but it's really just a mostly-zeroes @@ -1815,9 +1815,9 @@ function drawCurve(points[], t):
The steps taken here are:
Which is hard to work with, so let's expand that properly:
And that's just a summation of lower order curves:
We can rewrite this as a normal summation, and we're done:
@@ -2100,15 +2100,15 @@ function drawCurve(points[], t):
The tangent is very useful for moving along a line, but what if we @@ -2121,9 +2121,9 @@ function drawCurve(points[], t):
@@ -2144,8 +2144,8 @@ function drawCurve(points[], t):
@@ -2154,8 +2154,8 @@ function drawCurve(points[], t):
@@ -2608,7 +2608,7 @@ function drawCurve(points[], t):
@@ -3118,8 +3118,8 @@ function getCubicRoots(pa, pb, pc, pd) {
@@ -3129,15 +3129,15 @@ function getCubicRoots(pa, pb, pc, pd) {
If we drop all the zero-terms, this gives us:
@@ -3261,7 +3261,7 @@ function getCubicRoots(pa, pb, pc, pd) {
What we need to do is solve a simple equation:
And of course the same functions for y:
First, let's look at the function for x(t):
or, more commonly written using Leibnitz notation as:
First, we construct the one-level-of-de-Casteljau-up points:
And then we can compute the new control points:
So we write out the expansion and rearrange:
Which we can then decompose:
Computing T is really more "arranging the numbers":
Thus:
and merge the matrices:
Into something that looks like this:
First we solve for b:
which yields:
which we can then substitute in the expression for a:
Which, worked out for the x and y components, gives:
where "a" is some scaling factor, and:
and
Then the N() function itself. What does it look like?