在只有一条折痕的情况下(即此时的参数条件),计算每个中间折痕处的折叠角:% main_multiple_folds.m - 多折痕曲纹折纸机构运动学建模
% Multi-fold curved origami mechanism kinematic modeling
clear; clc; close all
%% 参数设置 - Parameter Settings
% 思路:基于单个折痕的扩展逻辑,将折痕横向扩展到多条
% Concept: Extend single fold logic to multiple parallel folds
% 生成扇形角度 - Generate sector angles
theta_deg = [];
N_vertices =13; % 每条折痕的顶点数 - Number of vertices per fold
N_folds =1; % 折痕数量 - Number of folds
% %直纹折纸
% %为每个顶点生成扇形角度 - Generate sector angles for each vertex
% theta_deg(:,1) = 95*ones(N_vertices,1) + rand(N_vertices,1)*0;
% theta_deg(:,2) = 85*ones(N_vertices,1) + rand(N_vertices,1)*0;
% theta_deg(:,3) = 60*ones(N_vertices,1) + rand(N_vertices,1)*0;
% theta_deg(:,4) = 120*ones(N_vertices,1) + rand(N_vertices,1)*0;
% theta_deg(:,3) = 180*ones(N_vertices,1) - theta_deg(:,1); % 条件(2)
% theta_deg(:,4) = 360*ones(N_vertices,1) - (theta_deg(:,1)+theta_deg(:,2)+theta_deg(:,3));
% %曲纹折纸(常曲率)
% s=10;
% ds=0.1;
% N_vertices=s/ds+1;
% kl=-0.1;kr=kl;%可折展
% phl=0/180*pi;phr=phl;
% rr=1/abs(kr);rl=1/abs(kl);
% dthr=2*atan(ds/(2*rr));dthl=2*atan(ds/(2*rl));
% theta_deg(:,1)=rad2deg(pi/2+sign(kr)*(dthr/2)+phr)*ones(N_vertices,1);
% theta_deg(:,2)=rad2deg(pi/2+sign(kr)*(dthr/2)-phr)*ones(N_vertices,1);
% theta_deg(:,3)=rad2deg(pi/2-sign(kl)*(dthl/2)+phl)*ones(N_vertices,1);
% theta_deg(:,4)=rad2deg(pi/2-sign(kl)*(dthl/2)-phl)*ones(N_vertices,1);
%曲纹折纸(变曲率)
s=15;
B=30;%离散程度
ds=s/B;
N_vertices=B+1;
for i=1:N_vertices
kl(i)=(0.05*ds*(i-1))^3.1;
kr=kl;
phl=0/180*pi;phr=phl;
rr(i)=1/abs(kr(i));rl(i)=1/abs(kl(i));
dthr(i)=2*atan(ds/(2*rr(i)));dthl(i)=2*atan(ds/(2*rl(i)));
theta_deg(i,1)=rad2deg(pi/2+sign(kr(i))*(dthr(i)/2)+phr);
theta_deg(i,2)=rad2deg(pi/2+sign(kr(i))*(dthr(i)/2)-phr);
theta_deg(i,3)=rad2deg(pi/2-sign(kl(i))*(dthl(i)/2)+phl);
theta_deg(i,4)=rad2deg(pi/2-sign(kl(i))*(dthl(i)/2)-phl);
end
th0=theta_deg(1,1);th1 = theta_deg(1,2);th2 = theta_deg(1,3);
I=1e-10;
%% 主循环参数 - Main loop parameters
for i_total =160 % % 折叠角度参数 - Folding angle parameter
% 基本参数设置 - Basic parameter setup
%l_initial=[1,0.6,1]*0.1; % 初始长度 - Initial lengths
l_initial=[1,ds,1]*0.1; % 初始长度 - Initial lengths
%l_initial=[1 ,1.5,1]*0.1; % 初始长度 - Initial lengths
c_scale = 1; % 缩放因子 - Scaling factor %曲纹折纸不适合非等距,因为改变了每条折痕曲率
rho_initial_deg = i_total; % 初始折叠角度 - Initial folding angle
sigma_geom_choice = -1; % 几何选择参数 - Geometry choice parameter
% 转换为弧度 - Convert to radians
theta_rad = deg2rad(theta_deg);
rho_central_rad = deg2rad(i_total);
%% 计算初始折痕 - Calculate initial fold
[P_center_0, P_left_0, P_right_0, actual_N_vertices] = calculate_3d_strip_geometry(...
theta_rad, rho_central_rad, l_initial, c_scale, sigma_geom_choice, N_vertices);
if isempty(P_center_0)
fprintf('Failed to calculate initial 3D geometry. Check parameters.\n');
return;
end
%% 多折痕扩展 - Multiple fold expansion
% 存储所有折痕的数据 - Store data for all folds
P_center_all = cell(N_folds, 1); % 中心线点 - Center line points
P_left_all = cell(N_folds, 1); % 左边界点 - Left boundary points
P_right_all = cell(N_folds, 1); % 右边界点 - Right boundary points
% 第一条折痕(原始折痕)- First fold (original fold)
P_center_all{1} = P_center_0;
P_left_all{1} = P_left_0;
P_right_all{1} = P_right_0;
% 生成多条折痕 - Generate multiple folds
for fold_idx = 2:N_folds
% 获取前一条折痕作为参考 - Get previous fold as reference
PR_prev_center = P_right_all{fold_idx-1};
PR_prev_left = P_center_all{fold_idx-1};
%% 计算前一条折痕的角度参数 - Calculate angle parameters for previous fold
PR_th2_ = zeros(1, length(PR_prev_center)-1);
PR_th3_ = zeros(1, length(PR_prev_center)-1);
% a=P_right_0(:,2)-P_right_0(:,1);
% b=P_center_0(:,1)-P_right_0(:,1);
% dot_product = dot(a, b);
% norm_a = norm(a);
% norm_b = norm(b);
% th10 = acosd(dot_product / (norm_a * norm_b));
a=PR_prev_center(:,1)-PR_prev_center(:,2);
b=PR_prev_left (:,2)-PR_prev_center(:,2);
dot_product = dot(a, b);
norm_a = norm(a);
norm_b = norm(b);
th10 = 180-acosd(dot_product / (norm_a * norm_b));
for i_ = 1:length(PR_prev_center)-1
% 计算向量夹角 - Calculate vector angles
A = (PR_prev_center(:,i_+1) - PR_prev_center(:,i_));
B = (PR_prev_left(:,i_) - PR_prev_center(:,i_));
dot_product = dot(A, B);
norm_A = norm(A);
norm_B = norm(B);
cos_theta(i_) = dot_product / (norm_A * norm_B);
PR_th2_(i_) = acos(cos_theta(i_));
end
for i_ = 2:length(PR_prev_center)
A = (PR_prev_center(:,i_-1) - PR_prev_center(:,i_));
B1 = (PR_prev_left(:,i_) - PR_prev_center(:,i_));
dot_product1 = dot(A, B1);
norm_B1 = norm(B1);
cos_theta(i_) = dot_product1 / (norm_A * norm_B1);
PR_th3_(i_) = acos(cos_theta(i_));
end
%
c=P_left_0(:,end-1)-P_left_0(:,end);
d=P_center_0(:,end)-P_left_0(:,end);
dot_product = dot(c, d);
norm_c = norm(c);
norm_d = norm(d);
th00 = acosd(dot_product / (norm_c * norm_d));
%% 计算新折痕的角度参数 - Calculate new fold angle parameters
PR_th2 = rad2deg(PR_th2_);
PR_th0 =180- PR_th2;
%% 生成新折痕的右边界 - Generate right boundary for new fold
% 计算第一个点的位置 - Calculate position of first point
A = (PR_prev_center(:,2) - PR_prev_center(:,1));
B = (PR_prev_left(:,1) - PR_prev_center(:,1));
% 计算法向量 - Calculate normal vector
PR_normal_Vector = cross(A, B);
if rem(fold_idx,2)==1
sign_flag = -1;
PR_th1 = th1;
PR_th0(N_vertices )=theta_deg(N_vertices,1);
else
sign_flag = 1;
PR_th1 = th10;
PR_th0(N_vertices )=PR_th0(N_vertices-1 );
end
% 旋转法向量 - Rotate normal vector
PR_right_normal_Vector = (RotationofRandL(PR_prev_center(:,1), ...
PR_prev_center(:,1) + PR_normal_Vector, A, deg2rad(sign_flag*i_total))) - PR_prev_center(:,1)';
% 计算旋转后的点 - Calculate rotated point
PR_right_ = RotationofRandL(PR_prev_center(:,1), PR_prev_center(:,2), ...
PR_right_normal_Vector/norm(PR_right_normal_Vector), -deg2rad(PR_th1));
% 新折痕的右边界点 - Right boundary points for new fold
PR_right = zeros(3, N_vertices);
PR_right(:,1) = PR_prev_center(:,1) + l_initial(3) *...
(PR_right_' - PR_prev_center(:,1)) / norm((PR_right_' - PR_prev_center(:,1)));
% 迭代计算其余点 - Iteratively calculate remaining points
for i = 2:N_vertices
A = (PR_right(:,i-1) - PR_prev_center(:,i-1));
B = (PR_prev_center(:,i) - PR_prev_center(:,i-1));
PR_normal_Vector = cross(A, B);
PR_right_normal_Vector = PR_normal_Vector / norm(PR_normal_Vector);
PR_right_1 = RotationofRandL(PR_prev_center(:,i), PR_prev_center(:,i-1), ...
PR_right_normal_Vector / norm(PR_right_normal_Vector), deg2rad(PR_th0(i)));
PR_right(:,i) = PR_prev_center(:,i) + l_initial(3) * c_scale^(i-1) * ...
(PR_right_1' - PR_prev_center(:,i)) / norm((PR_right_1' - PR_prev_center(:,i)));
end
% 存储新折痕数据 - Store new fold data
P_center_all{fold_idx} = PR_prev_center;
P_left_all{fold_idx} = PR_prev_left;
P_right_all{fold_idx} = PR_right;
% 打印进度信息 - Print progress information
fprintf('第 %d 条折痕计算完成 - Fold %d calculation completed\n', fold_idx, fold_idx);
end
%% 可视化所有折痕 - Visualize all folds
figure(122);
clf; % 清除图形 - Clear figure
hold on;
axis equal;
% 颜色映射 - Color mapping
colors1 = hsv(N_folds);
colors2 = jet(N_folds);
for fold_idx = 1:N_folds
P_center_curr = P_center_all{fold_idx};
P_left_curr = P_left_all{fold_idx};
P_right_curr = P_right_all{fold_idx};
if fold_idx == 1
first_point = P_center_curr(:,1);
% 绘制坐标系标记
% X轴(红色)
quiver3(first_point(1), first_point(2), first_point(3), 0.1, 0, 0, ...
'Color', 'r', 'LineWidth', 2, 'MaxHeadSize', 1.5, 'AutoScale', 'off');
% Y轴(绿色)
quiver3(first_point(1), first_point(2), first_point(3), 0, 0.1, 0, ...
'Color', 'g', 'LineWidth', 2, 'MaxHeadSize', 1.5, 'AutoScale', 'off');
% Z轴(蓝色)
quiver3(first_point(1), first_point(2), first_point(3), 0, 0, 0.1, ...
'Color', 'b', 'LineWidth', 2, 'MaxHeadSize', 1.5, 'AutoScale', 'off');
% 添加点标记
plot3(first_point(1), first_point(2), first_point(3), 'ko', ...
'MarkerSize', 5, 'MarkerFaceColor', 'y');
end
% 绘制每个折痕的面板 - Draw panels for each fold
for i = 1:N_vertices-1
% 左面板坐标 - Left panel coordinates
x_l = [P_center_curr(1,i) P_center_curr(1,i+1) P_left_curr(1,i+1) P_left_curr(1,i) P_center_curr(1,i)];
y_l = [P_center_curr(2,i) P_center_curr(2,i+1) P_left_curr(2,i+1) P_left_curr(2,i) P_center_curr(2,i)];
z_l = [P_center_curr(3,i) P_center_curr(3,i+1) P_left_curr(3,i+1) P_left_curr(3,i) P_center_curr(3,i)];
% 右面板坐标 - Right panel coordinates
x_r = [P_center_curr(1,i) P_center_curr(1,i+1) P_right_curr(1,i+1) P_right_curr(1,i) P_center_curr(1,i)];
y_r = [P_center_curr(2,i) P_center_curr(2,i+1) P_right_curr(2,i+1) P_right_curr(2,i) P_center_curr(2,i)];
z_r = [P_center_curr(3,i) P_center_curr(3,i+1) P_right_curr(3,i+1) P_right_curr(3,i) P_center_curr(3,i)];
% 绘制和填充面板 - Draw and fill panels
% plot3(x_l, y_l, z_l, '.-', 'LineWidth', 2, 'Color', colors1(fold_idx,:));
% plot3(x_r, y_r, z_r, '-', 'LineWidth', 2, 'Color', colors2(fold_idx,:));
% plot3(x_l, y_l, z_l, '.');
% plot3(x_r, y_r, z_r, '*' );
% % 填充颜色 - Fill color
fill3(x_l, y_l, z_l, colors1(fold_idx,:));
fill3(x_r, y_r, z_r, colors2(fold_idx,:));
end
end
axis off
% % 设置图形属性 - Set figure properties
% xlabel('X 坐标 - X Coordinate');
% ylabel('Y 坐标 - Y Coordinate');
% zlabel('Z 坐标 - Z Coordinate');
% title(sprintf('多折痕曲纹折纸机构 (%d 条折痕) - Multi-fold Curved Origami (%d folds)', N_folds, N_folds));
% % grid on;
% material shiny;
% light('Position',[0 0 0]);
% alpha(1); % 设置透明度
%view(3)
view(0,90);
% % 添加图例 - Add legend
% legend_entries = cell(N_folds, 1);
% for fold_idx = 1:N_folds
% legend_entries{fold_idx} = sprintf('折痕 %d - Fold %d', fold_idx, fold_idx);
% end
%% 验证几何一致性 - Verify geometric consistency
fprintf('\n=== 几何一致性验证 - Geometric Consistency Verification ===\n');
for fold_idx = 1:N_folds
P_center_curr = P_center_all{fold_idx};
P_right_curr = P_right_all{fold_idx};
% 计算共面性检验 - Calculate coplanarity test
triple_scalars = zeros(1, length(P_center_curr)-1);
for i_ = 1:length(P_center_curr)-1
P1 = P_center_curr(:,i_);
P2 = P_center_curr(:,i_+1);
P3 = P_right_curr(:,i_);
P4 = P_right_curr(:,i_+1);
% 计算混合积 - Calculate scalar triple product
v1 = P2 - P1;
v2 = P3 - P1;
v3 = P4 - P1;
triple_scalars(i_) = dot(v1, cross(v2, v3));
end
% 输出验证结果 - Output verification results
max_deviation = max(abs(triple_scalars));
fprintf('折痕 %d: 最大共面偏差 = %.2e - Fold %d: Max coplanarity deviation = %.2e\n', ...
fold_idx, max_deviation, fold_idx, max_deviation);
if max_deviation < 1e-10
fprintf(' ✓ 几何一致性良好 - Good geometric consistency\n');
else
fprintf(' ⚠ 存在几何偏差 - Geometric deviation detected\n');
end
end
%% 角度分析 - Angle analysis
% figure(123);
% clf;
% hold on;
%
% for fold_idx = 1
%
% % 计算角度变化 - Calculate angle changes
% P_center_curr = P_center_all{fold_idx};
% P_left_curr = P_left_all{fold_idx};
%
% angles_th2 = zeros(1, length(P_center_curr)-1);
% angles_th3 = zeros(1, length(P_center_curr)-1);
%
% for i_ = 1:length(P_center_curr)-1
% A = (P_center_curr(:,i_+1) - P_center_curr(:,i_));
% B = (P_left_curr(:,i_) - P_center_curr(:,i_));
%
% dot_product = dot(A, B);
% norm_A = norm(A);
% norm_B = norm(B);
% cos_theta = dot_product / (norm_A * norm_B);
%
% if i_ == 1
% angles_th2(i_) = acos(cos_theta);
% angles_th3(i_) = 0;
% else
% B1 = (P_left_curr(:,i_+1) - P_center_curr(:,i_+1));
% dot_product1 = dot(-A, B1);
% norm_B1 = norm(B1);
% cos_theta1 = dot_product1 / (norm_A * norm_B1);
%
% angles_th2(i_) = acos(cos_theta);
% angles_th3(i_) = acos(cos_theta1);
% end
% end
%
% % 绘制角度变化 - Plot angle changes
% plot(rad2deg(angles_th2), 'o-', 'LineWidth', 2, 'Color', colors1(fold_idx,:), ...
% 'DisplayName', sprintf('折痕 %d - θ2', fold_idx));
% plot(rad2deg(angles_th3), 's--', 'LineWidth', 2, 'Color', colors2(fold_idx,:), ...
% 'DisplayName', sprintf('折痕 %d - θ3', fold_idx));
%
% end
%
% xlabel('顶点索引 - Vertex Index');
% ylabel('角度 (度) - Angle (degrees)');
% title('多折痕角度分析 - Multi-fold Angle Analysis');
% legend('show');
% grid on;
%% 输出总结信息 - Output summary information
fprintf('\n=== 计算总结 - Calculation Summary ===\n');
fprintf('总折痕数量 - Total number of folds: %d\n', N_folds);
fprintf('每条折痕顶点数 - Vertices per fold: %d\n', N_vertices);
fprintf('计算完成 - Calculation completed successfully\n');
end
fprintf('\n多折痕曲纹折纸机构建模完成!- Multi-fold curved origami modeling completed!\n');
%% === 添加代码:整合所有点坐标到单一矩阵 ===
% 计算总点数 (每条折痕有3类点 * N_vertices个顶点)
totalPoints = N_folds * N_vertices * 3;
% 初始化坐标矩阵 (3行: x,y,z; totalPoints列)
allPointsMatrix = zeros(3, totalPoints);
% 当前索引指针
currentIdx = 1;
% 遍历所有折痕
for foldIdx = 1:N_folds
% 当前折痕的点集
P_center = P_center_all{foldIdx};
P_left = P_left_all{foldIdx};
PR_right = P_right_all{foldIdx};
% 将中心点添加到矩阵
allPointsMatrix(:, currentIdx:currentIdx+N_vertices-1) = P_left;
currentIdx = currentIdx + N_vertices;
% 将左边界点添加到矩阵
allPointsMatrix(:, currentIdx:currentIdx+N_vertices-1) = P_center;
currentIdx = currentIdx + N_vertices;
% 将右边界点添加到矩阵
allPointsMatrix(:, currentIdx:currentIdx+N_vertices-1) = PR_right;
currentIdx = currentIdx + N_vertices;
end
allPointsMatrix=allPointsMatrix';
for i=2:N_folds
if i==2
for j=1:2*N_vertices
allPointsMatrix((i-1)*3*N_vertices,:)=[];
end
else
for j=1:2*N_vertices
allPointsMatrix((i+1)*N_vertices,:)=[];
end
end
end
a1=allPointsMatrix(:,1);
a2=allPointsMatrix(:,2);
allPointsMatrix1=allPointsMatrix(:,1:2);