PyFoil, disegna profili alari con il cellulare
PyFoil è un semplice programmino scritto da me in Python che permette di disegnare profili NACA a 4 e 5 cifre, direttamente dal cellulare.
Per poterlo utilizzare è necessario installare il software Python for S60 sul proprio cellulare, che è reperibile a questo indirizzo.
Ecco alcuni screenshot del programma:

Segue il codice dell’applicazione.
import e32
import graphics
import appuifw
from math import sqrt, sin, cos, tan, atan, log10, ceil
def draw(r=None):
if buffer:
c.blit(buffer)
appuifw.app.orientation = 'landscape'
appuifw.app.screen = 'full'
c = appuifw.Canvas(redraw_callback=draw)
buffer = graphics.Image.new(c.size)
appuifw.app.body = c
width, height = c.size
airfoil, digit, t, m, p = [None for i in range(5)]
def set_NACA():
# Set NACA to operate
global airfoil, digit, t, m, p
airfoil = appuifw.query(u'Insert 4 digit NACA', 'number')
digit = ceil(log10(airfoil))
# Digit correction for 00XX and 000X
if digit in [1, 2]: digit = 4
t = (airfoil%100)/100. # Thickness
if digit == 4:
m = (airfoil/1000)/100. # Max camber
p = (airfoil/100-airfoil/1000*10)/10. # Max camber position
NACA_plot()
elif digit == 5:
mean_line_datas = {210:[0.0580, 361.4],
220:[0.1260, 51.64],
230:[0.2025, 15.957],
240:[0.2900, 6.643],
250:[0.3910, 3.230]}
try:
m = mean_line_datas[airfoil/100][0]
p = mean_line_datas[airfoil/100][1]
NACA_plot()
except KeyError:
appuifw.note(u'NACA not supported!', 'error')
else:
appuifw.note(u'NACA must be 4 or 5 digit!', 'error')
def derivative(func, x):
# Derivates a function
return (func(x) - func(x+0.01))/0.01
def mean_line(x):
# Airfoil mean line function
if digit == 4:
if p == 0:
return 0
elif x <= p:
return m/(p**2)*(2*p*x-x**2)
elif x > p:
return m*(1-2*p+2*p*x-x**2)/((1-p)**2)
elif digit == 5:
if x <= m:
return p/6*(x**3-3*m*x**2+m**2*(3-m)*x)
elif x > m:
return p*m**3/6*(1-x)
def thickness(x):
# Airfoil thickness function
return t /0.2*(0.2969*sqrt(x)-0.126*x-0.3516*x**2+0.2843*x**3-0.1015*x**4)
def NACA_plot():
# Plots a NACA
if not airfoil: set_NACA()
buffer.clear()
font = (None, 30)
color0 = (0, 0, 0) # Text color
color1 = (0, 0, 255) # Airfoil color
color2 = (255, 0, 0) # Meanline color
color3 = (100, 100, 100) # Radius color
# Draws the axes
y0 = height/2 # Origin
buffer.line((0, y0, width, y0), outline=color0)
# Draws the scale
for u in range(11):
buffer.line((u*width/10, y0-2, u*width/10, y0+2), outline=color0)
buffer.line((10, 2*y0-20, 10+width/10, 2*y0-20), outline=color0)
buffer.text((20+width/10, 2*y0-15), u'10% of the chord', fill=color0)
# Displays infos about the airfoil
radius = 1.1019*t**2
radius_pos = (0, y0 - radius*width, radius*width*2, y0 + radius*width)
buffer.ellipse(radius_pos, outline=color3)
buffer.text((10, 30), u'NACA %0#4d' % airfoil, font=font, fill=color0)
buffer.text((10, 55), u'Leading Edge radius: %.4f' % radius, fill=color0)
# Plot
for x in range(width):
x = float(x)/width
# Meanline
buffer.point((x*width, y0 - mean_line(x)*width), outline=color2)
# Airfoil
teta = atan(derivative(mean_line, x))
xU = (x - thickness(x)*sin(teta)) * width
yU = y0 - (mean_line(x) - thickness(x)*cos(teta)) * width
xL = (x + thickness(x)*sin(teta)) * width
yL = y0 - (mean_line(x) + thickness(x)*cos(teta)) * width
buffer.point((xU, yU), outline=color1, width=2)
buffer.point((xL, yL), outline=color1, width=2)
draw()
def velocity_field():
# Solve the velocity field
appuifw.note(u'Coming soon!', 'info')
def quit():
e32.Ao_lock().signal()
# Starting graphics
color = (0, 0, 0)
font1 = (u'Nokia Hindi TitleSmBd S6', 30)
font2 = (u'Nokia Hindi TitleSmBd S6', 15)
text1 = u'NACA PyFoil'
text2 = u'By Ale152'
box1 = buffer.measure_text(text1, font1)
box2 = buffer.measure_text(text2, font2)
position1 = ((width-box1[0][2])/2, 30)
position2 = ((width-box2[0][2])/2, 50)
buffer.text(position1, text1, font=font1, fill=color)
buffer.text(position2, text2, font=font2, fill=color)
for x in range(width):
x = float(x)/width
t = 0.12
buffer.point((x*width, height/2-thickness(x)*width), outline=color)
buffer.point((x*width, height/2+thickness(x)*width), outline=color)
draw()
appuifw.app.menu = [(u'Plot', NACA_plot),
(u'Velocity field', velocity_field),
(u'Set NACA', set_NACA),
(u'Quit', quit)]
app_lock = e32.Ao_lock()
app_lock.wait()
