Kategorien
Allgemein Satori

Bezierkurven in GFA-Basic

Ok, wir haben Ende 2023. Aber immernoch gibt es manchmal Situationen, wo ich weder mit Code noch mit Pseudocode was gut erklären kann. Dann hilft mir oft ein Relikt aus meiner Kindheit namens GFA-Basic. Der Interpreter kümmert sich um die Einrückung und Colorierung während ich tippe. Es gibt kaum Klammern und keine Semicola.
Menschen können das fast vom Blatt lesen, und darum geht es.

Ihr kennt sicher alle diese schönen Kurven, die galant durch eine Reihe von Kontrollpunkten laufen? Nun, gestern hab ich versucht, Emilio zu erklären, wie solche Bezierkurven entstehen:

Durch Interpolation zwischen Punkten, die ihrerseits Interpolationen sind. Vielleicht erkläre ich später noch ein paar Fallstricke zu Anzahl und Reihenfolge dieser Punkte, aber für heute nehmen wir die einfachste Form: Jeder Ankerpunkt, durch den die Kurve läuft, hat zwei spiegelbildliche Kontrollpunkte, durch feine Nadeln zu ihrem Ankerpunkt dargestellt. Deswegen brauchen wir nur einen davon abzuspeichern, der andere leitet sich davon ab.

Der Trick ist nun, dass man die Kurve in Abschnitten zwischen je zwei Ankerpunkten zeichnet. Den ersten Ankerpunkt wird die Kurve in Richtung ausgehender Kontrollpunkt verlassen, den zweiten Ankerpunkt in Richtung eingehender Kontrollpunkt erreichen. Dazu lässt man einen Parameter von 0 nach eins wandern und nutzt ihn insgesamt sechs mal zur Interpolation zwischen je zwei Punkten:

Zunächst errechnet man drei Zwischenpunkte aus vieren, aus denen sich wiederum zwei Zwischenpunkte ergeben, und zwischen diesen liegt der eine gesuchte Punkt, der die eigentliche Kurve zeichnet.

Hier ist der GFA-Basic-Code, um einige zufällige Punkte zu erzeugen und dann eine Bezierkurve durch sie zu zeichnen:


' *** Für Emilio mal eben BezierKurven visualisiert
' *** Remember: We have to calculate 3 levels of interpolation in order to
' ***           get those curves going through control points continuously

' ** INITIALISIERUNG

Type Int2 :
  x As Short
  y As Short
EndType

Local Short maxSegment = 18
Local Short maxContRange = 512
Local Short maxSteps = 120
Global Tang(maxSegment) As Int2
Global Cont(maxSegment) As Int2
Global ext, p As Int2

AutoRedraw = True
OpenW 1, , , 1600, 1280, 0

Global res As Int2 : res.x = _X : res.y = _Y

randomPoints(maxSegment, maxContRange)
DrawBezier(maxSegment, maxSteps)

'Warteschleife
Repeat
  DoEvents
Until ext Or InKey$ = #27
CloseW 1

Sub randomPoints(maxSegment&, maxContRange&)
  ' Generate and draw points
  Local T As Int2, C As Int2, segment
  For segment = 0 To maxSegment - 1

    ' tangent points
    T.x = Rand(res.x * .8) + res.x * .1
    T.y = Rand(res.y * .8) + res.y * .1
    Color RGB(128, 128, 128)
    Box T.x - 2, T.y - 2, T.x + 3, T.y + 3
    ' write to array
    Tang(segment).x = T.x
    Tang(segment).y = T.y

    ' control points
    C.x = Rand(maxContRange) - maxContRange / 2
    C.y = Rand(maxContRange) - maxContRange / 2
    Color RGB(64, 192, 128)
    Box T.x + C.x - 1, T.y + C.y - 1, T.x + C.x + 1, T.y + C.y + 1
    Color RGB(128, 144, 255)
    Box T.x - C.x - 1, T.y - C.y - 1, T.x - C.x + 1, T.y - C.y + 1
    Cont(segment).x = C.x
    Cont(segment).y = C.y

  Next
Return

Sub DrawBezier(maxSegment&, maxSteps&)
  Local Int segment, step, j
  Local Float s
  Local T0 As Int2,  T1 As Int2, C0 As Int2, C1 As Int2
  Local  R As Int2,   G As Int2,  B As Int2
  Local GR As Int2,  RB As Int2
  Local  Z As Int2, old As Int2

  For j = 0 To maxSegment - 1
    T0 = Tang(j)
    C0 = Cont(j)
    ' make control point absolute:
    C0.x += T0.x : C0.y += T0.y

    T1 = Tang((j + 1) % maxSegment)
    C1 = Cont((j + 1) % maxSegment)
    ' mirror control point 1 and make absolute:
    C1.x = T1.x - C1.x : C1.y = T1.y - C1.y

    For step = 0 To maxSteps
      s = step / maxSteps

      ' Interpolation Level 1:
      ' grüne Punkte = Tangentialpunkt 0 bis Kontrollpunkt 0
      interpol(T0, C0, s, G)
      Color RGB(64, 192, 128)
      Pset G.x, G.y

      ' blaue Punkte = Spiegelung von Kontrollpunkt 1 bis Tangentialpunkt 1
      interpol(C1, T1, s, B)
      Color RGB(128, 144, 255)
      Pset B.x, B.y

      ' rote Punkte = Interpolation zwischen Kontrollpunkten
      interpol(C0, C1, s, R)
      Color RGB(255, 192, 184)
      Pset R.x, R.y

      ' Interpolation Level 2:
      ' grün-rote Interpolation
      interpol(G, R, s, GR)
      ' rot-blaue Interpolation
      interpol(R, B, s, RB)

      ' Interpolation Level 3:
      ' schwarZe Punkte = BeZierkurve
      old = Z
      interpol(GR, RB, s, Z)       ' in Z wird das Ergebnis geschrieben

      If step > 0
        Color RGB(0, 0, 0)
        Line old.x, old.y, Z.x, Z.y
      EndIf

    Next
  Next
Return

Sub interpol(ByRef start As Int2, ByRef end As Int2, s, ByRef p As Int2)
  p.x = start.x * (1 - s) + end.x * s
  p.y = start.y * (1 - s) + end.y * s
Return

Sub Win_1_MouseWheel(Buttons&, Delta%, MseX%, MseY%)
  ext = Buttons && 1
Return

Sub Win_1_ReSize
  res.x = _X : res.y = _Y
  Win_1.BorderStyle = 0
Return
Kategorien
Allgemein

TELEGRAM vs. SIGNAL

Anlässlich der präzisen Analyse von Jürgen Schmidt auf heise online

Telegram-Chat: der sichere Datenschutz-Albtraum – eine Analyse und ein Kommentar

habe ich nochmals gecheckt, wie praktikabel es wirklich ist, Telegram in seriös zu nutzen, also nicht völlig unverschlüsselt.

Also. Die für modernes instant messaging essentielle Ende-zu-Ende-Verschlüsselung ist in Telegram

a) optional b) umständlich zu finden c) muss sie für jeden Kontakt einzeln angeschaltet werden und d) nicht aus dem Kontakt selbst aufrufbar, also nicht für die zentrale Funktion unserer Mobilgeräte, das „Teilen“, verfügbar.

Ich bin raus, sorry.

Kategorien
Allgemein

Flagge zeigen am Quartier am Hafen

Seit einigen Tagen schmücken neue Flaggen unser Quartier.

Die Hausgemeinschaft hat sich in einer Ausschreibung für meinen Entwurf entschieden, den ich mithilfe von #vvvv gerendert habe. Direkt aus demselben patch hatte ich dann auch die Druckvorlagen erstellt.

Kategorien
Satori

易经 – Das Buch der Wandlungen

Was mag das bedeuten, dass ich so gar nichts über das I Ging erinnere? Hatte ich dieses Kulturgut wegen bool isEsoteric = true nach /dev/null gepiped?

Jetzt bin ich jedenfalls zum ersten Mal über die binäre Codierung seiner 64 Zeichen, genannt Hexagramme, darauf gekommen. Diese sind allerdings keine digitale Früherscheinung in der Geschichte der Zahlenschrift, wie Leibniz nach seiner Erfindung des Binärcodes irrtümlicherweise annahm. Skeptisch eingeordnet sind sie schon eher ein Zeichensatz für eine altertümliche Methode zur Erforschung des Unbewussten, wie C.G. Jung sie aufgefasst hat.

Darüber hinaus aber vor allem eine unwahrscheinlich passende ästhetische Inspiration während meiner aktuellen Arbeit mit geometrischen Generatoren. Kein Wunder, dass mir am Tollsten daran gefällt, dass sowohl die Trigramme als auch die Hexagramme im UTF-Zeichensatz standardisiert sind.

Zum Nachtisch gönne ich mir aber auch ein kleines Bedeutungszitat, gewissermaßen als Orakelersatz:

Kraft
(乾, qián)
Himmel
(天, tiān)
Vater
(父, )
Beben
(震, zhèn)
Donner
(雷, léi)
Ältester Sohn
(長男, chǎngnán)
„Meine“ Trigramme mit Ihren (Haupt-)Bedeutungen.
Pakua
Kategorien
Allgemein WTF op se day

Text in Rastergrafik – Eine Seuche

Sprüche auf Hintergrundbildern. Wie sich mir beim scrollen die Nackenhaare aufstellen. Nicht, weil sie seicht und orthografisch kaputt sind und/oder die grafische Gestaltung an ihren Vorgänger, den esoterischen Wandkalender erinnert. Nein: Es regt sich eine Facette des Utopisten in mir, der die Information frei fließen sehen will, der das Semantic Web feiert, unter schlechten OCR-Werkzeugen gelitten hat oder einfach nur was markieren, kopieren und einfügen will, wo nunmal kein Bild eingefügt werden kann.

Kategorien
Foodporn
Kategorien
Allgemein

oktoskop ist Top News auf heise.de

Das oktoskop auf dem 36C3: Hacken und Basteln abseits der Vorträge

https://heise.de/-4623903

Kategorien
Allgemein

chaoskop @ 36C3

Auf geht’s zum 36. Chaos Communication Congress nach Leipzig!
Nach Projekt Aurora auf dem Chaos Camp 19 werden wir auf dem Congress vom 26.12.-30-12. wieder eine große Lichtkulisse aus Eierkartons in Halle 3 hängen und per video mapping bespielen. Was es dort Neues gibt, verrate ich natürlich noch nicht.

Aber ein Video vom BaseCamp in Bonn ist online: oktoskop | live visual stage design

Bis dahin, kommt vorbei!

Kategorien
WTF op se day

What the Fucx op se day

Mozilla AddOns:

Mit der Umstellung seiner Basis für Browsererweiterungen auf WebExtensions hat Mozilla zum xten Mal die Entwicklergemeinde brüskiert. Traurigerweise zeigt sich inzwischen, dass diesmal eine Mehrheit der Autoren final abgefuckt ist und damit der Zenit von Firefox insgesamt wohl überschritten ist.

Schon gestern hatte ich mich richtig geärgert, dass mein Workflow zur Erstellung von QR-Codes für Veranstaltungen kaputt ist, weil die entsprechende Erweiterung für den Thunderbird nicht mehr unterstützt wird.

Heute habe ich mein Flattr-AddOn vermisst, mit dem sich Micropayment in europäischer Manier hätte etablieren können. Jedoch ergitb eine Suche in der (ebenfalls gegenüber mycroft.mozdev.org verschlechterten) AddOn-Datenbank:

https://addons.mozilla.org/en-US/firefox/search/?q=flattr&type=extension

Kategorien
Allgemein

Deutsche Bahn gibt vier von vier FALSCHE „Wichtige Hinweise“

Die Deutsche Bahn gibt sich mal wieder alle Mühe, mich anzukotzen und auf meine fundierte Kritik mit erbärmlichem $Gefasel zu reagieren:

Und hier die umwerfend sachbezogene Reaktion:

Echt jetzt? Es würde mich nicht aufregen, wenn ich dieses nicht bereits vor Jahren mit denselben akribischen Nachweisen moniert hätte.
Nach aller Höflichkeit also, Deutsche Bahn, heute: Wann wacht ihr endlich auf?