bash
复制代码
% ==========================================================
% 高仿真无人机 | 全动态旋转动画
% 大疆风格 + 完美结构 + 流畅动画
% ==========================================================
clear; clc; close all;
% 窗口设置
f = figure('Color','w','Position',[100,100,900,700]);
ax = axes('Color',[0.96 0.98 1],'DataAspectRatio',[1 1 1]);
hold on; grid on; box on;
xlabel('X'); ylabel('Y'); zlabel('Z');
view(60,25);
lighting gouraud;
material shiny;
axis([-5 5 -5 5 -2 3]);
%% 1. 流线型机身(真实无人机造型)
body_color = [0.05 0.12 0.25];
[x,y,z] = ellipsoid(0,0,0, 1.8, 0.9, 0.5);
surf(x,y,z,'FaceColor',body_color,'EdgeColor','none');
% 顶部视觉模块
[x2,y2,z2] = cylinder(0.4,50);
z2 = z2*0.25 - 0.12;
surf(x2,y2,z2,'FaceColor',[0.02 0.05 0.1],'EdgeColor','none');
%% 2. 碳纤维机臂(从机身中心连接到旋翼)
arm_R = 0.12;
arm_L = 3.2;
arm_color = [0.1 0.1 0.13];
arm_points = [arm_L,arm_L,0; -arm_L,arm_L,0; arm_L,-arm_L,0; -arm_L,-arm_L,0];
for i = 1:4
cylinder3d([0,0,0], arm_points(i,:), arm_R, arm_color);
end
%% 3. 电机底座(真实结构)
motor_R = 0.28;
motor_H = 0.22;
for i = 1:4
[xm,ym,zm] = cylinder(motor_R,50);
zm = zm*motor_H - 0.11;
xm = xm + arm_points(i,1);
ym = ym + arm_points(i,2);
surf(xm,ym,zm,'FaceColor',[0 0 0],'EdgeColor','none');
end
%% 4. 起落架
leg_color = [0.08 0.08 0.1];
plot3([1.2 1.2],[1.2 1.2],[0 -1.2],'Color',leg_color,'LineWidth',4);
plot3([-1.2 -1.2],[1.2 1.2],[0 -1.2],'Color',leg_color,'LineWidth',4);
plot3([1.2 1.2],[-1.2 -1.2],[0 -1.2],'Color',leg_color,'LineWidth',4);
plot3([-1.2 -1.2],[-1.2 -1.2],[0 -1.2],'Color',leg_color,'LineWidth',4);
% 脚垫
pad_pos = [1.2,1.2,-1.2; -1.2,1.2,-1.2; 1.2,-1.2,-1.2; -1.2,-1.2,-1.2];
for i = 1:4
[xp,yp,zp] = cylinder(0.15,30);
zp = zp*0.1 - 0.05;
xp = xp + pad_pos(i,1); yp = yp + pad_pos(i,2); zp = zp + pad_pos(i,3);
surf(xp,yp,zp,'FaceColor',[0 0 0],'EdgeColor','none');
end
%% ====================== 核心:4 叶旋翼(每个旋翼 4 片桨叶)======================
blade_len = 1.25;
blade_w = 0.11;
blade_color = [0.93 0.93 0.96];
blades = [];
for m = 1:4
ox = arm_points(m,1);
oy = arm_points(m,2);
oz = 0.15;
% 每个旋翼 4 个叶片(0°、90°、180°、270°)
for k = 0:3
ang = k * pi/2;
bx = [ox, ox+blade_len*cos(ang)-blade_w*sin(ang), ox+blade_len*cos(ang)+blade_w*sin(ang), ox];
by = [oy, oy+blade_len*sin(ang)+blade_w*cos(ang), oy+blade_len*sin(ang)-blade_w*cos(ang), oy];
bz = [oz, oz+0.02, oz+0.02, oz];
p = patch(bx,by,bz,blade_color,'EdgeColor',[0.1 0.1 0.12],'FaceAlpha',0.98);
blades = [blades, p];
end
end
%% 灯光
light('Position',[6,6,8],'Color',[1 1 1]);
light('Position',[-6,-6,6],'Color',[0.9 0.9 1]);
light('Position',[0,7,4],'Color',[1 1 0.95]);
%% ====================== 旋翼旋转动画 ======================
angle = 0;
while ishandle(f)
angle = angle + 6; % 旋转速度
if angle > 360
angle = 0;
end
% 4个旋翼,每个4片桨叶一起旋转
for m = 1:4
baseIdx = (m-1)*4 + 1;
ox = arm_points(m,1);
oy = arm_points(m,2);
oz = 0.15;
for k = 0:3
currentAng = angle + k*90;
idx = baseIdx + k;
bx = [ox, ox+blade_len*cosd(currentAng)-blade_w*sind(currentAng), ...
ox+blade_len*cosd(currentAng)+blade_w*sind(currentAng), ox];
by = [oy, oy+blade_len*sind(currentAng)+blade_w*cosd(currentAng), ...
oy+blade_len*sind(currentAng)-blade_w*cosd(currentAng), oy];
bz = [oz, oz+0.02, oz+0.02, oz];
set(blades(idx),'XData',bx,'YData',by,'ZData',bz);
end
end
drawnow;
end
%% 辅助函数:3D圆柱体
function cylinder3d(startPos,endPos,r,color)
dirVec = endPos - startPos;
L = norm(dirVec);
dirVec = dirVec / L;
[X,Y,Z] = cylinder(r,50);
Z = Z * L;
R = rotMatrix([0,0,1],dirVec);
for i = 1:size(X,1)
for j = 1:size(X,2)
vec = R * [X(i,j); Y(i,j); Z(i,j)];
X(i,j) = vec(1) + startPos(1);
Y(i,j) = vec(2) + startPos(2);
Z(i,j) = vec(3) + startPos(3);
end
end
surf(X,Y,Z,'FaceColor',color,'EdgeColor','none');
end
function R = rotMatrix(v1,v2)
v = cross(v1,v2);
s = norm(v);
c = dot(v1,v2);
vx = [0,-v(3),v(2); v(3),0,-v(1); -v(2),v(1),0];
R = eye(3) + vx + vx^2*(1-c)/(c+1);
end