kurse:efcomputergrafik:kw4

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
kurse:efcomputergrafik:kw4 [2020/01/22 20:28]
Ivo Blöchliger [Todo]
kurse:efcomputergrafik:kw4 [2020/01/23 09:00]
Ivo Blöchliger [Blender]
Line 141: Line 141:
 \begin{align*} \begin{align*}
 x(t) & =  r \cdot \textrm{e}^{\textrm{i}t \cdot \frac{1}{r}}\\ x(t) & =  r \cdot \textrm{e}^{\textrm{i}t \cdot \frac{1}{r}}\\
-v(t) & =  x'(t) = \textrm{e}^{\textrm{i}t \cdot \frac{1}{r}}\\ +v(t) & =  x'(t) = \textrm{i}\textrm{e}^{\textrm{i}t \cdot \frac{1}{r}}\\ 
-a(t) & =  v'(t) = \frac{1}{r} \cdot \textrm{e}^{\textrm{i}t \cdot \frac{1}{r}}\\+a(t) & =  v'(t) = -\frac{1}{r} \cdot \textrm{e}^{\textrm{i}t \cdot \frac{1}{r}}\\
 \end{align*} \end{align*}
  
-Beträgt jetzt die Geschwindigkeit $\lambda$ anstatt 1, ändern sich die Gleichungen wie  folgt:+Beträgt jetzt der Betrag der Geschwindigkeit $\lambda$ anstatt 1, ändern sich die Gleichungen wie  folgt:
  
 \begin{align*} \begin{align*}
 x(t) & =  r \cdot \textrm{e}^{\textrm{i} \lambda t \cdot \frac{1}{r}}\\ x(t) & =  r \cdot \textrm{e}^{\textrm{i} \lambda t \cdot \frac{1}{r}}\\
-v(t) & =  x'(t) =  \lambda  \cdot \textrm{e}^{\textrm{i} \lambda t \cdot \frac{1}{r}}\\ +v(t) & =  x'(t) =  \textrm{i}\lambda  \cdot \textrm{e}^{\textrm{i} \lambda t \cdot \frac{1}{r}}\\ 
-a(t) & =  v'(t) =  \lambda^2 \cdot \frac{1}{r} \cdot \textrm{e}^{\textrm{i} \lambda t \cdot \frac{1}{r}}\\+a(t) & =  v'(t) =  -\lambda^2 \cdot \frac{1}{r} \cdot \textrm{e}^{\textrm{i} \lambda t \cdot \frac{1}{r}}\\
 \end{align*} \end{align*}
  
-D.h., wenn die Geschwindigkeit von $1$ auf $\lambda$ erhöht wird, wird die Beschleunigung mit $\lambda^2$ multipliziert.+D.h., wenn der Betrag der Geschwindigkeit von $1$ auf $\lambda$ erhöht wird, wird der Betrag der Beschleunigung mit $\lambda^2$ multipliziert.
  
 ===== Beschleunigung bei konstantem Geschwindigkeisbetrag 1 ===== ===== Beschleunigung bei konstantem Geschwindigkeisbetrag 1 =====
Line 160: Line 160:
  
 Sei $t(\ell)$ die Umkehrfunktion, d.h. der $t$-Parameter für eine bestimmte Länge. Die Ableitung ist dann Sei $t(\ell)$ die Umkehrfunktion, d.h. der $t$-Parameter für eine bestimmte Länge. Die Ableitung ist dann
 +(nach der Formel $(f^{-1})' = \frac{1}{f'(f^{-1})}$ mit $f^{-1}=t$ und $f=\ell$):
 $$ $$
-\frac{\textrm{d}t(\ell)}{\textrm{d}\ell} = \frac{1}{\ell'(t(\ell))} = \frac{1}{|p'(t(\ell)|}.+\frac{\textrm{d}t(\ell)}{\textrm{d}\ell} = \frac{1}{\ell'(t(\ell))} = \frac{1}{|p'(t(\ell))|}.
 $$ $$
 (D.h. der Parameter $t$ ändert sich mit der Länge indirekt proportional zur $t$-Geschwindigkeit). (D.h. der Parameter $t$ ändert sich mit der Länge indirekt proportional zur $t$-Geschwindigkeit).
Line 172: Line 173:
 p'(t(\ell)) \cdot \frac{1}{|p'(t(\ell))|} p'(t(\ell)) \cdot \frac{1}{|p'(t(\ell))|}
 \] \]
-d.h. man erhält den auf den Betrag 1 normalisierten Geschwindgkeitsvektor (was ja genau der Sinn der $p_{\ell}$ Parametrierung ist.+d.h. man erhält den auf den Betrag 1 normalisierten Geschwindgkeitsvektor (was ja genau der Sinn der $p_{\ell}$ Parametrierung ist).
  
-Die zweite Ableitung von $p_{\ell}$ nach $\ell$ ergibt die Beschleunigung $a_n(\ell)$, die rechtwinklich auf $v_n$ steht (sonst würde sich der Betrag von $v_n$ ändern).+Die zweite Ableitung von $p_{\ell}$ nach $\ell$ ergibt die Beschleunigung $a_n(\ell)$, die rechtwinklig auf $v_n$ steht (sonst würde sich der Betrag von $v_n$ ändern).
  
 Diese zweite Ableitung berechnen wir nummerisch durch Ableiten der ersten: Diese zweite Ableitung berechnen wir nummerisch durch Ableiten der ersten:
Line 181: Line 182:
 \] \]
  
 +===== Effektive Beschleunigung und Komponente in Bahnnormalebene =====
 +Sei $v_{\text{eff}}(t) \in \mathbb{R}$ der Betrag der effektiven Bahngeschwindigkeit im Punkt zum entsprechenden $t$-Parameter.
 +Die effektive Beschleunigung ist also 
 +\[
 +a_{\text{eff}}(t) =  (v_{\text{eff}}(t))^2 \cdot a_n(t) -g
 +\]
 +wobei $g$ die Gravitationsbeschleunigung ist.
 +
 +Diese Beschleunigung zerlegen wir in zwei Komponenten, eine tangential zur Bahn $a_t$, eine rechtwinklig dazu $a_r$. Die Komponente $a_t$ sorgt für die Beschleunigung des Zugs, die Komponente $a_r$ ist für die Bahnneigung relevant. Diese sollte nämlich rechtwinklig zu $a_r$ sein.
 +
 +$a_t$ ist die Projektion von $a_{\text{eff}}$ auf $v_n$. Es gilt (mit $|v_n|=1$):
 +\[
 +a_t = (\vec a_{\text{eff}} \cdot \vec v_n) \cdot \vec v_n \qquad \text{Skalarprodukt in der Klammer!}
 +\]
 +Und damit 
 +\[
 +a_r = a_{\text{eff}}-a_t
 +\]
 +
 +Damit bilden wir ein Koordinatensystem $K(t)$ mit Ursprung $p(t)$ und Einheitsvektoren
 +\[
 +e_1 = v_n(t), \qquad e_2 = \frac{a_r(t)}{|a_r(t)|}, \qquad e_3 = v_n(t) \times a_r(t) \cdot \frac{1}{|a_r(t)|}
 +\]
 +
 +===== Bau der Bahn =====
 +In geeigneter Schrittgrösse der Kurve entlang gehen, an jedem Punkt mit $K(t)$ Schienen-Punkte definieren.
 +Eventuell Stützen definieren.
 +
 +Blender Code analog zur Generierung der glatten Kurve.
 +===== Simulation der Bewegung =====
 +Zustand: $t$ (Ort auf der Bahn), $v_{\text{eff}}$ (aktueller Betrag der Geschwindigkeit)
 +
 +Schritt: Zeit um 1/framerate vorrücken, der Bahn folgen (z.B. um die Strecke, die mit $v_{\text{eff}}$ in dieser Zeit zurückgelegt würde, oder genauere schrittweise Simulation). Aus der Höhendifferenz und eventuell Reibung die neue Geschwindigkeit berechnen.
 +
 +Kamera entsprechend positionieren und Keyframe setzen:
 +
 +<code python>
 +cam = bpy.data.objects['Camera']
 +frame = 0
 +cam.animation_data_clear()
 +cam.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))
 +cam.keyframe_insert(data_path="rotation_euler", frame=frame)
 +cam.keyframe_insert(data_path="location", frame=frame)
 +frame+=1
 +</code>
 +Siehe auch https://blender.stackexchange.com/questions/108938/how-to-interpret-the-camera-world-matrix
 +
 +D.h. die erste Koordinatenrichtung ist rechts, die zweite oben und die dritte ist entgegen der Blickrichtung.
 +
 +===== Blender =====
 +Bezier Klasse laden in Blender:
 +<code python bahn.py>
 +# Nimmt die Bezierkurven aus myspline und erzeugt 
 +# die Bahn und die Kamera-Animation
 +
 +# Import in Blender 2.8 (see https://devtalk.blender.org/t/2-80-using-multiple-internal-scripts-breaking-change/6980 )
 +Bezier = bpy.data.texts["bezier.py"].as_module().Bezier
 +
 +obj = bpy.data.objects['mySpline']
 +
 +# Kurvenpunkte auslesen
 +mypoints=[]
 +if obj.type == 'CURVE':
 +    for subcurve in obj.data.splines:
 +        curvetype = subcurve.type
 +        if curvetype == 'BEZIER':
 +            for bezpoint in subcurve.bezier_points:
 +                mypoints.append(bezpoint.handle_left)
 +                mypoints.append(bezpoint.co)
 +                mypoints.append(bezpoint.handle_right)
 +                
 +
 +# Sammlung von Bezierkurven erzeugen
 +mySplines = []
 +numpoints = len(mypoints)
 +totalLength = 0
 +for i in range(numpoints//3):
 +    mySplines.append(Bezier((mypoints[i*3+1],
 +        mypoints[i*3+2], 
 +        mypoints[(i*3+3)%numpoints], 
 +        mypoints[(i*3+4)%numpoints])))
 +    totalLength+=mySplines[-1].length()
 +
 +
 +# Bahn erzeugen
 +try:
 +    bpy.ops.collection.objects_remove(bpy.data.collections['Rails'])
 +except:
 +    pass
 +    
 +railsCol = bpy.data.collections.new('Rails')
 +linksCol = bpy.data.collections.new('RailLinks')
 +railsCol.children.link(linksCol)
 +bpy.context.scene.collection.children.link(railsCol)
 +               
 +abstand = 0.2  # Bahnpunkte
 +ldone = 0  # Erledigte Bahnstrecke
 +i=0  # Aktuelle Bezierkurve
 +t = 0 # Aktuelle t-Parameter
 +g = Vector(0,0,-9.81) # Gravitationbeschleunigung
 +hmax = 40  # Hoehe fuer v=0
 +# Bahnpunkte: Ctrl-Links, Knoten, Ctrl-Rechts
 +railspts=[[],[],[]]  # Bahnpunkte, Schiene L, Schiene R, Träger 
 +while(ldone<totalLength):
 +    dl = abstand;
 +    tnext = -1
 +    while(tnext<0):
 +        tnext = mySplines[i].forward(dl, t)
 +        if (tnext<0) : # We get the negative remaining length
 +            i=(i+1)%numSplines
 +            t = 0
 +            dl=abs(tnext)
 +        else:
 +            ldone+=dl
 +    t = tnext
 +    # Potentielle Energie mgh
 +    ekin = (hmax-mySplines[i].x(t).z)*abs(g.z)
 +    # Ek = 1/2 * m * v^2
 +    v = (2*ekin)**0.5
 +    # Koordinatensystem (vorne, oben, rechts)
 +    k = mySplines[i].koordsyst(t,v,g)
 +    # Bahnpunkte berechnen
 +    #
 +    #
 +    #
 +    
 +
 +
 +# Blender-Kurven aus den Bahnpunkten erzeugen
 +for j in range(3):
 +    curvedata = bpy.data.curves.new(name="rail"+str(j), type='CURVE')
 +    curvedata.dimensions = '3D'
 +    objectdata = bpy.data.objects.new("rail"+str(j), curvedata)    
 +    objectdata.location = (0,0,0)
 +    objectdata.data.bevel_depth = 0.01
 +
 +    railsCol.objects.link(objectdata)
 + 
 +    polyline = curvedata.splines.new('BEZIER'   
 +    polyline.bezier_points.add(len(railspts[j])-1)    
 + 
 +    for idx, (h1, knot, h2) in enumerate(railspts[j]):
 +        point = polyline.bezier_points[idx]
 +        point.co = knot
 +        point.handle_left = h1
 +        point.handle_right = h2
 +        point.handle_left_type = 'ALIGNED'
 +        point.handle_right_type = 'ALIGNED'
  
 +</code>
  • kurse/efcomputergrafik/kw4.txt
  • Last modified: 2020/02/12 21:06
  • by Ivo Blöchliger