image image


Eine Vektorklasse (nicht nur) für P5 (Python)

Erinnert Ihr Euch, wie ich eine Vektorklasse für NodeBox 1 (und zwar in der Fork von Karsten Wolf) implementiert (und erweitert) hatte? Ich hatte sie so allgemein gehalten, daß sie nicht nur für die NodeBox, sondern auch in anderen Python-Bibliotheken (wie zum Beispiel dem Turtle-Modul) einsetzbar war. Das kommt mir jetzt für meine Experimente mit P5 (Python), dem »native«-Python-Mode für Processing, zugute.

image

Zwar hat Abhik Pal seinem P5 (Python) schon eine Vektorklasse in Anlehnung an PVector spendiert, aber ihr fehlen doch noch einige wichtige Methoden wie zum Beispiel heading(). Daher habe ich meine Anfang des Jahres in Python geschriebene Klasse wieder hervorgekramt und geschaut, ob sie auch mit P5 (Python) läuft. Und wie der Screenshot oben zeigt – sie läuft. 😎

Und weil ich sie gerade vorliegen hatte, habe ich sie gleich noch um drei Funktionen erweitert, die vielleicht nicht zwingend notwendig sind, die ich aber – seitdem ich in meinem letzten Python-Kurs Operator-Überladung behandelt hatte – ziemlich cool finde: __add__(), um zwei Vektoren wie gewohnt mit dem +-Symbol addieren zu können, __sub__, um zwei Vektoren mit dem --Symbol subtrahieren zu können und __str__() für eine nette Text-Repräsentation des Vektors. Die Methoden __mul__() und __truediv()__ habe ich weggelassen, da sie im Zusammenhang mit der Vektormathematik nicht unbedingt eindeutig sind. Denn ob das *-Symbol eine skalare Multiplikation oder das dot- oder das cross-Produkt meint, verwirrt vermutlich mehr als das es den Quelltext lesbarer macht. Ähnliches gilt natürlich auch für das Divisionssymbol /.

Die neuen Methoden habe ich wie folgt implementiert:

    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        result = PVector(x, y)
        return(result)
    
    def __sub__(self, other):
        x = self.x - other.x
        y = self.y - other.y
        result = PVector(x, y)
        return(result)
    
    def __str__(self):
        return("[ " + str(self.x) + ", " + str(self.y) + " ]")

Wie Ihr seht, sind auch diese Methoden völlig unabhängig und können sowohl in der Knotenschachtel, wie im Turtle-Modul, in P5 (Python) oder in jedem beliebigen anderen Python-Programmm verwendet werden.

Ein Namenskonflikt mit der in P5 eingebauten Vektorklasse ist auch nicht zu befürchten, da diese dort Vector und nicht PVector heißt.

Da die ersten beiden Implementierungen nun schon eine Weile her sind, hier noch mal der Quelltext des vollständigen Moduls:

import math

class PVector():
    
    def __init__(self, x, y):
        self.x = x
        self.y = y

# -- neu 21.01.18 -- #
    
    def set(self, v):
        self.x = v.x
        self.y = v.y
    
    def get(self):
        v = PVector(self.x, self.y)
        return(v)

# -- /neu 21.01.18 -- #
    
    def add(self, v):
        self.x += v.x
        self.y += v.y
        
    def sub(self, v):
        self.x -= v.x
        self.y -= v.y
    
    # Multiplikation mit einem Skalar
    def mult(self, n):
        self.x *= n
        self.y *= n
    
    # Division durch einen Skalar
    def div(self, n):
        self.x /= n
        self.y /= n

# -- neu 21.01.18 -- #

    # Elementweise Multiplikation eines Vektor mit einem anderen Vektor
    def mult2(self, v):
        self.x *= v.x
        self.y *= v.y

    # Elementweise Division eines Vektor mit einem anderen Vektor
    def div2(self, v):
        self.x /= v.x
        self.y /= v.y

# -- /neu 21.01.18 -- #

    # Magnitude
    def mag(self):
        return (math.sqrt(self.x*self.x + self.y*self.y))
    
    # Normalisierung
    def normalize(self):
        m = self.mag()
        if (m != 0):
            self.div(m)

# -- neu 21.01.18 -- #

    # Berechnung der euklidischen Distanz zwischen zwei Vektoren
    def dist(self, v):
        dx = self.x - v.x
        dy = self.y - v.y
        return (math.sqrt(dx*dx + dy+dy))
    
    # Berechnung des Skalarprodukts (inneren Produkts) eines Vektors
    def dot(self, v):
        return self.x*v.x + self.y*v.y
    
    # Begrenzt die Magnitude eines Vektors auf max
    def limit(self, max):
        if self.mag() > max:
            self.normalize()
            self.mult(max)
    
    # Berechnet den Winkel der Rotation eines Vektors
    def heading(self):
        angle = math.atan2(-self.y, self.x)
        return -1*angle

# -- /neu 21.01.18 -- #

# -- neu 19.11.18 -- #

    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        result = PVector(x, y)
        return(result)
    
    def __sub__(self, other):
        x = self.x - other.x
        y = self.y - other.y
        result = PVector(x, y)
        return(result)
    
    def __str__(self):
        return("[ " + str(self.x) + ", " + str(self.y) + " ]")
        
# -- /neu 19.11.18 -- #

Es steht unter der MIT-Lizenz und Ihr könnt es – natürlich auf eigene Gefahr – überall verwenden. Falls Ihr Fehler findet oder Verbesserungsvorschläge habt, bin ich für Hinweise in meinen (Email-) Kommentaren dankbar. Still digging!


(Kommentieren) 

image image



Über …

Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter, Autor, Netzaktivist und Hundesportler — Reihenfolge rein zufällig). Hier steht, was mir gefällt. Wem es nicht gefällt, der braucht ja nicht mitzulesen. Wer aber mitliest, ist herzlich willkommen und eingeladen, mitzudiskutieren!

Alle eigenen Inhalte des Schockwellenreiters stehen unter einer Creative-Commons-Lizenz, jedoch können fremde Inhalte (speziell Videos, Photos und sonstige Bilder) unter einer anderen Lizenz stehen.

Der Besuch dieser Webseite wird aktuell von der Piwik Webanalyse erfaßt. Hier können Sie der Erfassung widersprechen.

Diese Seite verwendet keine Cookies. Warum auch? Was allerdings die iframes von Amazon, YouTube und Co. machen, entzieht sich meiner Kenntnis.


Werbung


Werbung


image  image  image
image  image  image


image