User:Lilyuserin/SVG/bezier

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search

Allgmeines

[edit]

SVG kann keine Funktionen darstellen, sondern ist auf Gerade, Kreise, Ellipsen und Bezierkurven beschränkt.

Wie kann ich genügend glatte mindestens 2x stetig differenzierbare Funktionen durch Bezierkurven annähern.

[edit]

Berechnung

[edit]

Gegegeben seien vier Punkte einer (genügend glatten, sprich mindestens 2x stetig differenzierbaren) Funktion, und mit . Dann errechnen sich die Stützpunkte einer (von vielen möglichen) Bezierkurve folendermaßen:

Setzt man , so kann man leicht nachrechnen, dass und ist.

Beispiel 1

[edit]

Das einfachste kubische Polynom

ergibt folgende Stützpunkte:

Berechnung

[edit]

=

Der besseren Veranschaulichung halber habe ich eine zweite Kurve eingezeichnet (blau), deren X-Achse auf das 10-fache gestreckt ist.

Beispiel 2

[edit]

Das kubische Polynom (der Einfachheit halber symmetrisch zum Ursprung)

lässt sich exakt als Kombination einer Bezierkurve und ihrer Spiegelung am Ursprung darstellen.

Sinusfunktion

[edit]

Ich habe die Sinusfunktion im 1. Quadranten approximiert. Zum Vergleich habe ich eine Sinuskurve durch 45 äquidistante Stützstellen und linerare Interpolation erzeugt, in der Grafik in grau.

Die ursprünglich berechnete Bezierkurve (cyan) hat im Endpunkt eine Tangente, die nicht exakt horizontal ist. Daher habe ich eine zweite Bezierkurve (dunkelblau) erzeugt, indem ich die Y-Koordinate des 2. Stützpunktes durch die Y-Koordinate des Endpunktes ersetzt habe.

Verblüffend ist die Übereinstimmung der Bezierkurve mit der Sinuskurve, obwohl nur 4 Punkte approximiert wurden.

Winkel Wert Näherung
0 0 0 0 0
30 0.5 209 18*209-9*362+2*418=1340 -9*209+18*362-5*418=2545
60 362 233.33 848.33
90 1 418
45 0.7071 577 18*577-9*816+2*577=4196 -9*577+18*816-5*577=6610
90 1 816 699.33 1001.67
135 0.7071 577

SVG Code

[edit]
<?xml version="1.0" encoding="UTF-8"?>
<svg
 version="1.1"
 viewBox="-10 -500 920 610"
 height="610" width="920"
 xmlns:xlink="http://www.w3.org/1999/xlink"
 xmlns="http://www.w3.org/2000/svg">
 <title>Sinuskurve approximiert durch eine einzelne Bezierkurve</title>
 <defs>
  <pattern id="_10px" width="10" height="10" patternUnits="userSpaceOnUse">
   <path d="M0,0 H10 M0,10 V0" opacity=".6" stroke="lime" stroke-width=".5"/>
  </pattern>
  <pattern id="_50px" width="50" height="50" patternUnits="userSpaceOnUse">
   <path d="M0,0 H50 M0,50 V0" stroke="#0a0"/>
  </pattern>
  <pattern id="_100px" width="100" height="100" patternUnits="userSpaceOnUse">
   <path d="M0,0 H100 M0,100 V0" stroke="#080" stroke-width="1.5"/>
  </pattern>
  <rect id="paper" x="-10" y="-1100" width="400%" height="400%"/>
  <path id="sinuskurve" d="m0 0 2 3.4899 2 3.4857 2 3.4772 2 3.4645 2 3.4475
  2 3.4264 2 3.401 2 3.3715 2 3.338 2 3.3003 2 3.2586 2 3.213
  2 3.1635 2 3.11 2 3.0528 2 2.9919 2 2.9274 2 2.8592 2 2.7876
  2 2.7126 2 2.6343 2 2.5528 2 2.4681 2 2.3805 2 2.29 2 2.1966
  2 2.1006 2 2.0021 2 1.9011 2 1.7977 2 1.6922 2 1.5846 2 1.4751
  2 1.3638 2 1.2509 2 1.1364 2 1.0205 2 0.9034 2 0.78519 2 0.66602
  2 0.54603 2 0.42538 2 0.30422 2 0.18268 2 0.060917"/>
  <path id="bezierapprox" d="m0 0c300 233.33 600 424.17 900 418"/>
  <path id="bezierapprox1" d="m0 0c300 233.33 600 418 900 418"/>
  <path id="con" d="m0 0 300 233.33m600 184.67-300 6"/>
  <path id="con1" d="m0 0 300 233.33m600 184.67h-300"/>
 </defs>
 <g transform="scale(.5 .418)" opacity=".5">
  <use fill="url(#_10px)" xlink:href="#paper"/>
  <use fill="url(#_50px)" xlink:href="#paper"/>
  <use fill="url(#_100px)" xlink:href="#paper"/>
 </g>
 <g transform="scale(1,-1)">
  <g fill="cyan" stroke="cyan">
   <use fill="none" xlink:href="#bezierapprox"/>
   <circle r="7"/>
   <circle cx="300" cy="233" r="7"/>
   <circle cx="600" cy="424" r="7"/>
   <circle cx="900" cy="418" r="7"/>
   <use fill="none" xlink:href="#con"/>
  </g>
  <g fill="grey" stroke="grey">
   <circle cx="300" cy="209" r="5"/>
   <circle cx="600" cy="362" r="5"/>
   <use transform="scale(10,4.18)" fill="none" stroke-width=".3" xlink:href="#sinuskurve"/>
  </g>
  <g fill="blue" stroke="blue">
   <use fill="none" xlink:href="#bezierapprox1"/>
   <use fill="none" xlink:href="#con1"/>
   <circle cx="600" cy="418" r="7"/>
  </g>
 </g>
 <g font-family="Liberation Serif">
  <text font-size="20" text-anchor="middle">
   <tspan x="0" y="20">0</tspan>
   <tspan x="300" y="-180">30</tspan>
   <tspan x="600" y="-340">60</tspan>
   <tspan x="900" y="-400">90</tspan>
  </text>
 </g>
</svg>

Sinus eine volle Periode

[edit]

Pfad

[edit]
<path id="sinus" transform="scale(.5,-1.19617)"
  d="m0 0
     c300 233.33 600 418 900 418 s600 -185 900 -418
     s600 -418 900 -418 s600 185 900 418
     s600 418 900 418"/>

Arcus Sinus

[edit]
<path id="sinus" transform="scale(.46444,-1)"
  d="m0 0
     c-300 -233.33 -600 -418 -900 -418
     M0,0 c300 233.33 600 418 900 418
     "/>
  <path id="arcsinus" transform="scale(-1,-.46444)"
  d="m418 -900
     c0,300 -185.33,600 -418,900
     s-418,600 -418,900
     "/>