Längen- und Breitenkreise

Um Längen- und Breitenkreise darzustellen, wird auf einer grundlegende Funktion make-circle aufgebaut. Diese liefert ein Polygon mit count Ecken als Annäherung an einen Kreis. Der Mittelpunkt des Kreises wird durch den Punkt m angegeben. Der Kreis liegt in der Ebene, die durch den Punkt m und die beiden orthogonalen Einheitsvektoren u und v festgelegt wird. Der Radius des Kreises ist r.

(defproc make-circle (u v m r count precision)
  (let
    ((*pi* (pi precision))
     (points nil))
    (dotimes (i count (cons (first (last points)) points))
      (let
        ((xy (get-xy (* 2 i *pi* (/ count)) precision)))
        (push
          (list
            (+ (first m) (* r (first xy) (first u)) (* r (second xy) (first v)))
            (+ (second m) (* r (first xy) (second u)) (* r (second xy) (second v)))
            (+ (third m) (* r (first xy) (third u)) (* r (second xy) (third v))))
          points)))))

Die Hilfsfunktion get-xy liefert Punkte auf dem Einheitskreis. Sie verwendet die Funktion to-list, um komplexe Zahlen in zweielementige Listen umzuwandeln. Außerdem verwendet get-xy die Funktion cosine-sine, die den Cosinus und den Sinus zu einem Winkel als komplexe Zahl liefert (siehe Polarkoordinaten).

(defproc get-xy (d precision)
  (to-list (cosine-sine d precision)))

(defmethod to-list ((this complex))
  t
  (list (. this real) (. this imaginary)))

(defmethod to-list (r)
  (number? r)
  (list r 0))

Breitenkreise liegen in Ebenen, die parallel zur Äquatorialebene sind. Für die Darstellung der Kreise bedeutet das, dass man in eine Ebene parallel zur x- und z-Achse zeichnet. Deshalb wird für u (1 0 0) und v (0 0 1) angegeben. Der Sinus des Breitengrads wird mit dem Radius der Kugel multipliziert. Das Produkt gibt eine Verschiebung entlang der y-Achse an und legt den Mittelpunkt des Breitenkreises fest. Das Produkt aus Cosinus des Breitengrads und Kugelradius ergibt den Radius des Breitenkreises.

(defproc make-circle-of-latitude (latitude r count precision)
  (let
    ((xy (get-xy (degrees-to-radian latitude precision) precision)))
    (make-circle
      (list 1 0 0)
      (list 0 0 1)
      (list 0 (* r (second xy)) 0)
      (* r (first xy))
      count
      precision)))

Längenkreise gehen durch beide Pole. Deshalb liegt die y-Achse in ihrer Zeichenebene und v ist (0 1 0). Der Mittelpunkt der Längenkreise ist der Erdmittelpunkt, deshalb ist m (0 0 0). Die Wahl von u hängt vom Längengrad ab. Man beginnt mit einem Einheitsvektor auf der x-Achse und dreht diesen um die y-Achse um u zu erhalten. Der Radius eines Längenkreises entspricht immer dem Kugelradius.

(defproc make-circle-of-longitude (longitude r count precision)
  (let
    ((xy (get-xy (degrees-to-radian longitude precision) precision)))
    (make-circle
      (list (first xy) 0 (second xy))
      (list 0 1 0)
      (list 0 0 0)
      r
      count
      precision)))

Die Hilfsfunktion degrees-to-radian rechnet von Angaben in Grad in Werte im Bogenmaß um.

(defproc degrees-to-radian (d precision)
  (* 2/360 (pi precision) d))

Mit

(list
  (make-circle-of-longitude 0 1 40 1e-5)
  (make-circle-of-longitude 30 1 40 1e-5)
  (make-circle-of-longitude 60 1 40 1e-5)
  (make-circle-of-latitude -60 1 40 1e-5)
  (make-circle-of-latitude -30 1 40 1e-5)
  (make-circle-of-latitude 0 1 40 1e-5)
  (make-circle-of-latitude 30 1 40 1e-5)
  (make-circle-of-latitude 60 1 40 1e-5))

erhält man eine Liste von Polygonen, die die Längen- und Breitenkreise alle 30 Grad angeben. Die Zentralprojektion kann diese Polygone im Zweidimensionalen darstellen - siehe unten.


Anlage

Zentralprojektion von Längen- und Breitenkreisen

circles-latitude-longitude.sheet.xml