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.
(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.