User:Lilyuserin/SVG/bezier

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
     "/>