[Python] Zeichnung optimieren

Rationalisieren

Stromlinie des Strömungsfeldes, dargestellt durch das orthogonale Koordinatensystem $ \ boldsymbol {x} = (x, y) $, Geschwindigkeit $ \ boldsymbol {u} = (u, v) $ zu einem bestimmten Zeitpunkt $ t $ (Stromlinie) </ b> ist mathematisch eine normale Differentialgleichung $ \frac{\text{d} x}{\text{d} u(x,y,t)} = \frac{\text{d} y}{\text{d} v(x,y,t)} $ Es ist definiert durch. Stellen Sie sich vor, dass die in diesem Artikel vorgestellten Stromlinien nicht durch Lösen dieser normalen Differentialgleichung, sondern einfach durch Verbinden der Geschwindigkeitsvektoren gezeichnet werden.

Zeichnen Sie mit einem in matplotlib eingebauten Streamplot

Als Beispiel ein zweidimensionaler stationärer Taylor-Green-Wirbel: $ \begin{aligned} u &= \sin x \cos y \\\\ v &= -\cos x \sin y \end{aligned} $ Wird genutzt. Mit dem in matplotlib integrierten `` `streamplot``` können Sie problemlos Stromlinien zeichnen.


import matplotlib.pyplot as plt
import numpy as np
from numpy import sin, cos, pi, sqrt

n = 1000
x = np.linspace(0, 2*pi, n)
y = np.linspace(0, 2*pi, n)
X, Y = np.meshgrid(x, y)

# Taylor-Green Vortices
u = sin(X)*cos(Y)
v = - cos(X)*sin(X)
speed = sqrt(u**2 + v**2)

# Plot
plt.figure(1)
plt.streamplot(X, Y, u, v, density=3, color='k', arrowstyle='-', linewidth=0.6)
plt.contourf(X, Y, speed, 100, cmap='viridis')
plt.show()

Ich konnte eine Stromlinie zeichnen. Hintergrund ist die Strömungsgeschwindigkeit.

Zeichnen mit Line Integral Convolution (LIC)

Dies ist das Hauptthema. Das obige integrierte matplotlib-Streamplot ist schön genug, aber wenn Sie schöner (künstlerisch) zeichnen möchten, verwenden Sie die Methode Line Integral Convolution (LIC) </ b>. Wenn Sie es verwenden, können Sie Stromlinien sehr schön zeichnen. Es gibt eine kurze Erklärung in wikipedia. Informationen zum Algorithmus finden Sie in [Cabral and Leedom, 1993](https://dl.acm.org/doi/pdf/10.1145/166117.166151?casa_token=A78GoJh369IAAAAA%3AfWlns5xYUUWiQC09j8IIMBVDbqjc4jX4jX4jX4jX4jX4jX4jc4jX4jX4jc4JX4j2XJj4Jc4jX4jX4jj4Jc4jX4Jc4j2Jc4jc4jX4j2JJJJJJJJJJJJJ Beispiele für mit LIC gezeichnete Stromlinien sind Phillips et al., 2015 und Van Der Kindere et al., 2019 und so weiter. Ich bin dankbar, dass der Beispielcode in SciPy Cookbook enthalten ist. Sie können es verwenden, indem Sie `setup.py``` erstellen. Schreiben Sie die erste Hälfte des verknüpften `lic_demo.py``` neu. Da ich die Strömungsgeschwindigkeit im Hintergrund anzeigen möchte, multipliziere ich die Strömungsgeschwindigkeit in der letzten Zeile mit LIC.

Vector = np.stack([u, v], axis=2)
Vector = np.array(Vector, dtype=np.float32)
texture = np.random.rand(n, n).astype(np.float32)

plt.bone()
frame = 0
dpi = 1000
video = False
if video:
    kernellen = 31
    for t in np.linspace(0,1,16*5):
        kernel = np.sin(np.arange(kernellen)*np.pi/kernellen)*(1+np.sin(2*np.pi*5*(np.arange(kernellen)/float(kernellen)+t)))
        kernel = kernel.astype(np.float32)
        image = lic_internal.line_integral_convolution(Vector, texture, kernel)
        frame += 1
else:
    kernellen = 31
    kernel = np.sin(np.arange(kernellen)*np.pi/kernellen)
    kernel = kernel.astype(np.float32)
    image = lic_internal.line_integral_convolution(Vector, texture, kernel)

speed_LIC = image[1:-1, 1:-1]*speed[1:-1, 1:-1]

Es ist sehr schön.

Mathematica ist übrigens einfacher

Mathematica hat einen eingebauten `` `LineIntegralConvolutionPlot```!

LineIntegralConvolutionPlot[{{Sin[x] Cos[y], -Sin[y] Cos[x]}, {"noise", 1000, 1000}}, {x, 0, 2 Pi}, {y, 0, 2 Pi},  
ColorFunction -> "BlueGreenYellow", RasterSize -> 300]

Es wurde gerade gemacht ...

Recommended Posts