1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-31 12:01:54 +02:00

this rename is absolutely stupid

This commit is contained in:
Pomax
2020-08-20 13:01:32 -07:00
parent 59fdafb2c5
commit d92e370bd1
470 changed files with 22 additions and 9 deletions

View File

@@ -0,0 +1,42 @@
# Simplified drawing
We can also simplify the drawing process by "sampling" the curve at certain points, and then joining those points up with straight lines, a process known as "flattening", as we are reducing a curve to a simple sequence of straight, "flat" lines.
We can do this is by saying "we want X segments", and then sampling the curve at intervals that are spaced such that we end up with the number of segments we wanted. The advantage of this method is that it's fast: instead of evaluating 100 or even 1000 curve coordinates, we can sample a much lower number and still end up with a curve that sort-of-kind-of looks good enough. The disadvantage of course is that we lose the precision of working with "the real curve", so we usually can't use the flattened for for doing true intersection detection, or curvature alignment.
<graphics-element title="Flattening a quadratic curve" src="./quadratic.js"></graphics-element>
<graphics-element title="Flattening a cubic curve" src="./cubic.js"></graphics-element>
Try clicking on the sketch and using your up and down arrow keys to lower the number of segments for both the quadratic and cubic curve. You'll notice that for certain curvatures, a low number of segments works quite well, but for more complex curvatures (try this for the cubic curve), a higher number is required to capture the curvature changes properly.
<div class="howtocode">
### How to implement curve flattening
Let's just use the algorithm we just specified, and implement that:
```
function flattenCurve(curve, segmentCount):
step = 1/segmentCount;
coordinates = [curve.getXValue(0), curve.getYValue(0)]
for(i=1; i <= segmentCount; i++):
t = i*step;
coordinates.push[curve.getXValue(t), curve.getYValue(t)]
return coordinates;
```
And done, that's the algorithm implemented. That just leaves drawing the resulting "curve" as a sequence of lines:
```
function drawFlattenedCurve(curve, segmentCount):
coordinates = flattenCurve(curve, segmentCount)
coord = coordinates[0], _coord;
for(i=1; i < coordinates.length; i++):
_coord = coordinates[i]
line(coord, _coord)
coord = _coord
```
We start with the first coordinate as reference point, and then just draw lines between each point and its next point.
</div>

View File

@@ -0,0 +1,42 @@
# 簡略化した描画
曲線を複数点で「サンプリング」し、さらにそれを直線で繫げてしまえば、描画の手順を簡略化することができます。単なる一連の直線、つまり「平坦」な線へと曲線を単純化するので、この処理は「平坦化」という名前で知られています。
例えば「X個の線分がほしい」場合には、分割数がそうなるようにサンプリング間隔を選び、曲線をサンプリングします。この方法の利点は速さです。曲線の座標を100個だの1000個だの計算するのではなく、ずっと少ない回数のサンプリングでも、十分きれいに見えるような曲線を作ることができるのです。欠点はもちろん、「本物の曲線」に比べて精度が損なわれてしまうことです。したがって、交点の検出や曲線の位置揃えを正しく行いたい場合には、平坦化した曲線は普通利用できません。
<graphics-element title="2次ベジエ曲線の平坦化" src="./quadratic.js"></graphics-element>
<graphics-element title="3次ベジエ曲線の平坦化" src="./cubic.js"></graphics-element>
2次ベジエ曲線も3次ベジエ曲線も、図をクリックして上下キーを押すと曲線の分割数が増減しますので、試してみてください。ある曲線では分割数が少なくてもうまくいきますが、曲線が複雑になればなるほど、曲率の変化を正確に捉えるためにはより多くの分割数が必要になることがわかります3次ベジエ曲線で試してみてください
<div class="howtocode">
### 曲線平坦化の実装方法
上でいま解説したアルゴリズムを使って実装するだけです。
```
function flattenCurve(curve, segmentCount):
step = 1/segmentCount;
coordinates = [curve.getXValue(0), curve.getYValue(0)]
for(i=1; i <= segmentCount; i++):
t = i*step;
coordinates.push[curve.getXValue(t), curve.getYValue(t)]
return coordinates;
```
これで完了です。実装できました。あとは、一連の直線で結果の「曲線」を描画するだけです。
```
function drawFlattenedCurve(curve, segmentCount):
coordinates = flattenCurve(curve, segmentCount)
coord = coordinates[0], _coord;
for(i=1; i < coordinates.length; i++):
_coord = coordinates[i]
line(coord, _coord)
coord = _coord
```
先頭の座標を参照点にしてスタートし、あとはそれぞれの点からその次の点へと、直線を引いていくだけです。
</div>

View File

@@ -0,0 +1,42 @@
# 简化绘图
我们可以简化绘制的过程,先在具体的位置“采样”曲线,然后用线段把这些点连接起来。由于我们是将曲线转换成一系列“平整的”直线,故将这个过程称之为“拉平(flattening)”。
我们可以先确定“想要X个分段”然后在间隔的地方采样曲线得到一定数量的分段。这种方法的优点是速度很快比起遍历100甚至1000个曲线坐标我们可以采样比较少的点仍然得到看起来足够好的曲线。这么做的缺点是我们失去了“真正的曲线”的精度因此不能用此方法来做真实的相交检测或曲率对齐。
<graphics-element title="拉平一条二次曲线" src="./quadratic.js"></graphics-element>
<graphics-element title="拉平一条三次曲线" src="./cubic.js"></graphics-element>
试着点击图形,并用上下键来降低二次曲线和三次曲线的分段数量。你会发现对某些曲率来说,数量少的分段也能做的很好,但对于复杂的曲率(在三次曲线上试试),足够多的分段才能很好地满足曲率的变化。
<div class="howtocode">
### 如何实现曲线的拉平
让我们来实现刚才简述过的算法:
```
function flattenCurve(curve, segmentCount):
step = 1/segmentCount;
coordinates = [curve.getXValue(0), curve.getYValue(0)]
for(i=1; i <= segmentCount; i++):
t = i*step;
coordinates.push[curve.getXValue(t), curve.getYValue(t)]
return coordinates;
```
好了,这就是算法的实现。它基本上是画出一系列的线段来模拟“曲线”。
```
function drawFlattenedCurve(curve, segmentCount):
coordinates = flattenCurve(curve, segmentCount)
coord = coordinates[0], _coord;
for(i=1; i < coordinates.length; i++):
_coord = coordinates[i]
line(coord, _coord)
coord = _coord
```
我们将第一个坐标作为参考点,然后在相邻两个点之间画线。
</div>

View File

@@ -0,0 +1,45 @@
setup() {
this.steps = 8;
this.curve = Bezier.defaultCubic(this);
setMovable(this.curve.points);
}
draw() {
clear();
this.curve.drawSkeleton();
noFill();
start();
for(let i=0, e=this.steps; i<=e; i++) {
let p = this.curve.get(i/e);
vertex(p.x, p.y);
}
end();
this.curve.drawPoints();
setFill(`black`);
text(`Flattened to ${this.steps} segments`, 10, 15);
}
onKeyDown() {
let key = this.keyboard.currentKey;
if(key === `ArrowUp`) {
this.steps++;
}
if(key === `ArrowDown`) {
if(this.steps > 1) this.steps--;
}
redraw();
}
onMouseMove() {
if (this.cursor.down && !this.currentPoint) {
this.steps = round( map(this.cursor.y, 0,this.height, 24, 1) );
}
redraw();
}

View File

@@ -0,0 +1,45 @@
setup() {
this.steps = 4;
this.curve = Bezier.defaultQuadratic(this);
setMovable(this.curve.points);
}
draw() {
clear();
this.curve.drawSkeleton();
noFill();
start();
for(let i=0, e=this.steps; i<=e; i++) {
let p = this.curve.get(i/e);
vertex(p.x, p.y);
}
end();
this.curve.drawPoints();
setFill(`black`);
text(`Flattened to ${this.steps} segments`, 10, 15);
}
onKeyDown() {
let key = this.keyboard.currentKey;
if(key === `ArrowUp`) {
this.steps++;
}
if(key === `ArrowDown`) {
if(this.steps > 1) this.steps--;
}
redraw();
}
onMouseMove() {
if (this.cursor.down && !this.currentPoint) {
this.steps = round( map(this.cursor.y, 0,this.height, 16, 1) );
}
redraw();
}