bug fix on the event cancellation, which was causing scroll jumps and input-change cancellation
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Bézier curves are, like all "splines", interpolation functions. This means that they take a set of points, and generate values somewhere "between" those points. (One of the consequences of this is that you'll never be able to generate a point that lies outside the outline for the control points, commonly called the "hull" for the curve. Useful information!). In fact, we can visualize how each point contributes to the value generated by the function, so we can see which points are important, where, in the curve.
|
Bézier curves are, like all "splines", interpolation functions. This means that they take a set of points, and generate values somewhere "between" those points. (One of the consequences of this is that you'll never be able to generate a point that lies outside the outline for the control points, commonly called the "hull" for the curve. Useful information!). In fact, we can visualize how each point contributes to the value generated by the function, so we can see which points are important, where, in the curve.
|
||||||
|
|
||||||
The following graphs show the interpolation functions for quadratic and cubic curves, with "S" being the strength of a point's contribution to the total sum of the Bézier function. Click or click-drag to see the interpolation percentages for each curve-defining point at a specific <i>t</i> value.
|
The following graphs show the interpolation functions for quadratic and cubic curves, with "S" being the strength of a point's contribution to the total sum of the Bézier function. Click-and-drag to see the interpolation percentages for each curve-defining point at a specific <i>t</i> value.
|
||||||
|
|
||||||
<div class="figure">
|
<div class="figure">
|
||||||
<graphics-element title="Quadratic interpolations" src="./lerp-quadratic.js"></graphics-element>
|
<graphics-element title="Quadratic interpolations" src="./lerp-quadratic.js"></graphics-element>
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
ベジエ曲線は(すべての「スプライン」と同様に)補間関数です。これは点の集合を受け取って、それらの点のどこか「内側」の値を生成するということです。(このことから、制御点同士を結んで輪郭をつくったとき、その外側に位置する点は決して生成されないことがわかります。なお、この輪郭を曲線の「包」と呼びます。お役立ち情報でした!)実際に、補間関数によって生成された値に対する、各点の寄与の大きさを可視化することができますが、これを見れば、ベジエ曲線のどの場所でどの点が重要になるのかがわかります。
|
ベジエ曲線は(すべての「スプライン」と同様に)補間関数です。これは点の集合を受け取って、それらの点のどこか「内側」の値を生成するということです。(このことから、制御点同士を結んで輪郭をつくったとき、その外側に位置する点は決して生成されないことがわかります。なお、この輪郭を曲線の「包」と呼びます。お役立ち情報でした!)実際に、補間関数によって生成された値に対する、各点の寄与の大きさを可視化することができますが、これを見れば、ベジエ曲線のどの場所でどの点が重要になるのかがわかります。
|
||||||
|
|
||||||
下のグラフは、2次ベジエ曲線や3次ベジエ曲線の補間関数を表しています。ここでSは、ベジエ関数全体に対しての、その点の寄与の大きさを示します。ある<i>t</i>において、ベジエ曲線を定義する各点の補間率がどのようになっているのか、クリックやドラッグをして確かめてみてください。
|
下のグラフは、2次ベジエ曲線や3次ベジエ曲線の補間関数を表しています。ここでSは、ベジエ関数全体に対しての、その点の寄与の大きさを示します。ある<i>t</i>において、ベジエ曲線を定義する各点の補間率がどのようになっているのか、クリックドラッグをして確かめてみてください。
|
||||||
|
|
||||||
<div class="figure">
|
<div class="figure">
|
||||||
<Graphic inline={true} title="2次の補間" draw={this.drawQuadraticLerp}/>
|
<Graphic inline={true} title="2次の補間" draw={this.drawQuadraticLerp}/>
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
贝塞尔曲线是插值方程(就像所有曲线一样),这表示它们取一系列的点,生成一些处于这些点之间的值。(一个推论就是你永远无法生成一个位于这些控制点轮廓线外面的点,更普遍是称为曲线的外壳。这信息很有用!)实际上,我们可以将每个点对方程产生的曲线做出的贡献进行可视化,因此可以看出曲线上哪些点是重要的,它们处于什么位置。
|
贝塞尔曲线是插值方程(就像所有曲线一样),这表示它们取一系列的点,生成一些处于这些点之间的值。(一个推论就是你永远无法生成一个位于这些控制点轮廓线外面的点,更普遍是称为曲线的外壳。这信息很有用!)实际上,我们可以将每个点对方程产生的曲线做出的贡献进行可视化,因此可以看出曲线上哪些点是重要的,它们处于什么位置。
|
||||||
|
|
||||||
下面的图形显示了二次曲线和三次曲线的差值方程,“S”代表了点对贝塞尔方程总和的贡献。点击或拖动点来看看在特定的<i>t</i>值时,每个曲线定义的点的插值百分比。
|
下面的图形显示了二次曲线和三次曲线的差值方程,“S”代表了点对贝塞尔方程总和的贡献。点击拖动点来看看在特定的<i>t</i>值时,每个曲线定义的点的插值百分比。
|
||||||
|
|
||||||
<div class="figure">
|
<div class="figure">
|
||||||
<Graphic inline={true} title="二次插值" draw={this.drawQuadraticLerp}/>
|
<Graphic inline={true} title="二次插值" draw={this.drawQuadraticLerp}/>
|
||||||
|
@@ -11,27 +11,21 @@ Adding these ratio values to the regular Bézier curve function is fairly easy.
|
|||||||
The function for rational Bézier curves has two more terms:
|
The function for rational Bézier curves has two more terms:
|
||||||
|
|
||||||
\[
|
\[
|
||||||
Rational\ Bézier(n,t) = \left ( \sum_{i=0}^{n} \binom{n}{i} \cdot (1-t)^{n-i} \cdot t^{i} \cdot w_i \cdot BLUE[ratio_i] \right ) \cdot BLUE[\frac{ 1 }{ Basis_{(n,t)} }]
|
Rational\ Bézier(n,t) = \frac{ \sum_{i=0}^{n} \binom{n}{i} \cdot (1-t)^{n-i} \cdot t^{i} \cdot w_i \cdot BLUE[ratio_i] }{ BLUE[ \sum_{i=0}^{n} \binom{n}{i} \cdot (1-t)^{n-i} \cdot t^{i} \cdot ratio_i ] }
|
||||||
\]
|
\]
|
||||||
|
|
||||||
In this, the first new term represents the ratio for each coordinate, as a multiplication factor. If our ratio values are [1, 0.5, 0.5, 1] then <code>ratio<sub>0</sub> = 1</code>, <code>ratio<sub>1</sub> = 0.5</code>, and so on. The second term then corrects for all those multiplications by dividing the total value by the "basis" value of the Bézier curve, i.e. the value we get by computing the curve without any weighting at (but _with_ ratios):
|
In this, the first new term represents the ratio for each coordinate, as a multiplication factor. If our ratio values are [1, 0.5, 0.5, 1] then <code>ratio<sub>0</sub> = 1</code>, <code>ratio<sub>1</sub> = 0.5</code>, and so on. The second term then corrects for all those multiplications by dividing the total value by the "basis" value of the Bézier curve, i.e. the value we get by computing the curve without any weighting (but _with_ ratios):
|
||||||
|
|
||||||
\[
|
So what does this actually do? Let's look at the effect of "rationalising" our Bézier curves by interacting with the curve and ratios. The following graphic shows the curve from the previous section, enriched with ratio factors: the closer to zero we set one or more terms, the less relative influence the associated coordinate exerts on the curve (and of course the higher we set them, the more influence they have).
|
||||||
Basis_{n,t} = \sum_{i=0}^{n} \binom{n}{i} \cdot (1-t)^{n-i} \cdot t^{i} \cdot ratio_i
|
|
||||||
\]
|
|
||||||
|
|
||||||
So what does this actually do?
|
<graphics-element title="Our rational cubic Bézier curve" src="./rational.js">
|
||||||
|
ratio 1 <input type="range" min="0" max="2" value="1" step="0.01"><span>1.0</span><br>
|
||||||
|
ratio 2 <input type="range" min="0" max="2" value="1" step="0.01"><span>1.0</span><br>
|
||||||
|
ratio 3 <input type="range" min="0" max="2" value="1" step="0.01"><span>1.0</span><br>
|
||||||
|
ratio 4 <input type="range" min="0" max="2" value="1" step="0.01"><span>1.0</span>
|
||||||
|
</graphics-element>
|
||||||
|
|
||||||
Let's look at the effect of "rationalising" our Bézier curves by interacting with the curve and ratios. The following graphic shows the curve from the previous section, enriched with ratio factors: the closer to zero we set one or more terms, the less relative influence the associated coordinates exert on the curve (and of course the higher we set them, the more influence they have).
|
You can think of the ratio values as each coordinate's "gravity": the higher the gravity, the closer to that coordinate the curve will want to be. You'll also notice that if you simply increase or decrease all the ratios by the same amount, nothing changes... much like with gravity, if the relative strengths stay the same, nothing really changes. The values define each coordinate's influence _relative to all other points_.
|
||||||
|
|
||||||
<Graphic title="Our rational cubic Bézier curve" setup={this.drawCubic} draw={this.drawCurve} sliders={[
|
|
||||||
{min:0, max:2, value:1, step:0.01, label:`ratio 1`},
|
|
||||||
{min:0, max:2, value:1, step:0.01, label:`ratio 2`},
|
|
||||||
{min:0, max:2, value:1, step:0.01, label:`ratio 3`},
|
|
||||||
{min:0, max:2, value:1, step:0.01, label:`ratio 4`}
|
|
||||||
]} setSliders={this.setRatio} onSlide={this.changeRatio} context={this}/>
|
|
||||||
|
|
||||||
You can think of the ratio values as each coordinate's "gravity": the higher the gravity, the closer to that coordinate the curve will want to be. You'll also notice that if you simply increase or decrease all the ratios by the same amount, nothing changes... much like with gravity, if the relative strengths stay the same, nothing really changes. The values define each coordinate's influence _relative to all other points_.
|
|
||||||
|
|
||||||
<div class="howtocode">
|
<div class="howtocode">
|
||||||
|
|
||||||
|
30
chapters/weightcontrol/rational.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
setup() {
|
||||||
|
this.curve = Bezier.defaultCubic(this);
|
||||||
|
setMovable(this.curve.points);
|
||||||
|
|
||||||
|
const inputs = findAll(`input[type=range]`);
|
||||||
|
if (inputs) {
|
||||||
|
const ratios = inputs.map(i => parseFloat(i.value));
|
||||||
|
this.curve.setRatios(ratios);
|
||||||
|
inputs.forEach((input,pos) => {
|
||||||
|
input.listen([`input`], evt => {
|
||||||
|
evt.target.nextSibling.textContent = ratios[pos] = parseFloat(evt.target.value);
|
||||||
|
this.curve.update();
|
||||||
|
this.redraw();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
clear();
|
||||||
|
const curve = this.curve;
|
||||||
|
curve.drawSkeleton();
|
||||||
|
curve.drawCurve();
|
||||||
|
curve.drawPoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseMove() {
|
||||||
|
this.curve.update();
|
||||||
|
redraw();
|
||||||
|
}
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.9 KiB |
After Width: | Height: | Size: 9.9 KiB |
1
images/latex/3fd61ab3fe88f694e70f61e4f8ea056b.svg
Normal file
After Width: | Height: | Size: 17 KiB |
1
images/latex/fe880741c0d91317587412f1badeab3f.svg
Normal file
After Width: | Height: | Size: 19 KiB |
76
index.html
@@ -912,9 +912,9 @@ function Bezier(3,t):
|
|||||||
<p>
|
<p>
|
||||||
The following graphs show the interpolation functions for quadratic
|
The following graphs show the interpolation functions for quadratic
|
||||||
and cubic curves, with "S" being the strength of a point's
|
and cubic curves, with "S" being the strength of a point's
|
||||||
contribution to the total sum of the Bézier function. Click or
|
contribution to the total sum of the Bézier function. Click-and-drag
|
||||||
click-drag to see the interpolation percentages for each
|
to see the interpolation percentages for each curve-defining point
|
||||||
curve-defining point at a specific <i>t</i> value.
|
at a specific <i>t</i> value.
|
||||||
</p>
|
</p>
|
||||||
<div class="figure">
|
<div class="figure">
|
||||||
<graphics-element
|
<graphics-element
|
||||||
@@ -1081,9 +1081,9 @@ function Bezier(3,t,w[]):
|
|||||||
<p>The function for rational Bézier curves has two more terms:</p>
|
<p>The function for rational Bézier curves has two more terms:</p>
|
||||||
<img
|
<img
|
||||||
class="LaTeX SVG"
|
class="LaTeX SVG"
|
||||||
src="images/latex/39364a247a023d475d107aaf7b99d80c.svg"
|
src="images/latex/3fd61ab3fe88f694e70f61e4f8ea056b.svg"
|
||||||
width="489px"
|
width="407px"
|
||||||
height="44px"
|
height="48px"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
<p>
|
<p>
|
||||||
@@ -1093,35 +1093,51 @@ function Bezier(3,t,w[]):
|
|||||||
<code>ratio<sub>1</sub> = 0.5</code>, and so on. The second term
|
<code>ratio<sub>1</sub> = 0.5</code>, and so on. The second term
|
||||||
then corrects for all those multiplications by dividing the total
|
then corrects for all those multiplications by dividing the total
|
||||||
value by the "basis" value of the Bézier curve, i.e. the value we
|
value by the "basis" value of the Bézier curve, i.e. the value we
|
||||||
get by computing the curve without any weighting at (but
|
get by computing the curve without any weighting (but
|
||||||
<em>with</em> ratios):
|
<em>with</em> ratios):
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
So what does this actually do? Let's look at the effect of
|
||||||
|
"rationalising" our Bézier curves by interacting with the curve and
|
||||||
|
ratios. The following graphic shows the curve from the previous
|
||||||
|
section, enriched with ratio factors: the closer to zero we set one
|
||||||
|
or more terms, the less relative influence the associated coordinate
|
||||||
|
exerts on the curve (and of course the higher we set them, the more
|
||||||
|
influence they have).
|
||||||
|
</p>
|
||||||
|
<graphics-element
|
||||||
|
title="Our rational cubic Bézier curve"
|
||||||
|
width="275"
|
||||||
|
height="275"
|
||||||
|
src="./chapters/weightcontrol/rational.js"
|
||||||
|
>
|
||||||
|
<fallback-image>
|
||||||
<img
|
<img
|
||||||
class="LaTeX SVG"
|
width="275px"
|
||||||
src="images/latex/03df4af5636ff82d3e964de0b9727f23.svg"
|
height="275px"
|
||||||
width="271px"
|
src="images\chapters\weightcontrol\1128afb7511e00ad4c5e8c0628204b56.png"
|
||||||
height="41px"
|
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
<p>So what does this actually do?</p>
|
Scripts are disabled. Showing fallback image.
|
||||||
<p>
|
</fallback-image>
|
||||||
Let's look at the effect of "rationalising" our Bézier curves by
|
ratio 1
|
||||||
interacting with the curve and ratios. The following graphic shows
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
the curve from the previous section, enriched with ratio factors:
|
>1.0</span
|
||||||
the closer to zero we set one or more terms, the less relative
|
><br />
|
||||||
influence the associated coordinates exert on the curve (and of
|
ratio 2
|
||||||
course the higher we set them, the more influence they have).
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
</p>
|
>1.0</span
|
||||||
<p>
|
><br />
|
||||||
<Graphic title="Our rational cubic Bézier curve"
|
ratio 3
|
||||||
setup={this.drawCubic} draw={this.drawCurve} sliders={[ {min:0,
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 1</code>}, {min:0,
|
>1.0</span
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 2</code>}, {min:0,
|
><br />
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 3</code>}, {min:0,
|
ratio 4
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 4</code>} ]}
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
setSliders={this.setRatio} onSlide={this.changeRatio}
|
>1.0</span
|
||||||
context={this}/>
|
>
|
||||||
</p>
|
</graphics-element>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You can think of the ratio values as each coordinate's "gravity":
|
You can think of the ratio values as each coordinate's "gravity":
|
||||||
the higher the gravity, the closer to that coordinate the curve will
|
the higher the gravity, the closer to that coordinate the curve will
|
||||||
|
@@ -705,7 +705,7 @@ function Bezier(3,t):
|
|||||||
ベジエ曲線は(すべての「スプライン」と同様に)補間関数です。これは点の集合を受け取って、それらの点のどこか「内側」の値を生成するということです。(このことから、制御点同士を結んで輪郭をつくったとき、その外側に位置する点は決して生成されないことがわかります。なお、この輪郭を曲線の「包」と呼びます。お役立ち情報でした!)実際に、補間関数によって生成された値に対する、各点の寄与の大きさを可視化することができますが、これを見れば、ベジエ曲線のどの場所でどの点が重要になるのかがわかります。
|
ベジエ曲線は(すべての「スプライン」と同様に)補間関数です。これは点の集合を受け取って、それらの点のどこか「内側」の値を生成するということです。(このことから、制御点同士を結んで輪郭をつくったとき、その外側に位置する点は決して生成されないことがわかります。なお、この輪郭を曲線の「包」と呼びます。お役立ち情報でした!)実際に、補間関数によって生成された値に対する、各点の寄与の大きさを可視化することができますが、これを見れば、ベジエ曲線のどの場所でどの点が重要になるのかがわかります。
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
下のグラフは、2次ベジエ曲線や3次ベジエ曲線の補間関数を表しています。ここでSは、ベジエ関数全体に対しての、その点の寄与の大きさを示します。ある<i>t</i>において、ベジエ曲線を定義する各点の補間率がどのようになっているのか、クリックやドラッグをして確かめてみてください。
|
下のグラフは、2次ベジエ曲線や3次ベジエ曲線の補間関数を表しています。ここでSは、ベジエ関数全体に対しての、その点の寄与の大きさを示します。ある<i>t</i>において、ベジエ曲線を定義する各点の補間率がどのようになっているのか、クリックドラッグをして確かめてみてください。
|
||||||
</p>
|
</p>
|
||||||
<div class="figure">
|
<div class="figure">
|
||||||
<Graphic
|
<Graphic
|
||||||
@@ -811,9 +811,9 @@ function Bezier(3,t,w[]):
|
|||||||
<p>The function for rational Bézier curves has two more terms:</p>
|
<p>The function for rational Bézier curves has two more terms:</p>
|
||||||
<img
|
<img
|
||||||
class="LaTeX SVG"
|
class="LaTeX SVG"
|
||||||
src="images/latex/39364a247a023d475d107aaf7b99d80c.svg"
|
src="images/latex/3fd61ab3fe88f694e70f61e4f8ea056b.svg"
|
||||||
width="489px"
|
width="407px"
|
||||||
height="44px"
|
height="48px"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
<p>
|
<p>
|
||||||
@@ -823,35 +823,51 @@ function Bezier(3,t,w[]):
|
|||||||
<code>ratio<sub>1</sub> = 0.5</code>, and so on. The second term
|
<code>ratio<sub>1</sub> = 0.5</code>, and so on. The second term
|
||||||
then corrects for all those multiplications by dividing the total
|
then corrects for all those multiplications by dividing the total
|
||||||
value by the "basis" value of the Bézier curve, i.e. the value we
|
value by the "basis" value of the Bézier curve, i.e. the value we
|
||||||
get by computing the curve without any weighting at (but
|
get by computing the curve without any weighting (but
|
||||||
<em>with</em> ratios):
|
<em>with</em> ratios):
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
So what does this actually do? Let's look at the effect of
|
||||||
|
"rationalising" our Bézier curves by interacting with the curve and
|
||||||
|
ratios. The following graphic shows the curve from the previous
|
||||||
|
section, enriched with ratio factors: the closer to zero we set one
|
||||||
|
or more terms, the less relative influence the associated coordinate
|
||||||
|
exerts on the curve (and of course the higher we set them, the more
|
||||||
|
influence they have).
|
||||||
|
</p>
|
||||||
|
<graphics-element
|
||||||
|
title="Our rational cubic Bézier curve"
|
||||||
|
width="275"
|
||||||
|
height="275"
|
||||||
|
src="./chapters/weightcontrol/rational.js"
|
||||||
|
>
|
||||||
|
<fallback-image>
|
||||||
<img
|
<img
|
||||||
class="LaTeX SVG"
|
width="275px"
|
||||||
src="images/latex/03df4af5636ff82d3e964de0b9727f23.svg"
|
height="275px"
|
||||||
width="271px"
|
src="images\chapters\weightcontrol\1128afb7511e00ad4c5e8c0628204b56.png"
|
||||||
height="41px"
|
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
<p>So what does this actually do?</p>
|
Scripts are disabled. Showing fallback image.
|
||||||
<p>
|
</fallback-image>
|
||||||
Let's look at the effect of "rationalising" our Bézier curves by
|
ratio 1
|
||||||
interacting with the curve and ratios. The following graphic shows
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
the curve from the previous section, enriched with ratio factors:
|
>1.0</span
|
||||||
the closer to zero we set one or more terms, the less relative
|
><br />
|
||||||
influence the associated coordinates exert on the curve (and of
|
ratio 2
|
||||||
course the higher we set them, the more influence they have).
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
</p>
|
>1.0</span
|
||||||
<p>
|
><br />
|
||||||
<Graphic title="Our rational cubic Bézier curve"
|
ratio 3
|
||||||
setup={this.drawCubic} draw={this.drawCurve} sliders={[ {min:0,
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 1</code>}, {min:0,
|
>1.0</span
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 2</code>}, {min:0,
|
><br />
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 3</code>}, {min:0,
|
ratio 4
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 4</code>} ]}
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
setSliders={this.setRatio} onSlide={this.changeRatio}
|
>1.0</span
|
||||||
context={this}/>
|
>
|
||||||
</p>
|
</graphics-element>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You can think of the ratio values as each coordinate's "gravity":
|
You can think of the ratio values as each coordinate's "gravity":
|
||||||
the higher the gravity, the closer to that coordinate the curve will
|
the higher the gravity, the closer to that coordinate the curve will
|
||||||
|
@@ -88,6 +88,13 @@ class BaseAPI {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stopEvent(evt) {
|
||||||
|
if (evt.target === this.canvas) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -116,7 +123,7 @@ class BaseAPI {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
onMouseDown(evt) {
|
onMouseDown(evt) {
|
||||||
stop(evt);
|
this.stopEvent(evt);
|
||||||
this.cursor.down = true;
|
this.cursor.down = true;
|
||||||
this.getCursorCoords(evt);
|
this.getCursorCoords(evt);
|
||||||
}
|
}
|
||||||
@@ -125,7 +132,7 @@ class BaseAPI {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
onMouseMove(evt) {
|
onMouseMove(evt) {
|
||||||
stop(evt);
|
this.stopEvent(evt);
|
||||||
this.cursor.move = true;
|
this.cursor.move = true;
|
||||||
this.getCursorCoords(evt);
|
this.getCursorCoords(evt);
|
||||||
}
|
}
|
||||||
@@ -134,7 +141,7 @@ class BaseAPI {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
onMouseUp(evt) {
|
onMouseUp(evt) {
|
||||||
stop(evt);
|
this.stopEvent(evt);
|
||||||
this.cursor.down = false;
|
this.cursor.down = false;
|
||||||
this.cursor.move = false;
|
this.cursor.move = false;
|
||||||
this.getCursorCoords(evt);
|
this.getCursorCoords(evt);
|
||||||
@@ -148,7 +155,7 @@ class BaseAPI {
|
|||||||
// going to allow unmodified keys, or shift-modified keys,
|
// going to allow unmodified keys, or shift-modified keys,
|
||||||
// and tab has to always work. For obvious reasons.
|
// and tab has to always work. For obvious reasons.
|
||||||
if (!evt.altKey && !evt.ctrlKey && !evt.metaKey && evt.key !== "Tab") {
|
if (!evt.altKey && !evt.ctrlKey && !evt.metaKey && evt.key !== "Tab") {
|
||||||
stop(evt);
|
this.stopEvent(evt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +191,7 @@ class BaseAPI {
|
|||||||
canvas.setAttribute(`tabIndex`, 0);
|
canvas.setAttribute(`tabIndex`, 0);
|
||||||
canvas.classList.add(`focus-enabled`);
|
canvas.classList.add(`focus-enabled`);
|
||||||
canvas._force_listener = () => {
|
canvas._force_listener = () => {
|
||||||
|
/*
|
||||||
// I have NO idea why forceFocus() causes a scroll, but
|
// I have NO idea why forceFocus() causes a scroll, but
|
||||||
// I don't have time to dig into what is no doubt deep
|
// I don't have time to dig into what is no doubt deep
|
||||||
// black spec magic, so: check where we are, force the
|
// black spec magic, so: check where we are, force the
|
||||||
@@ -194,8 +202,11 @@ class BaseAPI {
|
|||||||
// Oh yeah... using round() because apparently scrollTo
|
// Oh yeah... using round() because apparently scrollTo
|
||||||
// is not NOT idempotent and rounding errors cause it to
|
// is not NOT idempotent and rounding errors cause it to
|
||||||
// drift. IT'S FUCKING HILARIOUS
|
// drift. IT'S FUCKING HILARIOUS
|
||||||
|
*/
|
||||||
this.forceFocus();
|
this.forceFocus();
|
||||||
|
/*
|
||||||
window.scrollTo(x, y);
|
window.scrollTo(x, y);
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
[`touchstart`, `mousedown`].forEach((evtName) =>
|
[`touchstart`, `mousedown`].forEach((evtName) =>
|
||||||
canvas.addEventListener(evtName, canvas._force_listener)
|
canvas.addEventListener(evtName, canvas._force_listener)
|
||||||
@@ -286,10 +297,4 @@ function enhanceContext(ctx) {
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outright kill off an event.
|
|
||||||
function stop(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
evt.stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
export { BaseAPI };
|
export { BaseAPI };
|
||||||
|
@@ -177,6 +177,7 @@ class GraphicsAPI extends BaseAPI {
|
|||||||
* custom element scoped querySelector
|
* custom element scoped querySelector
|
||||||
*/
|
*/
|
||||||
find(qs) {
|
find(qs) {
|
||||||
|
if (!this.element) return false;
|
||||||
return enrich(this.element.querySelector(qs));
|
return enrich(this.element.querySelector(qs));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +185,7 @@ class GraphicsAPI extends BaseAPI {
|
|||||||
* custom element scoped querySelectorAll
|
* custom element scoped querySelectorAll
|
||||||
*/
|
*/
|
||||||
findAll(qs) {
|
findAll(qs) {
|
||||||
|
if (!this.element) return false;
|
||||||
return Array.from(this.element.querySelectorAll(qs)).map((e) => enrich(e));
|
return Array.from(this.element.querySelectorAll(qs)).map((e) => enrich(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -72,16 +72,16 @@ class Bezier extends Original {
|
|||||||
|
|
||||||
drawCurve() {
|
drawCurve() {
|
||||||
const ctx = this.ctx;
|
const ctx = this.ctx;
|
||||||
const p = this.points;
|
|
||||||
ctx.cacheStyle();
|
ctx.cacheStyle();
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.strokeStyle = `#333`;
|
ctx.strokeStyle = `#333`;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(p[0].x, p[0].y);
|
const lut = this.getLUT().slice();
|
||||||
if (p[3]) {
|
let p = lut.shift();
|
||||||
ctx.bezierCurveTo(p[1].x, p[1].y, p[2].x, p[2].y, p[3].x, p[3].y);
|
ctx.moveTo(p.x, p.y);
|
||||||
} else {
|
while (lut.length) {
|
||||||
ctx.quadraticCurveTo(p[1].x, p[1].y, p[2].x, p[2].y);
|
p = lut.shift();
|
||||||
|
ctx.lineTo(p.x, p.y);
|
||||||
}
|
}
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.restoreStyle();
|
ctx.restoreStyle();
|
||||||
|
91
package-lock.json
generated
@@ -201,6 +201,12 @@
|
|||||||
"fill-range": "^7.0.1"
|
"fill-range": "^7.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"buffer-from": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"camelcase": {
|
"camelcase": {
|
||||||
"version": "5.3.1",
|
"version": "5.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||||
@@ -263,6 +269,16 @@
|
|||||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"clean-html": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/clean-html/-/clean-html-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-eDu0vN44ZBvoEU0oRIKwWPIccGWXtdnUNmKJuTukZ1de00Uoqavb5pfIMKiC7/r+knQ5RbvAjGuVZiN3JwJL4Q==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"htmlparser2": "^3.8.2",
|
||||||
|
"minimist": "^1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"coa": {
|
"coa": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
|
||||||
@@ -313,6 +329,18 @@
|
|||||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"concat-stream": {
|
||||||
|
"version": "1.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||||
|
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer-from": "^1.0.0",
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"readable-stream": "^2.2.2",
|
||||||
|
"typedarray": "^0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||||
@@ -498,6 +526,15 @@
|
|||||||
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
|
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"domhandler": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"domelementtype": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"domutils": {
|
"domutils": {
|
||||||
"version": "1.7.0",
|
"version": "1.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
|
||||||
@@ -758,6 +795,48 @@
|
|||||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"html": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/html/-/html-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-pUT6nqVJK/s6LMqCEKEL57WvH2E=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"concat-stream": "^1.4.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"htmlparser2": {
|
||||||
|
"version": "3.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||||
|
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"domelementtype": "^1.3.1",
|
||||||
|
"domhandler": "^2.3.0",
|
||||||
|
"domutils": "^1.5.1",
|
||||||
|
"entities": "^1.1.1",
|
||||||
|
"inherits": "^2.0.1",
|
||||||
|
"readable-stream": "^3.1.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"entities": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"http-proxy": {
|
"http-proxy": {
|
||||||
"version": "1.18.1",
|
"version": "1.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
|
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
|
||||||
@@ -811,6 +890,12 @@
|
|||||||
"minimatch": "^3.0.4"
|
"minimatch": "^3.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"indent": {
|
||||||
|
"version": "0.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/indent/-/indent-0.0.2.tgz",
|
||||||
|
"integrity": "sha1-jHnwgBkFWbaHA0uEx676l9WpEdk=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"indent-string": {
|
"indent-string": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
||||||
@@ -2025,6 +2110,12 @@
|
|||||||
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
|
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"typedarray": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||||
|
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"typedarray-to-buffer": {
|
"typedarray-to-buffer": {
|
||||||
"version": "3.1.5",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
"url": "https://github.com/Pomax/BezierInfo-2/issues"
|
"url": "https://github.com/Pomax/BezierInfo-2/issues"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "rm -f .timing && run-s time lint:* build time",
|
"start": "rm -f .timing && run-s time lint:* build time && rm -f .timing",
|
||||||
"test": "run-p server browser",
|
"test": "run-p server browser",
|
||||||
"---": "---",
|
"---": "---",
|
||||||
"browser": "open-cli http://localhost:8000",
|
"browser": "open-cli http://localhost:8000",
|
||||||
@@ -35,9 +35,12 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bezier-js": "^2.6.1",
|
"bezier-js": "^2.6.1",
|
||||||
"canvas": "^2.6.1",
|
"canvas": "^2.6.1",
|
||||||
|
"clean-html": "^1.5.0",
|
||||||
"fs-extra": "^9.0.1",
|
"fs-extra": "^9.0.1",
|
||||||
"glob": "^7.1.6",
|
"glob": "^7.1.6",
|
||||||
|
"html": "^1.0.0",
|
||||||
"http-server": "^0.12.3",
|
"http-server": "^0.12.3",
|
||||||
|
"indent": "0.0.2",
|
||||||
"marked": "^1.1.1",
|
"marked": "^1.1.1",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"nunjucks": "^3.2.2",
|
"nunjucks": "^3.2.2",
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import fs from "fs-extra";
|
import fs from "fs-extra";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
import prettier from "prettier";
|
import prettier from "prettier";
|
||||||
import generateLangSwitcher from "./generate-lang-switcher.js";
|
import generateLangSwitcher from "./generate-lang-switcher.js";
|
||||||
import nunjucks from "nunjucks";
|
import nunjucks from "nunjucks";
|
||||||
@@ -57,7 +58,11 @@ async function createIndexPages(locale, localeStrings, chapters) {
|
|||||||
|
|
||||||
const index = nunjucks.render(`index.template.html`, context);
|
const index = nunjucks.render(`index.template.html`, context);
|
||||||
|
|
||||||
|
// TODO: FIXME: Prettier is slow as hell, find an alternative that isn't...
|
||||||
|
const start = Date.now();
|
||||||
const data = prettier.format(index, { parser: `html` });
|
const data = prettier.format(index, { parser: `html` });
|
||||||
|
const end = Date.now();
|
||||||
|
console.log(`beautification for ${locale} took ${(end - start) / 1000}s`);
|
||||||
|
|
||||||
if (locale === defaultLocale) {
|
if (locale === defaultLocale) {
|
||||||
fs.writeFileSync(`index.html`, data, `utf8`);
|
fs.writeFileSync(`index.html`, data, `utf8`);
|
||||||
|
@@ -28,8 +28,9 @@ async function preprocessGraphicsElement(chapter, localeStrings, markdown) {
|
|||||||
|
|
||||||
// if there are no width/height attributes, inject them
|
// if there are no width/height attributes, inject them
|
||||||
|
|
||||||
// FIXME: This will not work if there is UI html that
|
// FIXME: This will not work if there is UI html that uses the
|
||||||
// TODO: uses width/height attributes, of course!
|
// TODO: width/height attributes, but the graphics-element
|
||||||
|
// does not, of course! [known bug]
|
||||||
|
|
||||||
if (updated.indexOf(`width=`) === -1)
|
if (updated.indexOf(`width=`) === -1)
|
||||||
updated = updated.replace(
|
updated = updated.replace(
|
||||||
@@ -78,8 +79,7 @@ async function preprocessGraphicsElement(chapter, localeStrings, markdown) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* ...docs go here...
|
||||||
* @param {*} src
|
|
||||||
*/
|
*/
|
||||||
async function generateFallbackImage(src, width, height) {
|
async function generateFallbackImage(src, width, height) {
|
||||||
// Get the sketch code
|
// Get the sketch code
|
||||||
|
@@ -23,6 +23,8 @@ nunjucks.configure(".", { autoescape: false });
|
|||||||
* ...docs go here...
|
* ...docs go here...
|
||||||
*/
|
*/
|
||||||
async function processLocale(locale, localeStrings, chapterFiles) {
|
async function processLocale(locale, localeStrings, chapterFiles) {
|
||||||
|
const start = Date.now();
|
||||||
|
|
||||||
const defaultLocale = localeStrings.getDefaultLocale();
|
const defaultLocale = localeStrings.getDefaultLocale();
|
||||||
|
|
||||||
const localeFiles = chapterFiles[locale];
|
const localeFiles = chapterFiles[locale];
|
||||||
@@ -74,6 +76,9 @@ async function processLocale(locale, localeStrings, chapterFiles) {
|
|||||||
console.log(`${locale} fully localized.`);
|
console.log(`${locale} fully localized.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const end = Date.now();
|
||||||
|
console.log(`Processing ${locale} took ${(end - start) / 1000}s`);
|
||||||
|
|
||||||
return chapters;
|
return chapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -686,7 +686,7 @@ function Bezier(3,t):
|
|||||||
贝塞尔曲线是插值方程(就像所有曲线一样),这表示它们取一系列的点,生成一些处于这些点之间的值。(一个推论就是你永远无法生成一个位于这些控制点轮廓线外面的点,更普遍是称为曲线的外壳。这信息很有用!)实际上,我们可以将每个点对方程产生的曲线做出的贡献进行可视化,因此可以看出曲线上哪些点是重要的,它们处于什么位置。
|
贝塞尔曲线是插值方程(就像所有曲线一样),这表示它们取一系列的点,生成一些处于这些点之间的值。(一个推论就是你永远无法生成一个位于这些控制点轮廓线外面的点,更普遍是称为曲线的外壳。这信息很有用!)实际上,我们可以将每个点对方程产生的曲线做出的贡献进行可视化,因此可以看出曲线上哪些点是重要的,它们处于什么位置。
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
下面的图形显示了二次曲线和三次曲线的差值方程,“S”代表了点对贝塞尔方程总和的贡献。点击或拖动点来看看在特定的<i>t</i>值时,每个曲线定义的点的插值百分比。
|
下面的图形显示了二次曲线和三次曲线的差值方程,“S”代表了点对贝塞尔方程总和的贡献。点击拖动点来看看在特定的<i>t</i>值时,每个曲线定义的点的插值百分比。
|
||||||
</p>
|
</p>
|
||||||
<div class="figure">
|
<div class="figure">
|
||||||
<Graphic
|
<Graphic
|
||||||
@@ -792,9 +792,9 @@ function Bezier(3,t,w[]):
|
|||||||
<p>The function for rational Bézier curves has two more terms:</p>
|
<p>The function for rational Bézier curves has two more terms:</p>
|
||||||
<img
|
<img
|
||||||
class="LaTeX SVG"
|
class="LaTeX SVG"
|
||||||
src="images/latex/39364a247a023d475d107aaf7b99d80c.svg"
|
src="images/latex/3fd61ab3fe88f694e70f61e4f8ea056b.svg"
|
||||||
width="489px"
|
width="407px"
|
||||||
height="44px"
|
height="48px"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
<p>
|
<p>
|
||||||
@@ -804,35 +804,51 @@ function Bezier(3,t,w[]):
|
|||||||
<code>ratio<sub>1</sub> = 0.5</code>, and so on. The second term
|
<code>ratio<sub>1</sub> = 0.5</code>, and so on. The second term
|
||||||
then corrects for all those multiplications by dividing the total
|
then corrects for all those multiplications by dividing the total
|
||||||
value by the "basis" value of the Bézier curve, i.e. the value we
|
value by the "basis" value of the Bézier curve, i.e. the value we
|
||||||
get by computing the curve without any weighting at (but
|
get by computing the curve without any weighting (but
|
||||||
<em>with</em> ratios):
|
<em>with</em> ratios):
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
So what does this actually do? Let's look at the effect of
|
||||||
|
"rationalising" our Bézier curves by interacting with the curve and
|
||||||
|
ratios. The following graphic shows the curve from the previous
|
||||||
|
section, enriched with ratio factors: the closer to zero we set one
|
||||||
|
or more terms, the less relative influence the associated coordinate
|
||||||
|
exerts on the curve (and of course the higher we set them, the more
|
||||||
|
influence they have).
|
||||||
|
</p>
|
||||||
|
<graphics-element
|
||||||
|
title="Our rational cubic Bézier curve"
|
||||||
|
width="275"
|
||||||
|
height="275"
|
||||||
|
src="./chapters/weightcontrol/rational.js"
|
||||||
|
>
|
||||||
|
<fallback-image>
|
||||||
<img
|
<img
|
||||||
class="LaTeX SVG"
|
width="275px"
|
||||||
src="images/latex/03df4af5636ff82d3e964de0b9727f23.svg"
|
height="275px"
|
||||||
width="271px"
|
src="images\chapters\weightcontrol\1128afb7511e00ad4c5e8c0628204b56.png"
|
||||||
height="41px"
|
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
<p>So what does this actually do?</p>
|
Scripts are disabled. Showing fallback image.
|
||||||
<p>
|
</fallback-image>
|
||||||
Let's look at the effect of "rationalising" our Bézier curves by
|
ratio 1
|
||||||
interacting with the curve and ratios. The following graphic shows
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
the curve from the previous section, enriched with ratio factors:
|
>1.0</span
|
||||||
the closer to zero we set one or more terms, the less relative
|
><br />
|
||||||
influence the associated coordinates exert on the curve (and of
|
ratio 2
|
||||||
course the higher we set them, the more influence they have).
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
</p>
|
>1.0</span
|
||||||
<p>
|
><br />
|
||||||
<Graphic title="Our rational cubic Bézier curve"
|
ratio 3
|
||||||
setup={this.drawCubic} draw={this.drawCurve} sliders={[ {min:0,
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 1</code>}, {min:0,
|
>1.0</span
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 2</code>}, {min:0,
|
><br />
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 3</code>}, {min:0,
|
ratio 4
|
||||||
max:2, value:1, step:0.01, label:<code>ratio 4</code>} ]}
|
<input type="range" min="0" max="2" value="1" step="0.01" /><span
|
||||||
setSliders={this.setRatio} onSlide={this.changeRatio}
|
>1.0</span
|
||||||
context={this}/>
|
>
|
||||||
</p>
|
</graphics-element>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You can think of the ratio values as each coordinate's "gravity":
|
You can think of the ratio values as each coordinate's "gravity":
|
||||||
the higher the gravity, the closer to that coordinate the curve will
|
the higher the gravity, the closer to that coordinate the curve will
|
||||||
|