2016-11-06 7 views
2

Ich möchte eine Funktion in Python schreiben, um das Kreuzverhältnis von vier projektiven Punkten zu berechnen, und ich frage mich, ob es eine elegante und prägnante Implementierung gibt, mit unendlichen Fällen umzugehen.Berechnen des Querverhält nisses

Eine naive Implementierung des Kreuzverhältnis sieht wie folgt aus:

ratio = lambda a,b,c: (a-c)/(b-c) 
cross_ratio = lambda a,b,c,d: ratio(a,b,c)/ratio(a,b,d) 

Aber das schlägt fehl, wenn einer der Eingänge Infinity ist. Das sollte nicht passieren, aber wir möchten, dass die Unendlichkeiten sich gegenseitig aufheben und uns ein einfaches Verhältnis geben.

Zum Beispiel sollte das Querverhältnis von Infinity, 0, 1, -1-1 sein.

Auch würde ich gerne Punkte als ein Verhältnis von zwei Zahlen ausgedrückt behandeln. So würde (1 1) sein die Zahl 1, während (1,0)Infinity darstellen würde, usw.

konnte mir immer mit ihm zurück zu einer Definition von Fällen und machen tun fallen, aber ich finde, dass das eine gute Gelegenheit sein gutes Design zu lernen.

Ich benutze Python 2.7 und das Sagemath-Modul. Irgendwelche Ratschläge zur Umsetzung?

Antwort

1

Ich würde versuchen, diese:

def det2(a, b): return a[0]*b[1] - a[1]*b[0] 
def cr2(a, b, c, d): return vector([det2(a,c)*det2(b,d), det2(a,d)*det2(b,c)]) 

Dies würde homogene Koordinaten auf Eingabe verwenden, so würde man zwei Elemente Vektoren INOUT-. Es würde auch sein Ergebnis in homogenen Koordinaten als Zwei-Element-Vektor zurückgeben, so dass Sie eine saubere Beschreibung des unendlichen Kreuzverhältnisses erhalten könnten. Wenn Sie das Ergebnis als ein Element von einem Feld stattdessen benötigen, verwenden Sie nur Teilung anstelle des Vektors Konstruktor:

def cr2(a, b, c, d): return (det2(a,c)*det2(b,d))/(det2(a,d)*det2(b,c)) 

ich das Suffix 2 meiner Formeln hinzugefügt, weil persönlich oft ich das Kreuz Verhältnis von vier kollineare Punkte müssen in das Flugzeug. In diesem Fall würde ich

def det3(a, b, c): 
    return matrix([a,b,c]).det() # Or spell this out, if you prefer 
def cr3(a, b, c, d, x): 
    return vector([det3(a,c,x)*det3(b,d,x), det3(a,d,x)* det3(b,c,x)]) 

Nun lassen Sie x jeder Punkt verwenden nicht kollinear mit a,b,c,d und Sie das Kreuz Verhältnis dieser vier Punkte. Oder allgemeiner, wenn a,b,c,d nicht kollinear sind, erhalten Sie das Querverhältnis der vier Linien, die diese mit x verbinden, was für eine Anzahl von Szenarien nützlich sein kann, von denen viele Kegelschnitte beinhalten.

1

Das Beste ist, mit der projektiven Linie zu arbeiten.

Die Dokumentation enthält hier nützliche Hinweise: http://doc.sagemath.org/html/en/reference/schemes/sage/schemes/projective/projective_space.html

Hier ist eine Implementierung des Quer Verhältnis, mit Beispielen.

sage: P = ProjectiveSpace(1, QQ) 
sage: oo, zero, one = P(1, 0), P(0, 1), P(1, 1) 
sage: tm = P.point_transformation_matrix 
sage: def cross_ratio(a, b, c, d): 
....:  a, b, c, d = P(a), P(b), P(c), P(d) 
....:  m = tm([a, b, c], [oo, zero, one]) 
....:  return P(list(m*vector(list(d)))) 
....: 
sage: cross_ratio(oo, zero, one, 1/2) 
(1/2 : 1) 
sage: cross_ratio(1, 2, 3, 4) 
(4/3 : 1) 
Verwandte Themen