WaBis

walter.bislins.ch

3D Herz-Kurven

Samstag, 7. September 2013 - 01:02 | Autor: wabis | Themen: Wissen, Mathematik, Genial, Demo | Kommentare(3)

Mathematik muss nicht langweilig und abstrakt sein. Mit etwas Geschick lassen sich mathematische Formeln in interessante 3D Grafiken verwandeln. Diese können sehr ansprechend aussehen, vor allem, wenn sie durch ein geeignetes Grafikprogramm mit Beleuchtungseffekten versehen werden.

In diesem Beitrag kannst du nicht nur schöne Bilder von 3D Herz-Kurven betrachten, sondern auch lernen, wie solche Bilder erzeugt werden. Ich zeige, welche Formeln hinter solchen Grafiken stecken und wie ich diese hergeleitet habe.

Als Bonus für jene, die Zugriff auf Grafik- oder entsprechende Mathematik-Programme haben, liefere ich eine Formel, ich nenne sie den Herz-Generator, mit der fast jede 2D Funktion zu einer 3D Herz-Kurve wird. Unbedingt ausprobieren!

Herz-Galerie

Diese Bilder habe ich mit dem von mir entwickelten Grafik-Programm JsGraph3D erstellt. Damit lassen sich 3D Kurven mit Beleuchtungseffekten im Browser berechnen und darstellen. Du kannst diesen Berechnungen live zusehen, indem du die Demo-Links unterhalb der Bilder anklickst. Die Bilder oben sind mit einer Auflösung von 1000 mal 1000 Flächen gerendert worden. Die Bilder hinter den Demo-Links werden mit einer Auflösung von 300 mal 300 Flächen gezeichnet.

Herz-Formel

Die Bilder der Herz-Galerie sind 3D Darstellungen der folgenden Formel:

(1)
mit
wobei'
' =' 'im Bereich −6·π bis +6·π
' =' 'Kreisradius
' =' 'ergibt einen Bereich von 0 bis 4

Die Farbe der Fläche und deren Ausblendung am Rand wird nach folgendem Algorithmus berechnet:

r = sqrt( x^2 - 1.2*abs(x)*y + y^2 )
z = ( sin( 15 * r^0.2 ) )^2
c = 1 - z
if r > 9.56 then
  // Übergang von rot/weiss nach rot/gelb
  if r > 12 then
    // Ausblenden
    a = e^( -( 0.5 * (r - 12) )^4 )
    color = { red: 1, green: c, blue: 0, alpha: a }
  else
    color = { red: 1, green: c, blue: 0, alpha: 1 }
  end if
else
  // Farben rot/weiss
  color = { red: 1, green: c, blue: c, alpha: 1 }
end if

Eine Beschreibung dieses Algorithmus findest du unter:

Wie man 3D Funktionen zeichnet

ZoomInformationen zum BildAufbau von 3D-Funktionen

Als 3D Funktionen bezeichne ich mathematische Funktionen, die von zwei Variablen abhängig sind:

(2)

f ist eine beliebige Funktion, die aus zwei Werten x und y einen dritten Wert z berechnet. Wenn wir x und y als Koordinaten in einer Ebene und z als dritte Koordinate im Raum betrachten, erhalten wir für jedes Wertepaar x und y und den zugehörigen Wert z einen Punkt im Raum: P( x, y, z ).

Wir können für eine ganze Reihe von XY-Koordinaten die zugehörigen Z-Koordinaten berechnen und erhalten dadurch ein Gitter von Punkten im Raum. Wenn wir benachbarte Punkte durch Linien verbinden, entsteht eine dreidimensionale Fläche wie im Bild gezeigt.

Wir können jedem Flächenelement eine bestimmte Farbe zuweisen, welche z.B. aus den Koordinaten der Fläche berechnet wird. Durch geeignete Grafik-Programme lassen sich zudem Beleuchtungseffekte hinzurechnen. Wenn das Gitter sehr fein gemacht wird, erhalten wir Grafiken wie in der Herz-Galerie.

Für die Grafiken der Herz-Galerie habe ich ein so feines Gitter gewählt, dass 1 002 001 Punkte und 1 000 000 Flächen berechnet worden sind! Dies hat pro Bild auf meinem PC (Intel Core i7 CPU 960 @ 3,2 GHz) im Chrome-Browser (Version 29.0.1547.62 m) 3 Sekunden für alle Berechnungen und 17 Sekunden für das Zeichnen benötigt.

Übrigens ist die Formel (1), auch wenn es auf den ersten Blick nicht so aussieht, dennoch eine Funktion der zwei Variablen x und y. Der Rasius r ist nur ein Zwischenwert. Die Aufsplittung der Formel in zwei Teile macht sie übersichtlicher, weil r zweimal verwendet wird. Als eine Formel geschrieben sieht (1) wiefolgt aus:

(3)

Rotations-Symmetrische 3D Kurven

ZoomInformationen zum BildAufbau einer rotations-symmetrischen 3D Kurve

Auf dem Weg zur Herz-Kurve müssen wir uns zuerst mit rotations-symmetrischen 3D Kurven befassen. Solche Kurven sind im Grunde 2D Funktionen, welche um die Z-Achse rotiert werden. 2D Funktionen sind Funktionen, die nur von einer Variablen abhängig sind, also die folgende Form haben:

(4)

Die blaue Kurve im Bild zeigt eine solche Funktion. Sie stellt den ersten Teil der Herz-Formel (1) dar:

(5)

Wie erhalten wir aus dieser 2D Funktion eine rotations-symmetrische 3D Kurve? Wie rotiert man überhaupt eine Funktion um die Z-Achse, sodass daraus eine Fläche entsteht?

In der Formel (5) kommt statt x und y nur die Variable r vor. Wir müssen also irgendwie aus den beiden XY-Werten eines Punktes einen Wert r berechnen:

Eine 3D Rotations-Kurve erhält man, indem für jeden Punkt der XY-Ebene berechnet wird, wie gross sein Abstand r zur Z-Achse ist. Dieser Abstand kann mit dem Satz von Pythagoras berechnet werden:

(6)

Damit können wir für jedes XY-Wertepaar einen zugehörigen Z-Wert erechnen, indem wir zuerst den Radius r nach Formel (6) berechnen und dann r in die Formel (5) einsetzen.

Mit diesem Verfahren kann aus jeder beliebigen 2D Funktion eine rotations-symmetrische 3D Kurve gezeichnet werden.

Herzförmige 3D Kurven

Vom Kreis zur Herz-Kurve

Das Geheimnis zum Erzeugen einer herzförmigen 3D Kurve liegt im Anwenden von Koordinaten-Transformationen auf eine rotations-symmetrische 3D Kurve. Durch Transformation von Koordinaten könne beliebige 3D Objekte verzerrt, gedreht und gespiegelt werden.

Zuerst möchte ich zeigen, welche Transformationen man auf eine 3D Rotations-Kurve anwenden muss, um eine Herzform zu erhalten. Dann zeige ich, wie man solche Koordinaten-Transformationen berechnet.

Im Bild ist erkennbar, dass die rote Herzform durch Spiegeln der rechten Hälfte der roten Ellipse an der Y-Achse entsteht. Die rot gestrichelte Ellipse wird erzeugt, indem der blau gestrichelte Kreis in Richtung der X-Achse zur blauen Ellipse gedehnt wird. Diese wird danach um den Winkel β im Gegenuhrzeigersinn um den Nullpunkt gedreht.

Damit sind die Transformationen von einer Rotations-Form in eine Herz-Form schon beschrieben:

  1. Dehnen in X-Richtung (Skalieren) um den Faktor a
  2. Rotieren im Gegenuhrzeigersinn um den Winkel β
  3. Spiegeln der rechten Hälfte an der Y-Achse

Koordinaten-Transformationen

Werden alle 3D Punkte einer Rotations-Kurve nacheinander wie oben beschrieben transformiert, wird die Rotations-Kurve zu einer Herz-Kurve verzerrt. Wir müssen nur die XY-Koordinaten aller Punkte transformieren. Die Z-Koordinaten können wir von den ursprünglichen Punkten übernehmen.

Für Transformationen verwendet man Vektoren und Matrizen-Operationen. Für jeden 3D Punkt P( x, y, z ) können wir einen 2D Vektor mit den Komponenten x und y bilden:

(7)

Der Vektor wird transformiert, indem er auf eine bestimmte Art mit der Transformations-Matrix T multipliziert wird (siehe Lineare Algebra). Dabei entsteht ein neuer Vektor . Aus dessen XY-Komponenten und der Z-Komponente von P können wir einen neuen 3D Punkt Q bilden:

(8)

Q ist der mit der Matrix T transformierte Punkt P.

Transformation vom Kreis zur Ellipse

Eine Matrix S, welche einen Kreis in X-Richtung um den Faktor a und in Y-Richtung um den Faktor b zu einer Ellipse deformiert, sieht wiefolgt aus:

(9)

Skalierungs-Matrix

Eine Matrix R, welche eine beliebige Figur um den Winkel β im Gegenuhrzeigersinn dreht, sieht wiefolgt aus:

(10)

Rotations-Matrix

Die beiden Matrizen S und R können durch Matrizenmultiplikation zu einer neuen Matrix T zusammengefasst werden:

(11)

Achtung, die Reihenfolge der Matrizenmultiplikation spielt eine Rolle. Die Transformationen werden von rechts nach links angewandt.

Wir müssen dann den Vektor nur noch mit einer Matrix T multiplizieren um die kombinierte Transformation, zuerst S danach R, zu erhalten.

Inverse Transformation

Mit der oben beschriebenen Koordinaten-Transformation könnten wir eine fertig berechnete rotations-symmetrische Kurve zu einer gedrehten ellipsoiden Kurve transformieren. Wir würden dazu Punkt für Punkt zunächst aus den XY-Koordinaten der Rotations-Kurve den jeweiligen Radius r berechnen, daraus die Z-Koordinate über die 2D Funktion, und schliesslich würden wir die XY-Koordinaten der Rotations-Kurve mit der Matrix T in die XY-Koordinaten der Ellipsen-Kurve transformieren. Die XY-Koordinaten der Ellipsen-Kurve zusammen mit der Z-Koordinate bilden jeweils einen Punkt der Ellipsen-Kurve.

Bei dieser Art der Transformation wird allerdings nicht nur ein Kreis zur Ellipse, sondern auch das zugrundeliegende XY-Koordinaten-Gitter wird zuerst gedehnt und dann gedreht.

Das Problem dabei: Einem Grafik-Programm kann man in der Regel keine Transformations-Matrix übergeben, sondern nur eine Funktion mit zwei Variablen. Das Grafik-Programm generiert ein regelmässiges XY-Koordinaten-Gitter und berechnet über die Funktion die Z-Koordinaten. Das Grafik-Programm gibt somit das Koordinaten-Gitter vor und dieses deckt sich nicht dem transformierten Gitter, in dem die Ellipse liegt.

Wie kommen wir von vorgegebenen XY-Koordinaten der zur berechnenden Ellipsen-Kurve auf die entsprechenden XY-Koordinaten der Rotations-Kurve? Denn wir brauchen für die Berechnung des Z-Wertes der Ellipsen-Kurve den Radius, der aus den entsprechenden XY-Koordinaten der Rotations-Kurve berechnet wird.

Mit der Transformations-Matrix T konnten wir einen Punkt P der Rotations-Kurve in einen entsprechenden Punkt Q der Ellipsen-Kurve transformieren. Wir benötigen aber genau die umgekehrte Transformation.

Dies ist kein Problem, denn wir müssen nur die Inverse Matrix T−1 der Matrix T berechnen, was in unserem Fall besonders einfach ist. Tipp: invertiere die beiden Matrizen S und R separat und multipliziere sie in umgekehrter Reihenfolge miteinander.

(15)
wobei'
' =' 'sin(β)
' =' 'cos(β)

Damit können wir einen Vektor , der aus den XY-Koordinaten eines Punktes Q( x, y, z ) auf der Ellipsen-Kurve gebildet wird, in einen Vektor zurück transformieren, welcher die XY-Kooridnaten des entsprechenden Punktes P( x' ,y' ,z ) auf der Kreis-Kurve enthält:

(16)
Transformation Ellipse in Krei

Ausmultipliziert erhalten wir die Transformations-Formeln für die beiden Koordinaten:

(17)
und
mit
wobei'
' =' 'XY-Koordinaten des Punktes Q auf der Ellipsen-Fläche
' =' 'XY-Koordinaten des zugehörigen Punktes P auf der Kreis-Fläche

Jetzt können wir den Kreisradius r für die Kreis-Koordinaten ( x', y' ) nach Pythagoras berechnen:

(18)
mit
wobei'
' =' 'XY-Koordinaten des Punktes Q auf der Ellipsen-Fläche
' =' 'Rotationswinkel der Ellipse
' =' 'Streckung des Kreises zur Ellipse in der X-Achse
' =' 'Streckung des Kreises zur Ellipse in der Y-Achse

Dieser Radius wird in die 2D Herz-Funktion eingesetzt welche uns den Z-Wert liefert.

Wenn wir mit verschiedenen Winkeln β und Streckungen a und b experimentieren wollen, müssen wir obige Formel (18) zum Berechnen des Radius r verwenden. In den Herz-Kurven auf dieser Seite habe ich mich auf die folgenden Werte festgelegt:

Setze ich diese Vorgaben in die Formel (18) ein, so erhalte ich:

(20)

Bis auf den Faktor 5/8 ist dies schon fast der zweite Teil der Herz-Formel (1). Der Faktor 5/8 spielt für unsere Herz-Formel keine Rolle, denn er beeinflusst lediglich die Grösse der Herzen und diese kann ich jederzeit durch Zoomen des Bildes verändern. Ich lasse diesen Faktor deshalb bei der Herz-Formel weg.

Wenn ich mit obiger Formel die 3D Kurve berechnen würde, würde jedoch noch kein Herz, sondern erst eine gedrehte Ellipse gezeichnet. Wir müssen also die rechte Hälfte der Ellispe noch an der Y-Achse spiegeln.

Spiegeln an der Y-Achse

Spiegeln an der Y-Achse macht aus der Ellipse ein Herz

Um die rechte Hälfte einer beliebige 3D Kurve an der Y-Achse zu spiegeln, müssen wir einfach alle x in der Formel durch den Absolutbetrag |x| ersetzten. So werden alle Punkte mit negativen X-Koordinaten zu Punkten mit positiven X-Koordinaten. Für alle links von der Y-Achse liegenden Punkte werden damit dieselben Z-Werte wie für die entsprechenden Punkte rechts der Y-Achse errechnet. Dies resultiert in einer spiegel-symmetrischen Grafik.

In der Herz-Formel (1) kommen nur im zweiten Teil bei der Berechnung des Radius r X-Werte vor. Bei X-Werten, welche im Quadrat stehen, muss nicht der Absolutbetrag berechnet werden, weil durch die Quadrierung sowieso nur positive Werte entstehen.

Die Formel (20) für den Radius r ändert sich durch die Spiegelung also zu:

(21)

Herz-Generator

Die Formel (21) ist universell einsetzbar um 3D Herz-Kurven zu erzeugen. Man geht von einer beliebigen 2D Funktion f(r) aus und setzt für r die Formel (21) ein:

(22)

beliebige 2D Funktion

mit

Herz-Generator

Damit die Herz-Form in der so erzeugten 3D Kurve erkennbar wird, muss man entweder eine 2D Funktion mit Wellen nehmen, z.B. eine periodische Funktion wie Sinus oder Cosinus, oder die Kurve muss entsprechend eingefärbt werden, z.B. so, dass der Z-Wert die Farbe bestimmt.

2D Herz-Funktion

Bisher habe ich gezeigt, wie wir aus einer 2D Funktion herzförmige 3D Kurven erzeugen können. Was jetzt noch fehlt, ist eine schöne 2D Funktion z = f(r), wie sie das folgende Bild zeigt, und ein Algorithmus für die Färbung der Fläche.

Die dicke rot/weiss/gelbe Kurve ist meine fertige 2D Herz-Funktion mit der entsprechenden Färbung und Ausblendung. Die grüne Hüllkurve beschränkt die 2D Herz-Funktion nach oben. Die blaue Kurve bestimmt ab der vertikalen blauen Linie den Wert des Alpha-Kanals. Der Alpha-Kanal steuert die Durchsichtigkeit der Fläche: 1 für sichtbar bis 0 für unsichtbar. Von r = 0 bis zur vertikalen roten Linie wechselt die Farbe der Herz-Kurve zwischen rot und weiss. Ab der Linie wechselt dann die Farbe zwischen rot und gelb.

Im Skelett-Bild sehen wir die 2D Herz-Funktion blau an der Schnittkante. Gelb ist auch noch die Hüllkurve eingezeichnet.

Aber nun zur Herleitung der Herz-Funktion:

Ich wollte mehrere ineinander verschachtelte Herzen haben. Da bietet sich als periodische Grundfunktion ein Sinus oder Cosinus an. Ich wählte den Sinus und setzte ihn zusätzlich ins Quadrat (also sin(r)2). Dadurch schwingt die Funktion zwischen Null und 1, statt zwischen −1 und +1. So erreiche ich, dass bei der Multiplikation der Grundfunktion mit der Hüllkurve die 2D Funktion zwischen einem positiven Wert und Null pendelt.

Bis jetzt sieht die 2D Herz-Funktion so aus:

(23)

Demo: Funktion 1

Diese 3D Herz-Kurve sieht mir zu langweilig aus; die Abstände zwischen den einzelnen Herzen sind zu regelmässig (klicke auf den Demo-Link um die zugehörige Grafik berechnen zu lassen).

Wenn ich den Radius mit einem Wert kleiner 1 potenziere (0,2 schien mir ein passender Wert), wird der Sinus bei Radien kleiner 1 gestaucht und bei Radien grösser 1 gedehnt. Damit erreiche ich, dass die Herzen im Zentrum näher beieinander liegen als weiter draussen. Damit der Sinus nicht allzusehr gestreckt wird, multipliziere ich noch mit 15. So erhalte ich 3 Wellen innerhalb eines Radius von 1 und 6 Wellen bis zu einem Radius von ca. 13:

(24)

Demo: Funktion 2

Jetzt sieht das Ganze noch etwas flach aus. Ich verpasse daher der Herz-Funktion noch eine Hüllkurve. Diese soll die bisherige Funktion bei r kleiner 1 verkleinern und bei r grösser 1 vergrössern. Die naheliegendste Lösung wäre, die ganze Formel mit r zu multiplizieren. Diese einfache Hüllkurve steigt mir aber viel zu stark an. Wenn ich aber r mit einem Wert kleiner 1 potenziere, steigt die Hüllkurve wesentlich moderater an (grüne bzw. gelbe Kurve). Als Exponent schien mir 0,6 passend (0,5 würde der Quadratwurzel entsprechen).

Damit ist meine 2D Herz-Funktion vollständig:

(25)

Demo: Funktion 3

Färben der Herz-Kurve

Das Einfärben ist relativ einfach. Ich verwende einfach die Funktion (24) um einen Farb-Parameter c zu berechnen:

(26)

Demo: In Farbe

Der Parameter c entspricht der 2D Herz-Funktion ohne Hüllkurve, hat also denselben Verlauf, jedoch einen Wertebereich der immer zwischen 0 und 1 wechselt. Mit diesem Wert kann ich die Farb-Kanäle rot, grün und blau so steuern, dass die Herz-Kurve zwischen rot und weiss, bzw. ab einem Radius von 9,56 zwischen rot und gelb wechselt.

Technisch funktioniert das Einfärben mit Hilfe meines Grafikprogrammes wiefolgt:

Es lässt sich eine Funktion installieren, die aufgerufen wird, bevor ein Flächenelement gezeichnet wird. Diese Funktion erhält als Argumente das Flächenelement und ein Objekt, welches u.a. die Farbe und den Alphakanal für dieses Flächenelement enthält. In dieser Funktion kann ich nun mit der Formel (26) einen Farbparameter c berechnen und damit die Farbe und den Alphakanal für dieses Flächenelement verändern. Diese Daten werden vom Grafikprogramm, nach eventueller Beleuchtungs-Berechnung, auf das Flächenelement beim Zeichnen angewandt.

Ausblenden der Herz-Kurve

Zum Ausblenden der Herz-Kurve über den Alpha-Kanal brauche ich eine Funktion, welche von einem Wert 1 mit grösser werdendem Radius langsam auf den Wert 0 verläuft.

PerfektGleichungG2.png

Es gibt eine Reihe von Funktionen, die teilweise dieser Anforderung entsprechen (siehe Bild). Wenn ich eine dieser Funktionen an die Stelle r = 12 verschiebe und etwas dehne, kann ich die rechte Hälfte der Funktion für die Steuerung des Alpha-Kanals brauchen.

Als Grundfunktion für das Ausblenden wähle ich:

(27)
wobei'
' =' 'Wert für den Alpha-Kanal
' =' 'Radius der 2D Funktion

In dieser Form ist die Kurve aber noch zu schmal und liegt bei Null statt an der Position 12. Indem ich in der Formel (27) den Radius mit 0,5 multipliziere, dehne ich die Funktion um den Faktor 2:

(28)

Indem ich in der Formel (28) r durch r−12 ersetze, verschiebe ich die Funktion an die Stelle r = 12:

(29)

Dies ist endlich die letzt Formel für unsere 3D Herz-Kurven!

Kommentare

1Marco Todesco 07.09.2013 | 08:46

Walti! Du bist der Hammer!
Super!

2Peterle 27.12.2017 | 22:26

Hallo Walti.

Auf der Experimenta in Frankfurt bin ich über eine Gleichung gestolpert,
die vermutlich einen Bezug zur Herzkurve hat.

Als mathematisch völlig unbegabter Mensch bin ich nicht in der Lage,
dies Aufzulösen oder eine für mich verständliche Ableitung daraus zu produzieren.

Kann jemand, der es versteht dies jemand idiotenfreundlich im Stil von "Mathe für Dummys" erklären?

(url)

herzliche Grüße,

Peterle

Externe Links und Bilder im Kommentar sind deaktiviert und werden nicht angezeigt!
Der Admin aktiviert nach Überprüfung die Links und Bilder.
3Peterle 27.12.2017 | 22:37

der andere link tut nicht, der hier ist besser:
(url)

sehr infromativ war auch (url)
brachte mich der lösung allerdings auch nicht näher

Externe Links und Bilder im Kommentar sind deaktiviert und werden nicht angezeigt!
Der Admin aktiviert nach Überprüfung die Links und Bilder.
Dein Kommentar zu diesem Artikel
Name
Email optional; wird nicht angezeigt
Kommentar
  • Name wird bei deinem Kommentar angezeigt.
  • Email ist nur für den Administrator, sie wird nicht angezeigt.
  • Du kannst deine Kommentare eine Zeit lang editieren oder löschen.
  • Du kannst Formatierungen im Kommentar verwenden, z.B: Code, Formeln, usw.
  • Externen Links und Bilder werden nicht angezeigt, bis sie der Admin freischaltet.
More Page Infos / Sitemap
Created Samstag, 7. September 2013
Scroll to Top of Page
Changed Montag, 18. März 2019