Hallo zusammen,
letztens hatte ich eine Telefonkonferenz bzw. Videokonferenz, in der ich mich über Sattelpunkte / relative und absolute Minima von Hyperflächen auslassen durfte. Als anschauliches Beispiel fand ich ein Video, in dem eine Hyperfläche animiert wurde.
Natürlich habe ich mich gefragt, wie man sowas programmieren kann / könnte. Vorhin hat mich es dann gepackt und habe da was programmiert.
In Anlehnung an die Codezeilen des Icon-Tutorials Teil 21 (Übungsaufgabe zu Teil 20) habe ich die Funktion
berechnet, im Bereich -1.5 pi <= x <= 1.5 pi und -1.5 pi <= y <= 1.5 pi auf den Bildschirm gebracht und schließlich mit Amplituden von -5 bis +5 als Animation erzeugt.
Leider ist das Video zu groß, um hier hochgeladen werden zu können.
Raffiniert ist dann auch die wechselnde Verzögerung, die bei der Amplitude um 0 ihr Minimum erreicht und bei bei minimaler und maximaler Amplitude ihr Maximum erreicht.
link graphics
global Breite, Hoehe, canvas_list
global Sx, Sy, # Skalierungsfaktoren Window-Viewport-Transformation - nicht implementiert
P, # Punkte im 3D-Raum
G, # Verbindungslinien in P - nicht implementiert
Max_Amplitude
$define step 0.05
record punkt_t(x, y, z)
procedure f(x, y)
return Max_Amplitude * cos(x)^3 * sin(y)^3
end
procedure prepare_animation(amplitude)
initial
{
WOpen( "canvas=maximal", "pos=0,0", "size=" || Breite || "," || Hoehe, "label=3D-Animation")
}
EraseArea(0,0,Breite, Hoehe)
Max_Amplitude := (amplitude - 25) / 5.0
x := -1.5 * &pi
while x <= 1.5 * &pi do
{
y := -2 * &pi
while y <= 2 * &pi do
{
put(P, punkt_t(x, y, f(x, y)))
y +:= step
}
x +:= step
}
plot(P)
P := [] # Löschen von P nach jedem einzelnen Plot
end
procedure animate()
# Vorlauf
every i := 1 to 50 do
{
CopyArea(canvas_list[i], &window)
delay(10 + abs(i-25)) # Verzögerung in Abhängigkeit der Amplitude
}
# Rücklauf
every i := 50 to 1 by -1 do
{
CopyArea(canvas_list[i], &window)
delay(10 + abs(i-25))
}
end
procedure main()
P := []
canvas_list := list(50)
if WOpen("canvas=maximal") then
{
Breite := WAttrib("displaywidth")
Hoehe := WAttrib("displayheight")
WClose()
}
else stop("Kein Fenster")
every i := 0 to 49 do
{
prepare_animation(i)
canvas_list[1 + i] := WOpen("size=" || Breite || "," || Hoehe, "pos=1,1", "canvas=hidden")
CopyArea(&window, canvas_list[1+i])
}
WAttrib("canvas=maximal")
WAttrib("pos=1,1")
repeat
{
animate()
if WQuit(&window) then break
}
every WClose(!canvas_list)
WClose()
end
procedure plot(P)
every i := 1 to *P do
{
# Zeichenfarbe in Abhängig des Abstandes von der Ebene xy = 0
Fg(65535 * abs(P[i].z) / 7 || "," || 65535 * abs(P[i].z) / 7 || "," || 65535 * abs(P[i].z) / 7)
DrawCircle(WAttrib("width") /2 + 40 * P[i].x + 10 * P[i].y, WAttrib("height") / 2 - 10 * P[i].y - 40 * P[i].z, 1)
}
end
Alles anzeigen
Beste Grüße
Andreas