2D Animation von Pulsen
#1
Guten Abend,
ich bin recht neu bei Blender und erst recht in diesem Forum. Ich habe folgendes Problem: Ich möchte einen Pulszug darstellen. Bei diesem Pulszug möchte ich an einen Puls ranzoomen. Unter diesem Gauss-Puls sollen dann nochmal Gaußpulse erscheinen, wobei der vorherige als Einhüllende dienen soll. Soweit bin ich gekommen.

Nun mein Problem:
In einem weiteren Animationschritt sollen sich die Pulse unter der Einhüllenden bewegen und dabei ihre Amplitude anpassen, sodass sie unter der Einhüllenden bleiben. Die Bewegung in x-Richtung ist kein Problem aber ich hänge bei der Anpassung der Amplitude. Ich wäre froh, wenn mir jemand helfen könnte.

Das Problem ist also bei der Funktion update_amplitude() aber ich finde es einfach nicht, bzw. verstehe es zu wenig.


Code:
import bpy
import math

print("jetzt")


A_main = 3.0 
mu_main = 0.0
sigma_main = .8
num_points = 1000 
x_range = 26 


def delete_existing_objects():
    bpy.ops.object.select_all(action='SELECT')
    bpy.ops.object.delete()


def create_gaussian_curve(name="GaussianCurve", A=1.0, mu=0.0, sigma=1.0, num_points=100, x_range=100):
    curve_data = bpy.data.curves.new(name=name, type='CURVE')
    curve_data.dimensions = '3D'


    curve_object = bpy.data.objects.new(name, curve_data)
    bpy.context.collection.objects.link(curve_object)


    bpy.context.view_layer.objects.active = curve_object
    bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS', center='BOUNDS')


    spline = curve_data.splines.new(type='POLY') 
    spline.points.add(count=num_points) 

    # Berechne die Punkte der Kurve
    for i in range(num_points):
        x = (i / (num_points - 1)) * 2 * x_range - x_range 
        y = A * math.exp(-(x - mu)**2 / (2 * sigma**2))
        spline.points[i].co = (x, y, 0, 1) 

    return curve_object

def update_amplitude(curve_object, A_new, x=0.0, sigma=.05):
    spline = curve_object.data.splines[0] 


    for point in spline.points:
        x = point.co[0]

        y = A_new * math.exp(-(x)**2 / (2 * sigma**2)) 
        point.co[1] = y 


delete_existing_objects()



for i in range(-5, 5):
    curve_object = create_gaussian_curve(A=A_main, mu=mu_main - (i * 8), sigma=sigma_main, num_points=num_points, x_range=x_range)



bpy.ops.object.camera_add(location=(0, 0, 50))
camera = bpy.context.object
camera.rotation_euler = (0, 0, 0)
bpy.context.scene.camera = camera


camera.location = (0, 0, 50)
camera.keyframe_insert(data_path="location", frame=1)
camera.location = (0, 1.5, 5)
camera.keyframe_insert(data_path="location", frame=100)

camera.data.lens = 35
camera.data.keyframe_insert(data_path="lens", frame=1)
camera.data.lens = 25
camera.data.keyframe_insert(data_path="lens", frame=100)

curve_objects = []
for i in range(-4, 5):
    mu = 0 - i / 2
    A = A_main * math.exp(-(mu)**2 / (2 * sigma_main**2))
    curve_object = create_gaussian_curve(name="GaussianCurve", A=A, mu=mu, sigma=0.05, num_points=1000, x_range=5)
    curve_object.hide_viewport = True
    curve_object.keyframe_insert(data_path="hide_viewport", frame=1)
    curve_object.hide_viewport = False
    curve_object.keyframe_insert(data_path="hide_viewport", frame=100)
    curve_objects.append(curve_object)



for frame in range(120, 151): 
    for curve_object in curve_objects[0:1]:

        x = 0+frame/150/2

       
        A_new =  A_main * math.exp(-(x)**2 / (2 * sigma_main**2))
        print(A_new)
       
        update_amplitude(curve_object, A_new, x=x, sigma=0.05)
        curve_object.location.x = x
        curve_object.keyframe_insert(data_path="location", frame=frame)
        #curve_object.data.update()
        #curve_object.keyframe_insert(data_path="location", frame=frame)
        #curve_object.data.update()
# Animation Einstellungen
bpy.context.scene.frame_start = 1
bpy.context.scene.frame_end = 150
bpy.context.view_layer.update()
Zitieren
#2
Hallo Guther,

also wenn ich das Ziel richtig verstehe, sollen unter der Kurve "animiert" kleinere Amplituden durchlaufen und sich praktisch am jeweiligen Punkt der X-Achse am Maximum der "großen" Amplitude orientieren

Die "update_amplitude"-Funktion weiß nach meiner Einschätzung nach nicht, wo/in welchem Frame "wir" gerade sind. Also müsste noch Frame und mu übergeben werden?! und dann die 1.001-Punkte neu abgespeichert (also nicht wirklich nur die Location)

Code:
def update_amplitude(curve_object, A_new, x=0.0, sigma=.05, frame=0):
    spline = curve_object.data.splines[0]


    for point in spline.points:
        x = point.co.x

        y = A_new * math.exp(-(x)**2 / (2 * sigma**2))
        point.co.y = y
        #NEU:
        point.keyframe_insert("co", frame=frame)

Beachte (Wertübergabe):
frame=0
und ganz unten
point.keyframe_insert("co", frame=frame)

bei keyframe_insert "nur" die "location" zu verwenden wirft die y-Werte über den Haufen, deswegen "co" verwenden, dann werden die individuellen Punkt-Standorte berücksichtigt. Location beschreibt einfach nur wo sich das Objekt befindet. Also müsstest du oben noch irgendwie point.co.x = "k.A." reinstricken.

Ach' so, und ganz unten hatte ich noch etwas angepasst:
Code:
for frame in range(120, 151):
    for curve_object in curve_objects[0:1]:

        x = 0+frame/150/2

      
        A_new =  A_main * math.exp(-(x)**2 / (2 * sigma_main**2))
        print(A_new)
      
        update_amplitude(curve_object, A_new, x, 0.05, frame)
       
        #ALT
        #curve_object.location.x = x
        #curve_object.keyframe_insert(data_path="location", frame=frame)


Gruß Hobbyblenderer  Hä?
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste