Superformel
Die Superformel beschreibt spezielle Kurven in der Ebene. Sie wurde 1997 von dem belgischen Wissenschaftler Johan Gielis veröffentlicht.
Die Kurven hängen von den Längen der Halbachsen a und b und den Parametern m, n1, n2 und n3 ab. Die Punkte (r, φ) der Kurve in Polarkoordinaten ergeben sich anhand der Gleichung
1 / r = (abs((1 / a) cos(1/4 m φ)) ^ n2 + abs((1 / b) sin(1/4 m φ)) ^ n3) ^ (1 / n1)
Die Methode draw-super-curve lässt eine Schildkröte (siehe Schildkröten-Grafik) eine dieser Kurven entlangwandern. Dabei sind die Halbachsen a und b fest auf 1 gesetzt. Für die Parameter m, n1, n2 und n3 können positive, ganze Zahlen angegeben werden. Außerdem kann die Größe der Kurve festgelegt werden.
(defmethod draw-super-curve ((this turtle) m n1 n2 n3 size)
(and
(integer? m)
(integer? n1)
(integer? n2)
(integer? n3)
(>= m 1)
(>= n1 1)
(>= n2 1)
(>= n3 1)
(>= size 1))
(move-to-translated-points
this
(close-curve
(get-superformula-points
m n1 n2 n3
(. this heading)
(. this *pi*)
size))))
Die Methode move-to-translated-points stellt sicher, dass die aktuelle Position der Schildkröte auf dem Rand der Kurve liegt.
(defproc move-to-translated-points (turtle points)
(let
((translation (- (. turtle position) (first points))))
(dolist (point points)
(move-to turtle (+ point translation)))))
Die Funktion get-superformula-points berechnet eine Liste von Punkten auf der Kurve. Dabei wird die Hilfsfunktion estimate-length benutzt, um die Zahl der Punkte so festzulegen, dass das entstehende Bild eine gute Qualität hat (d.h. nicht eckig erscheint).
(defproc get-superformula-points (m n1 n2 n3 heading *pi* size)
(let
((edges (estimate-length m n1 n2 n3))
(angle (* 2/360 *pi* heading)))
(let
((step (* 2 *pi* (/ edges))))
(map-with
(lambda (i)
(round
(from-polar
(* size (get-radius m n1 n2 n3 (+ angle (* step i)) 1e-15))
(* step i)
1e-15)))
(range 0 edges)))))
(defproc estimate-length (m n1 n2 n3)
(* 4 m (+ n2 n3)))
Die Funktionen get-radius und get-inverse-radius berechnen den Radius bzw. dessen Kehrwert aus den Parametern der Kurve und dem Winkel.
(defproc get-radius (m n1 n2 n3 angle precision)
(/ (get-inverse-radius m n1 n2 n3 angle precision)))
(defproc get-inverse-radius (m n1 n2 n3 angle precision)
(let
((xy (from-polar 1 (* 1/4 m angle) precision)))
(root
(+ (expt (abs (real xy)) n2)
(expt (abs (imaginary xy)) n3))
n1
precision)))
Die Hilfsfunktion close-curve sorgt dafür, dass die Liste der Punkte eine geschlossene Kurve ergibt.
(defproc close-curve (points)
(cons (first (last points)) points))
Quellen
https://de.wikipedia.org/wiki/Superformel
https://en.wikipedia.org/wiki/Superformula
Die Kurven hängen von den Längen der Halbachsen a und b und den Parametern m, n1, n2 und n3 ab. Die Punkte (r, φ) der Kurve in Polarkoordinaten ergeben sich anhand der Gleichung
1 / r = (abs((1 / a) cos(1/4 m φ)) ^ n2 + abs((1 / b) sin(1/4 m φ)) ^ n3) ^ (1 / n1)
Die Methode draw-super-curve lässt eine Schildkröte (siehe Schildkröten-Grafik) eine dieser Kurven entlangwandern. Dabei sind die Halbachsen a und b fest auf 1 gesetzt. Für die Parameter m, n1, n2 und n3 können positive, ganze Zahlen angegeben werden. Außerdem kann die Größe der Kurve festgelegt werden.
(defmethod draw-super-curve ((this turtle) m n1 n2 n3 size)
(and
(integer? m)
(integer? n1)
(integer? n2)
(integer? n3)
(>= m 1)
(>= n1 1)
(>= n2 1)
(>= n3 1)
(>= size 1))
(move-to-translated-points
this
(close-curve
(get-superformula-points
m n1 n2 n3
(. this heading)
(. this *pi*)
size))))
Die Methode move-to-translated-points stellt sicher, dass die aktuelle Position der Schildkröte auf dem Rand der Kurve liegt.
(defproc move-to-translated-points (turtle points)
(let
((translation (- (. turtle position) (first points))))
(dolist (point points)
(move-to turtle (+ point translation)))))
Die Funktion get-superformula-points berechnet eine Liste von Punkten auf der Kurve. Dabei wird die Hilfsfunktion estimate-length benutzt, um die Zahl der Punkte so festzulegen, dass das entstehende Bild eine gute Qualität hat (d.h. nicht eckig erscheint).
(defproc get-superformula-points (m n1 n2 n3 heading *pi* size)
(let
((edges (estimate-length m n1 n2 n3))
(angle (* 2/360 *pi* heading)))
(let
((step (* 2 *pi* (/ edges))))
(map-with
(lambda (i)
(round
(from-polar
(* size (get-radius m n1 n2 n3 (+ angle (* step i)) 1e-15))
(* step i)
1e-15)))
(range 0 edges)))))
(defproc estimate-length (m n1 n2 n3)
(* 4 m (+ n2 n3)))
Die Funktionen get-radius und get-inverse-radius berechnen den Radius bzw. dessen Kehrwert aus den Parametern der Kurve und dem Winkel.
(defproc get-radius (m n1 n2 n3 angle precision)
(/ (get-inverse-radius m n1 n2 n3 angle precision)))
(defproc get-inverse-radius (m n1 n2 n3 angle precision)
(let
((xy (from-polar 1 (* 1/4 m angle) precision)))
(root
(+ (expt (abs (real xy)) n2)
(expt (abs (imaginary xy)) n3))
n1
precision)))
Die Hilfsfunktion close-curve sorgt dafür, dass die Liste der Punkte eine geschlossene Kurve ergibt.
(defproc close-curve (points)
(cons (first (last points)) points))
Quellen
https://de.wikipedia.org/wiki/Superformel
https://en.wikipedia.org/wiki/Superformula