Подогнать кривую SVG полиному - PullRequest
7 голосов
/ 08 января 2012

Предполагая, что у меня есть функции, такие как x² или 2x + 3x², как можно создать SVG-путь, соответствующий этим функциям?

Из моего ограниченного понимания кривых SVG и Безье Я считаю, что я ищу for - это простой метод построения контрольных точек Безье, который обеспечит соответствие полученного графа заданной функции. Вы можете смело предположить (если вы еще не догадались), что я новичок в графическом программировании. Я знаю, что фреймворки, такие как gnuplot , могут выполнять этот тип интерполяции, но я ищу больше объяснений о том, как сделать это вручную, используя SVG и JavaScript .

РЕДАКТИРОВАТЬ: Точное соответствие не является строгим требованием, но полученный график должен быть достаточно точным (в учебных целях).

1 Ответ

9 голосов
/ 08 января 2012
<?xml version="1.0" standalone="no"?>

SVG предоставляет кривые Безье порядка 2 и 3, которые должны быть достаточно хороши для квадратичных и кубических полиномов.

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="20cm" height="20cm" viewBox="0 0 1000 1000"
    xmlns="http://www.w3.org/2000/svg" version="1.1">
  <style type="text/css"><![CDATA[
    .axis { fill: none; stroke: black; stroke-width: 3; }
    .tick { fill: none; stroke: black; stroke-width: 1; }
    .fun1 { fill: none; stroke: blue; stroke-width: 2; }
    .fun2 { fill: none; stroke: red; stroke-width: 2; }
  ]]></style>
  <polyline class="axis" points="0,500 1000,500" />
  <polyline class="tick" points="0,490 0,510" />
  <polyline class="tick" points="100,490 100,510" />
  <polyline class="tick" points="200,490 200,510" />
  <polyline class="tick" points="300,490 300,510" />
  <polyline class="tick" points="400,490 400,510" />
  <polyline class="tick" points="600,490 600,510" />
  <polyline class="tick" points="700,490 700,510" />
  <polyline class="tick" points="800,490 800,510" />
  <polyline class="tick" points="900,490 900,510" />
  <polyline class="tick" points="1000,490 1000,510" />
  <polyline class="axis" points="500,0 500,1000" />
  <polyline class="tick" points="490,0 510,0" />
  <polyline class="tick" points="490,100 510,100" />
  <polyline class="tick" points="490,200 510,200" />
  <polyline class="tick" points="490,300 510,300" />
  <polyline class="tick" points="490,400 510,400" />
  <polyline class="tick" points="490,600 510,600" />
  <polyline class="tick" points="490,700 510,700" />
  <polyline class="tick" points="490,800 510,800" />
  <polyline class="tick" points="490,900 510,900" />
  <polyline class="tick" points="490,1000 510,1000" />

Взять y = x² - 4, с конечными точками (-3, 5) и (3, 5); касательные имеют вид y = -6x - 13 и y = 6x - 13. Поместите одну контрольную точку Q на обе касательные в точке (0, -13). Это должно работать легко для любого квадратичного.

  <path class="fun1" d="M200,0 Q500,1800 800,0" />

Кубики немного обмануты. При y = (x³ - 9x) / 16 от (-5, -5) до (5, 5) касательные имеют вид y = (33x + 125) / 8 и y = (33x - 125) / 8. Видя, что кривая должна пройти через (0, 0) с наклоном -9/16, это простой расчет, чтобы найти C контрольных точек (-5/3, 35/4) и (5/3, 35/4). Вероятно, большую часть времени это невозможно сделать вручную, но я думаю, что этот подход должен быть численно выполнимым для любой другой кубики - две переменные для определения того, как далеко вдоль каждой касательной лежат контрольные точки, и два ограничения, форсирующие конкретную точку и направление.

  <path class="fun2" d="M0,1000 C333,-375 667,1375 1000,0" />

( Анимированные кривые Безье были очень полезны, когда я их разрабатывал.)

</svg>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...