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


superformula.sheet.xml

Anlage

Kurven für a = b = 1 und unterschiedliche Parameterwerte