====== Schrittmotorsteuerung ====== Diskrete Schritte, Zeitabstände der Schritte bestimmen Geschwindigkeit. $$ \vec F=m\cdot \vec a $$ Problem: Plötzliche Geschwindigkeitsänderung hat unendliche Beschleunigung zur Folge. Dabei können Schritte verloren gehen, unerwünschte Vibrationen in der Maschine ausgelöst werden etc. Lösungsansatz: Vor Ecken wird langsam abgebremst und danach wieder beschleunigt (mit einer zu definierenden maximalen Beschleunigung). Problem: Bei Polygonen ist jeder Punkt eine Ecke, was zu einer sehr langsamen Maschine führen würde. Lösungsansatz: Kurven mit gemeinsamer Tangente in den Endpunkten. Bezierkurven: Für die Schrittmotoren brauchen wir Zeitpunkte für die Schritte. Dazu muss letztlich die Gleichung $x=p_x(t)$ gelöst werden (Gleichung 3. Grades), wobei $x$ die nächste, durch Schritte vorgegebene $x$-Koordinate ist. Leider existiert diese nicht immer, z.B. wenn die Kurve vertikal ist. Es gäbe auch andere, iterative Ansätze, wo das nächste $t$ so bestimmt wird, dass sich eine Koordinaten um genau eine Schrittlänge unterscheidet. Kurzum: Zum Nachfahren mit Schrittmotoren sind Bezierkurven mühsam. Viel einfacher wäre es, Kreisbogen zu fahren (konstante Zentripetal-Beschleunigung). Tatsächlich wird das in G-Code normalerweise so gemacht: https://www.cnccookbook.com/cnc-g-code-arc-circle-g02-g03/ Wir werden uns nicht damit befassen, wie wir Bezierkurven allgemein möglichst gut durch Kreisbogen und Geradenstücke annähern können. Stattdessen untersuchen wir das inverse Problem: ====== Kreise mit kubischen Bezierkurven approximieren ====== Aufgabe: Finden Sie die Koordinaten von den 4 Kontrollpunkten einer kubischen Bezierkurve so, dass der Viertelkreisbogen des Einheitskreises im ersten Quadranten möglichst gut angenähert wird. pts(r) := [[1,0],[1,r],[r,1],[0,1]]; p(t,r) := (1-t)^3*pts(r)[1]+3*(1-t)^2*t*pts(r)[2]+3*(1-t)*t^2*pts(r)[3]+t^3*pts(r)[4]; d(t,r):=(p(t,r).p(t,r))^0.5; define(d2(t,r),p(t,r).p(t,r)); solve(d2(0.5,r)=1,r); solve(d2dt(t,r)=0, t); tmax : rhs(solve(d2dt(t,r)=0, t)[2]); solve(d(tmax,r)-1 = 1-d(0.5,r),r); define(dtmax(r),d(tmax,r)); define(rdiff(r), float((dtmax(r)-1)-(1-d(0.5,r)))); load ("newton1"); ropt:newton(rdiff(r), r, 0.55,1.0e-17); 2.0-d(0.5,ropt); plot3d(d(t,r), [t,0,1],[r,0.55,0.555]); Liefert ein optimales $r\approx 0.5519150244935106$ mit einer Abweichung von $\approx 1.000196076469877$. Siehe auch http://spencermortensen.com/articles/bezier-circle/ und https://pdfs.semanticscholar.org/1639/0db1a470bd13fe428e0896671a9a5745070a.pdf ====== Achterbahn mit Bezierkurven ====== * Modellierung in Blender * Auslesen der Kurvendaten * Berechnung der Geschwindigkeit * Effektive Beschleunigung und daraus den Normalvektor zur Bahn * Orthonormales Koordinatensystem zu jedem Bahnpunkt * Längenparametrierung * Bahnoptimierung (Annäherung an Kreisbogen, Minimierung der 3. Ableitung)