splitting + image regen
@@ -2,7 +2,7 @@
|
||||
|
||||
Using de Casteljau's algorithm, we can also find all the points we need to split up a Bézier curve into two, smaller curves, which taken together form the original curve. When we construct de Casteljau's skeleton for some value `t`, the procedure gives us all the points we need to split a curve at that `t` value: one curve is defined by all the inside skeleton points found prior to our on-curve point, with the other curve being defined by all the inside skeleton points after our on-curve point.
|
||||
|
||||
<Graphic title="Splitting a curve" setup={this.setupCubic} draw={this.drawSplit} />
|
||||
<graphics-element title="Splitting a curve" width="825" src="./splitting.js"></graphics-element>
|
||||
|
||||
<div class="howtocode">
|
||||
|
||||
@@ -32,7 +32,3 @@ function drawCurve(points[], t):
|
||||
After running this function for some value `t`, the `left` and `right` arrays will contain all the coordinates for two new curves - one to the "left" of our `t` value, the other on the "right". These new curves will have the same order as the original curve, and can be overlaid exactly on the original curve.
|
||||
|
||||
</div>
|
||||
|
||||
This is best illustrated with an animated graphic (click to play/pause):
|
||||
|
||||
<Graphic title="Bézier curve splitting" setup={this.setupCubic} draw={this.drawAnimated} onClick={this.togglePlay} />
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
ベジエ曲線を分割して、繫ぎ合わせたときに元に戻るような小さい2曲線にしたい場合にも、ド・カステリョのアルゴリズムを使えば、これに必要な点をすべて求めることができます。ある値`t`に対してド・カステリョの骨格を組み立てると、その`t`で曲線を分割する際に必要になる点がすべて得られます。骨格内部の点のうち、曲線上の点から見て手前側にある点によって一方の曲線が定義され、向こう側にある点によってもう一方の曲線が定義されます。
|
||||
|
||||
<Graphic title="曲線の分割" setup={this.setupCubic} draw={this.drawSplit} />
|
||||
<graphics-element title="曲線の分割" width="825" src="./splitting.js"></graphics-element>
|
||||
|
||||
<div class="howtocode">
|
||||
|
||||
@@ -32,7 +32,3 @@ function drawCurve(points[], t):
|
||||
ある値`t`に対してこの関数を実行すると、`left`と`right`に新しい2曲線の座標が入ります。一方は`t`の「左」側、もう一方は「右」側の曲線です。この2曲線は元の曲線と同じ次数になり、また元の曲線とぴったり重なります。
|
||||
|
||||
</div>
|
||||
|
||||
これはアニメーションで見るのがわかりやすいでしょう(クリックで再生・停止します)。
|
||||
|
||||
<Graphic title="ベジエ曲線の分割" setup={this.setupCubic} draw={this.drawAnimated} onClick={this.togglePlay} />
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
使用 de Casteljau 算法我们也可以将一条贝塞尔曲线分割成两条更小的曲线,二者拼接起来即可形成原来的曲线。当采用某个 `t` 值构造 de Casteljau 算法时,该过程会给到我们在 `t` 点分割曲线的所有点: 一条曲线包含该曲线上点之前的所有点,另一条曲线包含该曲线上点之后的所有点。
|
||||
|
||||
<Graphic title="分割一条曲线" setup={this.setupCubic} draw={this.drawSplit} />
|
||||
<graphics-element title="分割一条曲线" width="825" src="./splitting.js"></graphics-element>
|
||||
|
||||
<div class="howtocode">
|
||||
|
||||
@@ -32,7 +32,3 @@ function drawCurve(points[], t):
|
||||
对某个给定 `t` 值,该函数执行后,数组 `left` 和 `right` 将包含两条曲线的所有点的坐标 -- 一条是`t`值左侧的曲线,一条是`t`值右侧的曲线, 与原始曲线同序且完全重合。
|
||||
|
||||
</div>
|
||||
|
||||
以下是带动画效果的最好的演示(点击以播放/暂停):
|
||||
|
||||
<Graphic title="贝塞尔曲线的分割" setup={this.setupCubic} draw={this.drawAnimated} onClick={this.togglePlay} />
|
||||
|
28
chapters/splitting/keepthisornot.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
|
||||
/*
|
||||
|
||||
// const { left, right } = this.getLeftAndRight(this.t, this.curve.points);
|
||||
// const c1 = new Bezier(this, left);
|
||||
// const c2 = new Bezier(this, right);
|
||||
|
||||
getLeftAndRight(t, points, left=[], right=[]) {
|
||||
if(points.length === 1) {
|
||||
left.push(points[0]);
|
||||
right.push(points[0]);
|
||||
return { left, right };
|
||||
}
|
||||
|
||||
let newpoints = points.slice(1);
|
||||
for(let i=0; i<newpoints.length; i++) {
|
||||
if(i === 0) left.push(points[i]);
|
||||
if(i === newpoints.length-1) right.push(points[i+1]);
|
||||
newpoints[i] = {
|
||||
x: (1-t) * points[i].x + t * points[i+1].x,
|
||||
y: (1-t) * points[i].y + t * points[i+1].y,
|
||||
}
|
||||
}
|
||||
|
||||
return this.getLeftAndRight(t, newpoints, left, right);
|
||||
}
|
||||
*/
|
82
chapters/splitting/splitting.js
Normal file
@@ -0,0 +1,82 @@
|
||||
setup() {
|
||||
this.t = 0.5;
|
||||
this.curve = Bezier.defaultCubic(this);
|
||||
setMovable(this.curve.points);
|
||||
}
|
||||
|
||||
draw() {
|
||||
resetTransform();
|
||||
clear();
|
||||
|
||||
let p = this.curve.get(this.t);
|
||||
const struts = this.struts = this.curve.getStrutPoints(this.t);
|
||||
const c1 = new Bezier(this, [struts[0], struts[4], struts[7], struts[9]]);
|
||||
const c2 = new Bezier(this, [struts[9], struts[8], struts[6], struts[3]]);
|
||||
|
||||
this.drawBasics(p);
|
||||
|
||||
translate(this.width/3, 0);
|
||||
setStroke(`black`);
|
||||
line(0, 0, 0, this.height);
|
||||
|
||||
this.drawSegment(c1, p);
|
||||
|
||||
translate(this.width/3, 0);
|
||||
setStroke(`black`);
|
||||
line(0, 0, 0, this.height);
|
||||
|
||||
this.drawSegment(c2, p);
|
||||
}
|
||||
|
||||
drawBasics(p) {
|
||||
this.curve.drawCurve(`lightgrey`);
|
||||
this.curve.drawSkeleton(`lightgrey`);
|
||||
this.curve.drawPoints(false);
|
||||
noFill();
|
||||
setStroke(`red`);
|
||||
circle(p.x, p.y, 3);
|
||||
|
||||
setStroke(`lightblue`);
|
||||
this.curve.drawStruts(this.struts);
|
||||
setFill(`black`)
|
||||
text(`The full curve, with struts`, 10, 15);
|
||||
}
|
||||
|
||||
drawSegment(c, p) {
|
||||
setStroke(`lightblue`);
|
||||
this.curve.drawCurve(`lightblue`);
|
||||
this.curve.drawSkeleton(`lightblue`);
|
||||
this.curve.drawStruts(this.struts);
|
||||
c.drawCurve();
|
||||
c.drawSkeleton(`black`);
|
||||
noFill();
|
||||
setStroke(`red`);
|
||||
circle(p.x, p.y, 3);
|
||||
setFill(`black`)
|
||||
text(`The first half`, 10, 15);
|
||||
}
|
||||
|
||||
onKeyDown() {
|
||||
let key = this.keyboard.currentKey;
|
||||
|
||||
if(key === `ArrowUp`) {
|
||||
this.t += 0.01;
|
||||
}
|
||||
|
||||
if(key === `ArrowDown`) {
|
||||
this.t -= 0.01
|
||||
}
|
||||
|
||||
this.t = this.t < 0 ? 0 : this.t > 1 ? 1 : this.t;
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
onMouseMove() {
|
||||
if (this.cursor.down && !this.currentPoint) {
|
||||
this.t = map(this.cursor.y, 0,this.height, 0, 1);
|
||||
} else {
|
||||
this.curve.update();
|
||||
}
|
||||
redraw();
|
||||
}
|
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 967 B |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 9.2 KiB |
BIN
images/chapters/flattening/1a22ba71ef9a5aaf9c55e0b8c2f3f6e5.png
Normal file
After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 4.5 KiB |
BIN
images/chapters/flattening/6fd4fa0aca97b89939624de9339acf11.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 4.9 KiB |
BIN
images/chapters/splitting/9482f3b5bc36c11395525fefb67dd18b.png
Normal file
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
36
index.html
@@ -585,7 +585,7 @@
|
||||
<img
|
||||
width="825px"
|
||||
height="275px"
|
||||
src="images\chapters\whatis\b2e7a2bc650cbed9d750e8afc40a1aa3.png"
|
||||
src="images\chapters\whatis\f91cf03cba43b012c66a8f310097ced6.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
@@ -1586,7 +1586,7 @@ function RationalBezier(3,t,w[],r[]):
|
||||
<img
|
||||
width="275px"
|
||||
height="275px"
|
||||
src="images\chapters\flattening\3eb70cd7ada74dfe1417ddb572730597.png"
|
||||
src="images\chapters\flattening\6fd4fa0aca97b89939624de9339acf11.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
@@ -1602,7 +1602,7 @@ function RationalBezier(3,t,w[],r[]):
|
||||
<img
|
||||
width="275px"
|
||||
height="275px"
|
||||
src="images\chapters\flattening\04573510619447c4361c7768ac0175cf.png"
|
||||
src="images\chapters\flattening\1a22ba71ef9a5aaf9c55e0b8c2f3f6e5.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
@@ -1660,11 +1660,22 @@ function RationalBezier(3,t,w[],r[]):
|
||||
curve being defined by all the inside skeleton points after our
|
||||
on-curve point.
|
||||
</p>
|
||||
<Graphic
|
||||
<graphics-element
|
||||
title="Splitting a curve"
|
||||
setup="{this.setupCubic}"
|
||||
draw="{this.drawSplit}"
|
||||
/>
|
||||
width="825"
|
||||
height="275"
|
||||
src="./chapters/splitting/splitting.js"
|
||||
>
|
||||
<fallback-image>
|
||||
<img
|
||||
width="825px"
|
||||
height="275px"
|
||||
src="images\chapters\splitting\9482f3b5bc36c11395525fefb67dd18b.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
</fallback-image></graphics-element
|
||||
>
|
||||
|
||||
<div class="howtocode">
|
||||
<h3>implementing curve splitting</h3>
|
||||
@@ -1697,17 +1708,6 @@ function drawCurve(points[], t):
|
||||
overlaid exactly on the original curve.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This is best illustrated with an animated graphic (click to
|
||||
play/pause):
|
||||
</p>
|
||||
<Graphic
|
||||
title="Bézier curve splitting"
|
||||
setup="{this.setupCubic}"
|
||||
draw="{this.drawAnimated}"
|
||||
onClick="{this.togglePlay}"
|
||||
/>
|
||||
</section>
|
||||
<section id="matrixsplit">
|
||||
<h1><a href="#matrixsplit">Splitting curves using matrices</a></h1>
|
||||
|
@@ -487,7 +487,7 @@
|
||||
<img
|
||||
width="825px"
|
||||
height="275px"
|
||||
src="images\chapters\whatis\b2e7a2bc650cbed9d750e8afc40a1aa3.png"
|
||||
src="images\chapters\whatis\f91cf03cba43b012c66a8f310097ced6.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
@@ -1229,7 +1229,7 @@ function RationalBezier(3,t,w[],r[]):
|
||||
<img
|
||||
width="275px"
|
||||
height="275px"
|
||||
src="images\chapters\flattening\3eb70cd7ada74dfe1417ddb572730597.png"
|
||||
src="images\chapters\flattening\6fd4fa0aca97b89939624de9339acf11.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
@@ -1245,7 +1245,7 @@ function RationalBezier(3,t,w[],r[]):
|
||||
<img
|
||||
width="275px"
|
||||
height="275px"
|
||||
src="images\chapters\flattening\04573510619447c4361c7768ac0175cf.png"
|
||||
src="images\chapters\flattening\1a22ba71ef9a5aaf9c55e0b8c2f3f6e5.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
@@ -1285,11 +1285,22 @@ function RationalBezier(3,t,w[],r[]):
|
||||
<p>
|
||||
ベジエ曲線を分割して、繫ぎ合わせたときに元に戻るような小さい2曲線にしたい場合にも、ド・カステリョのアルゴリズムを使えば、これに必要な点をすべて求めることができます。ある値<code>t</code>に対してド・カステリョの骨格を組み立てると、その<code>t</code>で曲線を分割する際に必要になる点がすべて得られます。骨格内部の点のうち、曲線上の点から見て手前側にある点によって一方の曲線が定義され、向こう側にある点によってもう一方の曲線が定義されます。
|
||||
</p>
|
||||
<Graphic
|
||||
<graphics-element
|
||||
title="曲線の分割"
|
||||
setup="{this.setupCubic}"
|
||||
draw="{this.drawSplit}"
|
||||
/>
|
||||
width="825"
|
||||
height="275"
|
||||
src="./chapters/splitting/splitting.js"
|
||||
>
|
||||
<fallback-image>
|
||||
<img
|
||||
width="825px"
|
||||
height="275px"
|
||||
src="images\chapters\splitting\9482f3b5bc36c11395525fefb67dd18b.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
</fallback-image></graphics-element
|
||||
>
|
||||
|
||||
<div class="howtocode">
|
||||
<h3>曲線分割の実装方法</h3>
|
||||
@@ -1316,16 +1327,6 @@ function drawCurve(points[], t):
|
||||
ある値<code>t</code>に対してこの関数を実行すると、<code>left</code>と<code>right</code>に新しい2曲線の座標が入ります。一方は<code>t</code>の「左」側、もう一方は「右」側の曲線です。この2曲線は元の曲線と同じ次数になり、また元の曲線とぴったり重なります。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
これはアニメーションで見るのがわかりやすいでしょう(クリックで再生・停止します)。
|
||||
</p>
|
||||
<Graphic
|
||||
title="ベジエ曲線の分割"
|
||||
setup="{this.setupCubic}"
|
||||
draw="{this.drawAnimated}"
|
||||
onClick="{this.togglePlay}"
|
||||
/>
|
||||
</section>
|
||||
<section id="matrixsplit">
|
||||
<h1><a href="#matrixsplit">行列による曲線の分割</a></h1>
|
||||
|
@@ -71,11 +71,11 @@ class Bezier extends Original {
|
||||
return closest;
|
||||
}
|
||||
|
||||
drawCurve() {
|
||||
drawCurve(color = `#333`) {
|
||||
const ctx = this.ctx;
|
||||
ctx.cacheStyle();
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = `#333`;
|
||||
ctx.strokeStyle = color;
|
||||
ctx.beginPath();
|
||||
const lut = this.getLUT().slice();
|
||||
let p = lut.shift();
|
||||
@@ -88,7 +88,7 @@ class Bezier extends Original {
|
||||
ctx.restoreStyle();
|
||||
}
|
||||
|
||||
drawPoints() {
|
||||
drawPoints(labels = true) {
|
||||
const colors = [`red`, `green`, `blue`, `yellow`];
|
||||
const api = this.api;
|
||||
const ctx = this.ctx;
|
||||
@@ -99,50 +99,59 @@ class Bezier extends Original {
|
||||
this.points.forEach((p, i) => {
|
||||
api.setFill(colors[i % colors.length]);
|
||||
api.circle(p.x, p.y, 5);
|
||||
api.setFill(`black`);
|
||||
api.text(`(${p.x},${p.y})`, p.x + 10, p.y + 10);
|
||||
if (labels) {
|
||||
api.setFill(`black`);
|
||||
api.text(`(${p.x},${p.y})`, p.x + 10, p.y + 10);
|
||||
}
|
||||
});
|
||||
ctx.restoreStyle();
|
||||
}
|
||||
|
||||
drawSkeleton(t = false) {
|
||||
drawSkeleton(color = `#555`) {
|
||||
const api = this.api;
|
||||
const ctx = this.ctx;
|
||||
ctx.cacheStyle();
|
||||
const p = this.points;
|
||||
ctx.strokeStyle = `#555`;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(p[0].x, p[0].y);
|
||||
ctx.lineTo(p[1].x, p[1].y);
|
||||
ctx.lineTo(p[2].x, p[2].y);
|
||||
|
||||
if (p[3]) {
|
||||
ctx.lineTo(p[3].x, p[3].y);
|
||||
if (t !== false) {
|
||||
// TODO: additional cubic struts
|
||||
// ... code goes here ...
|
||||
}
|
||||
}
|
||||
ctx.stroke();
|
||||
api.noFill();
|
||||
api.setStroke(color);
|
||||
api.start();
|
||||
p.forEach((v) => api.vertex(v.x, v.y));
|
||||
api.end();
|
||||
ctx.restoreStyle();
|
||||
}
|
||||
|
||||
drawStruts(t) {
|
||||
getStrutPoints(t) {
|
||||
const p = this.points.map((p) => new Vector(p));
|
||||
const mt = 1 - t;
|
||||
|
||||
let s = 0;
|
||||
let n = p.length + 1;
|
||||
while (--n > 1) {
|
||||
let list = p.slice(s, s + n);
|
||||
for (let i = 0, e = list.length - 1; i < e; i++) {
|
||||
let pt = list[i + 1].subtract(list[i + 1].subtract(list[i]).scale(mt));
|
||||
p.push(pt);
|
||||
}
|
||||
s += n;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
drawStruts(t) {
|
||||
const p = t.forEach ? t : this.getStrutPoints(t);
|
||||
|
||||
const api = this.api;
|
||||
const ctx = api.ctx;
|
||||
ctx.cacheStyle();
|
||||
api.noFill();
|
||||
|
||||
let s = 0;
|
||||
let n = p.length + 1;
|
||||
let s = this.points.length;
|
||||
let n = this.points.length;
|
||||
while (--n > 1) {
|
||||
let list = p.slice(s, s + n);
|
||||
api.start();
|
||||
for (let i = 0, e = list.length - 1; i < e; i++) {
|
||||
let pt = list[i + 1].subtract(list[i + 1].subtract(list[i]).scale(mt));
|
||||
p.push(pt);
|
||||
for (let i = 0; i < n; i++) {
|
||||
let pt = p[s + i];
|
||||
api.vertex(pt.x, pt.y);
|
||||
api.circle(pt.x, pt.y, 5);
|
||||
}
|
||||
@@ -150,8 +159,6 @@ class Bezier extends Original {
|
||||
s += n;
|
||||
}
|
||||
ctx.restoreStyle();
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -62,7 +62,8 @@ async function createIndexPages(locale, localeStrings, chapters) {
|
||||
const start = Date.now();
|
||||
const data = prettier.format(index, { parser: `html` });
|
||||
const end = Date.now();
|
||||
console.log(`beautification for ${locale} took ${(end - start) / 1000}s`);
|
||||
|
||||
//console.log(`beautification for ${locale} took ${(end - start) / 1000}s`);
|
||||
|
||||
if (locale === defaultLocale) {
|
||||
fs.writeFileSync(`index.html`, data, `utf8`);
|
||||
|
@@ -77,7 +77,7 @@ async function processLocale(locale, localeStrings, chapterFiles) {
|
||||
}
|
||||
|
||||
const end = Date.now();
|
||||
console.log(`Processing ${locale} took ${(end - start) / 1000}s`);
|
||||
// console.log(`Processing ${locale} took ${(end - start) / 1000}s`);
|
||||
|
||||
return chapters;
|
||||
}
|
||||
|
@@ -472,7 +472,7 @@
|
||||
<img
|
||||
width="825px"
|
||||
height="275px"
|
||||
src="images\chapters\whatis\b2e7a2bc650cbed9d750e8afc40a1aa3.png"
|
||||
src="images\chapters\whatis\f91cf03cba43b012c66a8f310097ced6.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
@@ -1195,7 +1195,7 @@ function RationalBezier(3,t,w[],r[]):
|
||||
<img
|
||||
width="275px"
|
||||
height="275px"
|
||||
src="images\chapters\flattening\3eb70cd7ada74dfe1417ddb572730597.png"
|
||||
src="images\chapters\flattening\6fd4fa0aca97b89939624de9339acf11.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
@@ -1211,7 +1211,7 @@ function RationalBezier(3,t,w[],r[]):
|
||||
<img
|
||||
width="275px"
|
||||
height="275px"
|
||||
src="images\chapters\flattening\04573510619447c4361c7768ac0175cf.png"
|
||||
src="images\chapters\flattening\1a22ba71ef9a5aaf9c55e0b8c2f3f6e5.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
@@ -1253,11 +1253,22 @@ function RationalBezier(3,t,w[],r[]):
|
||||
<code>t</code> 点分割曲线的所有点:
|
||||
一条曲线包含该曲线上点之前的所有点,另一条曲线包含该曲线上点之后的所有点。
|
||||
</p>
|
||||
<Graphic
|
||||
<graphics-element
|
||||
title="分割一条曲线"
|
||||
setup="{this.setupCubic}"
|
||||
draw="{this.drawSplit}"
|
||||
/>
|
||||
width="825"
|
||||
height="275"
|
||||
src="./chapters/splitting/splitting.js"
|
||||
>
|
||||
<fallback-image>
|
||||
<img
|
||||
width="825px"
|
||||
height="275px"
|
||||
src="images\chapters\splitting\9482f3b5bc36c11395525fefb67dd18b.png"
|
||||
loading="lazy"
|
||||
/>
|
||||
Scripts are disabled. Showing fallback image.
|
||||
</fallback-image></graphics-element
|
||||
>
|
||||
|
||||
<div class="howtocode">
|
||||
<h3>分割曲线的代码实习</h3>
|
||||
@@ -1289,14 +1300,6 @@ function drawCurve(points[], t):
|
||||
与原始曲线同序且完全重合。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>以下是带动画效果的最好的演示(点击以播放/暂停):</p>
|
||||
<Graphic
|
||||
title="贝塞尔曲线的分割"
|
||||
setup="{this.setupCubic}"
|
||||
draw="{this.drawAnimated}"
|
||||
onClick="{this.togglePlay}"
|
||||
/>
|
||||
</section>
|
||||
<section id="matrixsplit">
|
||||
<h1><a href="#matrixsplit">Splitting curves using matrices</a></h1>
|
||||
|