Wind TurbineΒΆ

../../_images/anim_wturbine.png

Animation control:

Visualization

Frame Value

Surface geometry

constant

Surface position

rotated about the Y-coordinate axis

Surface color

constant

Shading and highlighting

fixed to the coordinate axis

Axis coordinate

constant

Based on the static plot from the Multiple Rotated Surfaces example.

import copy
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import s3dlib.surface as s3d

#.. Spiral wind turbine animation

# 0. Define animation control parameters ............................

totalTime, f_domain, numFrames = 1, (0.0,1.0), 60   # time in seconds
frames=np.linspace(*f_domain, numFrames, endpoint=False)
interval = int(1000.0*totalTime/numFrames)          # milliseconds

# 1. Define function to examine .....................................
rez,color = 5, '.8'
Ro,Rmax,Zmx,Zred = 0.04, .655, 0.586, 0.2

def blade( position=None ) :
    def blade_geom(rtz) :
        r,t,z = rtz       #  0 < t < 2pi  and  -1 < z < 1
        Znorm = (z+1)/2   #  normalized coor: 0 < Znorm < 1
        dltR = (Rmax - Ro)/(2*np.pi)
        Ra = dltR*(t + (Ro/dltR)  )
        R = Ro + (Ra-Ro)*Znorm
        G = Zred*( 1 - t/(2*np.pi) )
        F = 1 -Zmx*t/(2*np.pi)
        Z = (F-G)*Znorm + G
        return 2*R, t, 2*Z-1
    bladeN = s3d.CylindricalSurface(rez, 'squ_s', color=color)
    bladeN.map_geom_from_op(blade_geom)
    if position is not None:
        bladeN.transform(s3d.eulerRot(position,0))
    return bladeN

# 2. Setup surfaces .................................................

axle = s3d.CylindricalSurface(rez,'tri2_v',color=color).domain(.075,1.5)
turbine = blade() + blade(120) + blade(-120) + axle
turbine.transform( s3d.eulerRot(0,90)  )
turbinecopy = copy.copy(turbine)

# 3. Construct figure, add surface, plot ............................
minmax = (-1,1)
param = 'Ro: {:.3f}\nRmax: {:.3f}\n Zmx: {:.3f}\nZred: {:.3f}'.format(Ro,Rmax,Zmx,Zred)
fig = plt.figure(figsize=plt.figaspect(1),constrained_layout=True,facecolor='k')
fig.text(0.04,0.95,str(turbine), ha='left', fontsize='medium',)
fig.text(0.95,0.05,param,ha='right', va='bottom', fontsize='medium', 
    fontfamily='monospace', bbox={'edgecolor': 'k', 'facecolor': '0.95', 'pad': 5} )
ax = plt.axes(projection='3d', aspect='equal', proj_type='ortho')
ax.set(xlim=minmax, ylim=minmax, zlim=minmax)
ax.set_axis_off()
ax.view_init(12)
ax.add_collection3d(turbine.shade(.2).hilite(focus=2))

#plt.show()

# 4. Animation ======================================================

def update_fig(frame):
    global turbine
    turbine.remove()

    rot = 120*frame
    turbine = copy.copy(turbinecopy)
    turbine.transform(s3d.axisRot(rot,[0,1,0]))
    ax.add_collection3d(turbine.shade(.2).hilite(focus=2))
    return

anim = FuncAnimation(fig, update_fig, frames, interval=interval, repeat=True)
anim.save('wturbine.html',writer='html')

msg = "saved {} frames, values: [{:.3f} to {:.3f}] @ {} milliseconds/frane"
print(msg.format(numFrames,np.min(frames),np.max(frames),interval))