No BSD License  

Highlights from
Wing Designer

image thumbnail
from Wing Designer by John Rogers
Wing Designer computes aircraft performance measures from wing and engine parameters.

DeterminePanelGeometry(inputgeo, figs)
function [panel, Vol] = DeterminePanelGeometry(inputgeo, figs)
% find coordinates for horseshoe vortices and control points and plot
% Aircraft-Fixed coordinate system:
%       x: forward along fuselage axis
%       y: out starboard wing
%       z: down
% Local Profile coordinate system:
%       x: along chord from leading edge toward trailing edge
%       z: up

plot_on = 1;

%% constants
halfSpan=inputgeo.b/2;     % half wingspan
sweep=inputgeo.sweep;       % wing sweep angle in radians
dihedral=inputgeo.dih;    %dihedral angle in radians
nc=inputgeo.nc;  %number of panels on camber line, upper and lower surfaces
ns = inputgeo.ns; % number of span segments per side
M = inputgeo.M;    %Freestream mach number
beta = sqrt(1-M^2); %Prandtl-Glauert correction


%% Root Airfoil data
y=0;            % span station
chord=inputgeo.c_r;        % chord length
alphaRoot=inputgeo.i_r;    % geometric angle of incidence at root in radians

% call function
[Croot,Troot,Aroot]=NacaCoord(inputgeo.root,y,nc); % Croot = nondimensional camber line, Troot = nondimensional surface;
%Croot coordinates = [x location in fraction chord, y location in fraction
%                       chord, z location in fraction chord]
%Troot coordinates = [x location in fraction chord, y location in fraction
%                       chord, z location in fraction chord]

%% Scale to chord length
Croot(:,1)=chord*Croot(:,1);Croot(:,3)=chord*Croot(:,3);
Troot(:,1)=chord*Troot(:,1);Troot(:,3)=chord*Troot(:,3);
Aroot=Aroot*chord^2;

%Calculate slope of camber line for each panel at the root
%Calculate the chord along each elemental panel
dzdxRoot = zeros(1,nc);
ccRoot = zeros(1,nc);
if nc == 1 %If there is only one chordwise element
    i=1;
    dzdxRoot(i)=-(Croot(i+1,3)-Croot(i,3))/(Croot(i+1,1)-Croot(i,1));
    ccRoot(i)=0.75*(Croot(i+1,1)-Croot(i,1));
else        %if there are more than one chordwise elements
    for i=1:nc
        dzdxRoot(i)=(Croot(i+1,3)-Croot(i,3))/(Croot(i+1,1)-Croot(i,1));
        if i==nc
            ccRoot(i)=0.75*(Croot(i+1,1)-Croot(i,1));
        else
            ccRoot(i)=0.75*(Croot(i+1,1)-Croot(i,1))+0.25*(Croot(i+2,1)-Croot(i+1,1));
        end
    end
end

if plot_on
    axes(figs.root); cla;
    plot(Croot(:,1)*-3.2808,Croot(:,3)*-3.2808,'r') %Convert to feet; plot with z-axis positive up and x-axis to the left
    hold on
    plot(Troot(:,1)*-3.2808,Troot(:,3)*-3.2808,'b')  %Convert to feet; plot with z-axis positive up and x-axis to the left
    axis equal
    title('Root airfoil')
end

%% Tip Airfoil data
y=-halfSpan;     % span station; left wing
chord=inputgeo.taper*inputgeo.c_r;        % chord length
alphaTip=inputgeo.i_r+inputgeo.twist;    % geometric angle of incidence at tip in radians

%call function
[Ctip,Ttip,Atip]=NacaCoord(inputgeo.tip,y,nc);

%% scale to chord length
Ctip(:,1)=chord*Ctip(:,1);Ctip(:,3)=chord*Ctip(:,3);
Ttip(:,1)=chord*Ttip(:,1);Ttip(:,3)=chord*Ttip(:,3);
Atip=Atip*chord^2;

%Calculate slope of camber line for each panel at the tip
%Calculate the chord along each elemental panel
dzdxTip = zeros(1,nc);
ccTip = zeros(1,nc);
if nc == 1 %If there is only one chordwise element
    dzdxTip(i)=-(Ctip(i+1,3)-Ctip(i,3))/(Ctip(i+1,1)-Ctip(i,1));
    ccTip(i)=0.75*(Ctip(i+1,1)-Ctip(i,1));
else        %if there are more than one chordwise elements
    for i=1:nc
        dzdxTip(i)=(Ctip(i+1,3)-Ctip(i,3))/(Ctip(i+1,1)-Ctip(i,1));
        if i==nc
            ccTip(i)=0.75*(Ctip(i+1,1)-Ctip(i,1));
        else
            ccTip(i)=0.75*(Ctip(i+1,1)-Ctip(i,1))+0.25*(Ctip(i+2,1)-Ctip(i+1,1));
        end
    end
end

if plot_on
    axes(figs.tip); cla;
    plot(Ctip(:,1)*-3.2808,Ctip(:,3)*-3.2808,'r') %Convert to feet; plot with z-axis positive up and x-axis to the left
    hold on
    plot(Ttip(:,1)*-3.2808,Ttip(:,3)*-3.2808,'b') %Convert to feet; plot with z-axis positive up and x-axis to the left
    axis equal
    title('Tip airfoil')
end

%% Root: Transform to Aircraft-Fixed Coordinate System:
% skin:
%Skin(number of spanwise sections, number of chordwise sections, coordinates in 3 dimensions (x,y,z))
Skin(1,1:2*nc+1,1:3) = Troot*[cos(alphaRoot) 0 sin(alphaRoot); 0 1 0; -sin(alphaRoot) 0 cos(alphaRoot)];

% Mean camber line:
Camber(1,1:nc+1,1:3) = Croot*[cos(alphaRoot) 0 sin(alphaRoot); 0 1 0; -sin(alphaRoot) 0 cos(alphaRoot)];

%% Tip: Transform to Aircraft-Fixed Coordinate System:
% sweep and dihedral
% Negative sign occurs because local axes are opposite to global
xLETip = -halfSpan*(tan(sweep));% x coordinate of Leading Edge at Tip
zLETip = -halfSpan*(tan(dihedral));% z coordinate of Leading Edge at Tip
% Skin:
LETip=ones(2*nc+1,1)*[xLETip 0 zLETip];
Skin(ns+1,1:2*nc+1,1:3) = Ttip*[cos(alphaTip) 0 sin(alphaTip); 0 1 0; -sin(alphaTip) 0 cos(alphaTip)]+LETip;

% Mean camber line
LETip=ones(nc+1,1)*[xLETip 0 zLETip];
Camber(ns+1,1:nc+1,1:3) = Ctip*[cos(alphaTip) 0 sin(alphaTip); 0 1 0; -sin(alphaTip) 0 cos(alphaTip)]+LETip;

%% Intermediate stations
for k=1:ns-1 % k = 0 corresponds to root, k = ns corresponds to tip
    eta=k/ns;
    for i=1:nc+1 % along camber
        Camber(k+1,i,:) = Camber(1,i,:)+eta*(Camber(ns+1,i,:)-Camber(1,i,:));
    end
    for i=1:2*nc+1 %along surface
        Skin(k+1,i,:) = Skin(1,i,:)+eta*(Skin(ns+1,i,:)-Skin(1,i,:));
    end
end

if plot_on
    %Plot wing surface
    axes(figs.fig); cla; hold on; axis equal; 
    for k=1:ns+1
        plot3(Skin(k,:,1)*-3.2808,Skin(k,:,2)*3.2808,Skin(k,:,3)*-3.2808);  %Convert to feet; plot with z-axis positive up and x-axis to the left
        plot3(Skin(k,:,1)*-3.2808,-Skin(k,:,2)*3.2808,Skin(k,:,3)*-3.2808);  %Convert to feet; plot with z-axis positive up and x-axis to the left
        plot3(Camber(k,:,1)*-3.2808,Camber(k,:,2)*3.2808,Camber(k,:,3)*-3.2808,'r')  %Convert to feet; plot with z-axis positive up and x-axis to the left
    end
    for i=1:size(Skin,2)
    plot3(Skin(:,i,1)*-3.2808,Skin(:,i,2)*3.2808,Skin(:,i,3)*-3.2808);
    plot3(Skin(:,i,1)*-3.2808,-Skin(:,i,2)*3.2808,Skin(:,i,3)*-3.2808);
    end
end


%Determine panel properties
twist = zeros(1,ns);
dzdx = zeros(ns,nc);
cc = zeros(ns,nc);
CP = zeros(ns,nc,3);
BV = zeros(ns,nc,3);
BV1 = zeros(ns,nc,3);
BV2 = zeros(ns,nc,3);
BVhalfspan = zeros(ns,nc);
sweep_c4 = zeros(ns,nc);

for k = 1:ns
    %Determine local twist at each panel, dz/dx at control points, and
    %chord along left trailing leg of elemental panel
    eta=k/(ns+1);
    twist(k)=alphaRoot+eta*(alphaTip-alphaRoot);
    dzdx(k,:)=dzdxRoot+eta*(dzdxTip-dzdxRoot);
    cc(k,:)=ccRoot+eta*(ccTip-ccRoot);  %Validated
    %Determine control point coordinates, coordinates to center of bound
    %vortex, half span of bound vortex, and quarter-chord sweep angle
    for i = 1:nc
        CP(k,i,:)=0.5*(Camber(k,i,:)+Camber(k+1,i,:))+0.75*(0.5*(Camber(k,i+1,:)+Camber(k+1,i+1,:))-0.5*(Camber(k,i,:)+Camber(k+1,i,:)));
        BV(k,i,:)=0.5*(Camber(k,i,:)+Camber(k+1,i,:))+0.25*(0.5*(Camber(k,i+1,:)+Camber(k+1,i+1,:))-0.5*(Camber(k,i,:)+Camber(k+1,i,:)));
        BV1(k,i,:)=0.75*Camber(k+1,i,:)+0.25*Camber(k+1,i+1,:);  %Left bound vortex coordinate
        BV2(k,i,:)=0.75*Camber(k,i,:)+0.25*Camber(k,i+1,:);  %Right bound vortex coordinate
        BVhalfspan(k,i)= 0.5*(0.75*norm(shiftdim(Camber(k,i,2:3)-Camber(k+1,i,2:3)))+0.25*norm(shiftdim(Camber(k,i+1,2:3)-Camber(k+1,i+1,2:3))));
        %Only consider [Y,Z] distances due to definition of halfspan in
        %NASA paper; considering X distance as well makes halfspan increase
        %greatly as you increase sweep and invalidates calculations
        %Validated BVhalfspan calculation through (1:ns-1,1:nc)
        sweep_c4(k,i)=atan((Camber(k,i,1)-Camber(k+1,i,1))/(Camber(k,i,2)-Camber(k+1,i,2))); %Validated
    end
end

%Prandtl-Glauert corrections
CPprime = CP(:,:,1)/beta;
BVprime = BV(:,:,1)/beta;
BV1prime = BV1(:,:,1)/beta;
BV2prime = BV2(:,:,1)/beta;
sweep_c4_prime = atan(tan(sweep_c4)/beta);

for k = 1:ns
    for i  = 1:nc
        panel(k,i).CP=shiftdim(CP(k,i,:));  %Removing singleton dimensions
        panel(k,i).BV=shiftdim(BV(k,i,:)); %Removing singleton dimensions
        panel(k,i).BV1=shiftdim(BV1(k,i,:)); %Removing singleton dimensions
        panel(k,i).BV2=shiftdim(BV2(k,i,:)); %Removing singleton dimensions
        panel(k,i).dzdx=dzdx(k,i);
        panel(k,i).twist=twist(k);
        panel(k,i).s=BVhalfspan(k,i);
        panel(k,i).sweep=sweep_c4(k,i);
        panel(k,i).sweepprime=sweep_c4_prime(k,i);
        panel(k,i).CPprime=CPprime(k,i);
        panel(k,i).BVprime=BVprime(k,i);
        panel(k,i).BV1prime=BV1prime(k,i);
        panel(k,i).BV2prime=BV2prime(k,i);
        panel(k,i).cc=cc(k,i);
    end
end

%Determine wing volume
Vol = 1/3*(Aroot +sqrt(Aroot*Atip) + Atip)*inputgeo.b;

Contact us