n-dimensionale Peano-Kurve - Vektor zu Skalar und andersherum

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

n-dimensionale Peano-Kurve - Vektor zu Skalar und andersherum

Beitrag von STARGÅTE »

Hier mal ein kleines Modul zum Thema raumfüllende Kurven, im Speziellen die Peano-Kurve.
Nun soll das Modul selbst keine Kurven zeichnen oder sowas. Vielmehr ist das Modul dafür gedacht, aus einer skalaren Zahl zwischen 0 und 1 einen n-dimensionalen Vektor zu berechnen bzw. aus einem n-dimensionalen Vektor eine skalare Zahl, und das eineindeutig.
Dass heißt, jede Zahl zwischen 0 und 1 ist genau einem Punkt in der Ebene, im Raum oder im Hyperraum zugeordnet.
(Natürlich geht Genauigkeit verloren, wenn man aus einer Double, zwei oder mehr Doubles macht. Das sollte hoffentlich klar sein.)

Wofür sollte man sowas brauchen? Nun, ein klassisches Anwendungsbeispiel wäre die Umwandlung von einem Bild (zwei Dimensionen mit Helligkeitswert) in einen Ton (eine Dimension, die Frequenz, mit Lautstärke) oder andersherum. Ein schönes Video gibt es dazu von 3Blue1Brown

Code: Alles auswählen

Global Dimensions.i = 2
Global Dim Vector.d(Dimensions-1)
Global Scalar.d

Scalar = 0.3  ; Pick a scalar number between 0.0 and 1.0
Debug Scalar
SpaceFillingCurve::PeanoVector(@Vector(), Scalar, Dimensions)
Debug "{" + StrD(Vector(0), 5) + ", " + StrD(Vector(1), 5) + "}"
Debug SpaceFillingCurve::PeanoScalar(@Vector(), Dimensions)
0.29999999999999999
{0.75000, 0.25000}
0.3000000000000001

Code: Alles auswählen

DeclareModule SpaceFillingCurve
	
	#MaxDepth = 20
	
	Structure DoubleArray
		d.d[0]
	EndStructure
	
	; Peano-curve
	Declare.i PeanoVector(*Vector.DoubleArray, Scalar.d, Dimensions.i=2, Depth.i=#MaxDepth)  ; Gives the n-dimensional vector from a scalar number using the Peano-curve.
	Declare.d PeanoScalar(*Vector.DoubleArray, Dimensions.i=2, Depth.i=#MaxDepth)            ; Gives the scalar number from an n-dimensional vector using the Peano-curve.
	
EndDeclareModule



Module SpaceFillingCurve
	
	EnableExplicit
	
	#DoubleEpsilon = 2.2204460492503130808e-16
	
	Procedure.d PeanoScalar(*VectorIn.DoubleArray, Dimensions.i=2, Depth.i=#MaxDepth)
		
		Protected MaxI.i = Dimensions-1
		Protected Dim Vector.d(MaxI)
		Protected Dim Direction.d(MaxI)
		Protected I.i, J.i
		Protected Scaling.d = 1.0
		Protected Scalar.d  = 0.5
		
		For I = MaxI To 0 Step -1
			Vector(I) = *VectorIn\d[I]
			Direction(I)   = 1.0
		Next
		
		While Depth > 0
			For I = MaxI To 0 Step -1
				Scaling / 3.0
				If Scaling < #DoubleEpsilon : Break : EndIf
				Vector(I) * 3
				If Vector(I) < 1
					Scalar - Scaling * Direction(I)
				ElseIf Vector(I) < 2
					Vector(I) - 1
					For J = MaxI To 0 Step -1
						If J <> I
							Direction(J) = -Direction(J)
						EndIf
					Next
				Else
					Vector(I) - 2
					Scalar + Scaling * Direction(I)
				EndIf
			Next
			Depth - 1
		Wend
		
		ProcedureReturn Scalar
		
	EndProcedure
	
	Procedure.i PeanoVector(*VectorOut.DoubleArray, ScalarIn.d, Dimensions.i=2, Depth.i=#MaxDepth)
		
		Protected MaxI.i = Dimensions-1
		Protected Dim Direction.d(MaxI)
		Protected I.i, J.i
		Protected Scaling.d = 1.0
		
		For I = MaxI To 0 Step -1
			*VectorOut\d[I] = 0.5
			Direction(I)    = 1.0
		Next
		
		While Depth > 0
			Scaling / 3.0
			If Scaling < #DoubleEpsilon : Break : EndIf
			For I = MaxI To 0 Step -1
				ScalarIn * 3
				If ScalarIn < 1.0
					*VectorOut\d[I] - Scaling * Direction(I)
				ElseIf ScalarIn < 2.0
					ScalarIn - 1.0
					For J = MaxI To 0 Step -1
						If J <> I
							Direction(J) = -Direction(J)
						EndIf
					Next
				Else
					*VectorOut\d[I] + Scaling * Direction(I)
					ScalarIn - 2.0
				EndIf
			Next
		Wend
		
		ProcedureReturn *VectorOut
		
	EndProcedure
	
EndModule
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: n-dimensionale Peano-Kurve - Vektor zu Skalar und andersherum

Beitrag von NicTheQuick »

Cool, das wollte ich auch irgendwann mal programmieren. Ich hab deswegen immer noch diesen Link in meinen Lesezeichen: http://blog.notdot.net/2009/11/Damn-Coo ... ert-Curves
:-D

Deinen Code muss ich bei Gelegenheit mal ausprobieren. Danke!

Edit: Hoppla, das war der falsche Link, ist aber auch interessant. :lol:
Bild
Antworten