mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-09-02 12:54:23 +02:00
82 lines
6.0 KiB
Markdown
82 lines
6.0 KiB
Markdown
# Контроль кривых Безье
|
||
|
||
Кривые Безье, как и все отрезки кривых, являются интерполярными функциями. Это значит, что они имеют заданный набор контрольных точек и генерируют значения где-то "между" ними. (Одним следствием этого есть то, что невозможно сгенерировать точки вне этого "каркаса". Полезная информация!). На практике мы можем проиллюстрировать влияние каждой контрольной точки на течение кривой по отдельности и проследить какие из точек имеют наибольший эффект в тех и иных частях кривой.
|
||
|
||
Следующие зарисовки демонстрируют интерполяции функций для квадратной и кубической кривых, где "S" представляет степень влияния контрольной точки на положение участка кривой по ходу развития t. Потяните ползунки, чтобы отследить проценты интерполяций каждой контрольной точки на конкретном <i>t</i>.
|
||
|
||
<div class="figure">
|
||
<graphics-element title="Квадратная интерполяция" src="./lerp.js" data-degree="3">
|
||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||
</graphics-element>
|
||
<graphics-element title="Кубическая интерполяция" src="./lerp.js" data-degree="4">
|
||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||
</graphics-element>
|
||
<graphics-element title="Интерполяция кривой 15-го порядка" src="./lerp.js" data-degree="15">
|
||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||
</graphics-element>
|
||
</div>
|
||
|
||
Также представлена интерполяция кривой Безье 15<sup>го</sup> порядка. Как вы можете видеть, начальная и конечная точки влияют на положение кривой значительно больше, чем любая другая контрольная точка.
|
||
|
||
Желая изменить кривую, нам нужно изменить "вес"-а (* коофициенты) для каждой точки, по сути меняя интерполяцию. Имплементация оного предельно логична: нужно просто перемножить каждую точку на значение, меняющее ее 'силу'. Эти значения, по конвенции называют "весом" и мы можем учесть их запись в нашей оригинальной функции Безье:
|
||
|
||
\[
|
||
Bézier(n,t) = \sum_{i=0}^{n}
|
||
\underset{\textit{биноминальный термин}}{\underbrace{\binom{n}{i}}}
|
||
\cdot\
|
||
\underset{\textit{полиноминальный термин}}{\underbrace{(1-t)^{n-i} \cdot t^{i}}}
|
||
\cdot\
|
||
\underset{\textit{вес}}{\underbrace{w_i}}
|
||
\]
|
||
|
||
Хоть и выглядит заморочено, но, так уж получается, в реальности "веса" просто значения координат на графике, к которым мы бы хотели, чтобы наша функция стремилась. Так, для кривой <i>n-го</i> порядка, w<sub>0</sub> есть начальной координатой, w<sub>n</sub> конечной координатой, а все между ними — контрольными координатами. Например, чтобы кубическая кривая начиналась в (110,150), стремилась к точкам (25,190) и (210,250) заканчиваясь на (210,30), мы запишем это следующим образом:
|
||
|
||
\[
|
||
\left \{ \begin{matrix}
|
||
x = DARKRED[110] \cdot (1-t)^3 + DARKGREEN[25] \cdot 3 \cdot (1-t)^2 \cdot t + DARKBLUE[210] \cdot 3 \cdot (1-t) \cdot t^2 + AMBER[210] \cdot t^3 \\
|
||
y = DARKRED[150] \cdot (1-t)^3 + DARKGREEN[190] \cdot 3 \cdot (1-t)^2 \cdot t + DARKBLUE[250] \cdot 3 \cdot (1-t) \cdot t^2 + AMBER[30] \cdot t^3
|
||
\end{matrix} \right.
|
||
\]
|
||
|
||
Это производит кривую, график которой мы видели в первой главе этой статьи.
|
||
|
||
<graphics-element title="Наша кубическая кривая Безье" src="../introduction/cubic.js"></graphics-element>
|
||
|
||
Что еще можно сделать с кривой Безье? На самом деле — вполне не мало. Остальная часть статьи описывает множества доступных операций и задач, которые они решают.
|
||
|
||
<div class="howtocode">
|
||
|
||
### Имплементация весовых функций.
|
||
|
||
Отталкиваясь от того, что мы уже знаем как воплотить базис функции, добавление контрольных точек представляет собой удивительно легкую задачу:
|
||
|
||
```
|
||
function Bezier(n,t,w[]):
|
||
sum = 0
|
||
for(k=0; k<=n; k++):
|
||
sum += w[k] * binomial(n,k) * (1-t)^(n-k) * t^(k)
|
||
return sum
|
||
```
|
||
|
||
И оптимизированная версия:
|
||
|
||
```
|
||
function Bezier(2,t,w[]):
|
||
t2 = t * t
|
||
mt = 1-t
|
||
mt2 = mt * mt
|
||
return w[0]*mt2 + w[1]*2*mt*t + w[2]*t2
|
||
|
||
function Bezier(3,t,w[]):
|
||
t2 = t * t
|
||
t3 = t2 * t
|
||
mt = 1-t
|
||
mt2 = mt * mt
|
||
mt3 = mt2 * mt
|
||
return w[0]*mt3 + 3*w[1]*mt2*t + 3*w[2]*mt*t2 + w[3]*t3
|
||
```
|
||
|
||
И вот, мы знаем как программировать базис функции с весами.
|
||
|
||
</div>
|