====== Intro ======
* meine Wenigkeit
* mein mickgriges Namensgedächtnis
* Warum Bezier-Kurven?
====== Ziele ======
* Physikalisch halbwegs realistische Achterbahn mit Blender
* Ansteuerung des Whiteboard-Plotters vom Tech-Lab. Siehe https://fginfo.ksbg.ch/~ivo/videos/tech-lab-whiteboard-plotter.mp4. Input: SVG-Datei aus Inkscape, Output: Folge von $(r_1,r_2)$-Koordinaten, die linear abgefahren werden, plus Kommandos zum Heben/Senken des Stifts. Einheit: mm.
====== Programm ======
* Software auf Schulcomputern: https://fginfo.ksbg.ch/dokuwiki/doku.php?id=lehrkraefte:blc:informatik:glf19:glf19#make_the_computer_zimmer_great_again
* Demo mit Inkscape (https://inkscape.org/release/0.92.4/windows/64-bit/)
* Geometrische Definition
* Gerade, 3 Punkte, 4 Punkte
* Programmierung, Animation
====== Brainstorm ======
* Linearkombinationen, Konvexe Kombinationen, 2 Punkte, 3 Punkte, $n$ Punkte
* Kubische Interpolation: 1D, Splines, Basen des Polynomvektorraumes, Bernsteinpolynome
* Kubische Bezier-Kurven
* Darstellung in SVG-Dateien
* Casteljau's Algorithmus
* Länge einer Bezierkurve, "paramétrisation curviligne"
* ?Schnittpunkte zweier Bezierkurven?
* ?Rationale Bezierkurven?
* ?Kubische Splines? https://towardsdatascience.com/numerical-interpolation-natural-cubic-spline-52c1157b98ac
* https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline, Konvertierung in kubische Bezier Splines.
* ?Bezier-Flächen?, ??Nurbs??
* Ableitungen von Kurven, Geschwindigkeit, Beschleunigung
* ?Achterbahnen parametrieren?
* ?Der ideale Looping?
====== Blender stuff ======
* https://medium.com/@behreajj/scripting-curves-in-blender-with-python-c487097efd13
* https://blender.stackexchange.com/questions/6750/poly-bezier-curve-from-a-list-of-coordinates
===== Bezier Kurven =====
* https://fginfo.ksbg.ch/~ivo/videos/blender2.8-Bezier-Kurven.mkv
**Zusammenfassung**: Add -> Curve -> Bezier
* 'e' -> Extrude um neuen Punkt anzufügen.
* 'gz' -> In z-Richtung verschieben.
* Auf Koordinatenachsen klicken, für orthonormale Projektion
* Rechtsklick 'Toggle Cyclic'
*
===== Manipulation in Python =====
==== Auslesen der Daten ====
import bpy
obj = bpy.data.objects['BezierCurve']
if obj.type == 'CURVE':
for subcurve in obj.data.splines:
curvetype = subcurve.type
if curvetype == 'BEZIER':
print("curve is closed:", subcurve.use_cyclic_u)
for bezpoint in subcurve.bezier_points:
print('knot', bezpoint.co)
print('handle_left', bezpoint.handle_left)
print('handle_right', bezpoint.handle_right)
==== Generieren der Daten ====
* https://blender.stackexchange.com/questions/6750/poly-bezier-curve-from-a-list-of-coordinates
* https://docs.blender.org/api/current/bpy.ops.curve.html
Working example, adapted to blender 2.8 from https://github.com/zeffii/BlenderPythonRecipes/wiki/Curves
import bpy
from mathutils import Vector
coordinates = [
((-1, 0, 0), (-0.7, 0, 0), (-1, 0.5521, 0)),
((0, 1, 0), (-0.5521, 1, 0), (0, 0.7, 0)),
((0, 0, 0), (0, 0.3, 0), (-0.3, 0, 0))
]
def MakeCurveQuarter(objname, curvename, cList, origin=(0,0,0)):
curvedata = bpy.data.curves.new(name=curvename, type='CURVE')
curvedata.dimensions = '2D'
objectdata = bpy.data.objects.new(objname, curvedata)
objectdata.location = origin
bpy.context.scene.collection.children[0].objects.link(objectdata)
polyline = curvedata.splines.new('BEZIER')
polyline.bezier_points.add(len(cList)-1)
for idx, (knot, h1, h2) in enumerate(cList):
point = polyline.bezier_points[idx]
point.co = knot
point.handle_left = h1
point.handle_right = h2
point.handle_left_type = 'FREE'
point.handle_right_type = 'FREE'
polyline.use_cyclic_u = True
MakeCurveQuarter("NameOfMyCurveObject", "NameOfMyCurve", coordinates)
==== Einbinden von eigenen Modulen ====
# Eigene, selbstgeschriebene Bezier-Klasse
Bezier = bpy.data.texts["bezier.py"].as_module().Bezier
==== Kamera animieren ====
e = bpy.data.objects['Camera']
e.animation_data_clear()
# Loop über die frames
# Orthonormales system (y,-an,-vv) und Ursprung pp
# wobei -vv die Blickrichtung, -an nach unten zeigt und y nach rechts zeigt.
# matrix_world = (rechts, unten, hinten)
e.matrix_world = ( (y.x,y.y,y.z,1), (-an.x, -an.y, -an.z, 1), (-vv.x,-vv.y,-vv.z,1), (pp.x, pp.y, pp.z, 0))
# Rotation und Translation "keyframen"
e.keyframe_insert(data_path="rotation_euler", frame=frame)
e.keyframe_insert(data_path="location", frame=frame)
frame+=1
==== numpy ====
import numpy as np
a = np.array([[3,1], [1,2]])
b = np.array([9,8])
x = np.linalg.solve(a, b)
print(x) # Das geht unter Linux ins Terminal, wo Blender gestartet wurde. Keine Ahnung wohin das sonst geht...
===== Video kodieren =====
ffmpeg -r 30 -i %04d.png test.mkv
Z.B. https://fginfo.ksbg.ch/~ivo/videos/achterbahn-take1.mkv