<think>我们将整合之前的两部分代码:生成匹配点集和拟合直线。
完整流程:
1. 用户输入终点纵坐标Ye,第一组横坐标X1,第二组横坐标X2。
2. 根据起点(xs,ys)和终点(xe,Ye)生成线段,并计算第一组点P1(在原始线段上)。
3. 使用相同的纵坐标(来自P1)和第二组横坐标X2生成点集P2。
4. 对P2点集进行直线拟合,得到拟合直线的斜率和截距,并绘制拟合结果。
我们将创建一个主函数,该函数调用之前的两部分功能,并展示完整流程。</think>### 完整算法:从线段生成到直线拟合
#### 算法流程概述
1. **输入阶段**:获取用户输入的线段参数和点集坐标
2. **点集生成**:基于线段参数计算原始点集P1
3. **匹配点生成**:基于P1纵坐标生成新点集P2
4. **直线拟合**:使用最小二乘法对P2点集进行直线拟合
5. **结果输出**:可视化结果并输出拟合参数
```matlab
function [P1, P2, slope, intercept, R2] = fullLineFittingPipeline()
% 阶段1:用户输入与点集生成
% 固定起点
xs = 0.69762; % 起点横坐标
ys = 0; % 起点纵坐标
xe = 8.607; % 终点横坐标
% 获取终点纵坐标
ye = input('请输入终点纵坐标 Ye: ');
if ~isscalar(ye) || ~isnumeric(ye)
error('终点纵坐标必须是标量数值');
end
% 获取第一组横坐标
X1 = input('请输入第一组横坐标数组 (如 [1, 3, 5]): ');
if ~isvector(X1) || any(X1 < xs) || any(X1 > xe)
error('X1 必须是向量且值在起点和终点横坐标之间');
end
n = numel(X1);
% 计算斜率
slope_original = (ye - ys) / (xe - xs);
% 生成原始点集 P1
Y1 = ys + slope_original * (X1 - xs);
P1 = [X1(:), Y1(:)]; % 确保列向量格式
% 获取第二组横坐标
prompt = sprintf('请输入第二组横坐标 (需包含 %d 个点): ', n);
X2 = input(prompt);
if numel(X2) ~= n
error('第二组横坐标点数必须与第一组相同!');
end
if any(X2 < xs) || any(X2 > xe)
warning('部分X2值超出线段范围,结果可能不准确');
end
% 生成匹配点集 P2 (保持原始纵坐标)
P2 = [X2(:), Y1(:)];
% 阶段2:直线拟合
X = P2(:, 1);
Y = P2(:, 2);
% 最小二乘法计算
X_mean = mean(X);
Y_mean = mean(Y);
numerator = sum((X - X_mean) .* (Y - Y_mean));
denominator = sum((X - X_mean).^2);
if abs(denominator) < eps
slope = 0;
intercept = Y_mean;
else
slope = numerator / denominator;
intercept = Y_mean - slope * X_mean;
end
% 计算拟合值和R²
Y_fit = slope * X + intercept;
SS_res = sum((Y - Y_fit).^2);
SS_tot = sum((Y - Y_mean).^2);
R2 = 1 - (SS_res / SS_tot);
% 阶段3:综合可视化
figure('Name', '完整线段生成与拟合流程', 'Position', [100, 100, 1200, 800]);
% 子图1:原始线段与点集
subplot(2, 2, [1, 3]);
% 绘制原始线段
x_ref = linspace(xs, xe, 100);
y_ref = ys + slope_original * (x_ref - xs);
plot(x_ref, y_ref, 'k-', 'LineWidth', 1.5, 'DisplayName', '原始线段');
hold on;
% 绘制原始点集P1
plot(P1(:,1), P1(:,2), 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r', ...
'DisplayName', '原始点集P1');
% 绘制新点集P2
plot(P2(:,1), P2(:,2), 'bs', 'MarkerSize', 10, 'MarkerFaceColor', 'b', ...
'DisplayName', '新点集P2');
% 标记端点
plot(xs, ys, 'gp', 'MarkerSize', 15, 'MarkerFaceColor', 'g', ...
'DisplayName', '起点');
plot(xe, ye, 'mp', 'MarkerSize', 15, 'MarkerFaceColor', 'm', ...
'DisplayName', '终点');
% 添加标签
text(P1(:,1), P1(:,2), cellstr(num2str((1:n)')), ...
'VerticalAlignment', 'bottom', 'FontSize', 10);
text(P2(:,1), P2(:,2), cellstr(num2str((1:n)')), ...
'VerticalAlignment', 'top', 'FontSize', 10);
title('原始线段与点集生成');
xlabel('X坐标'); ylabel('Y坐标');
legend('Location', 'best');
grid on;
axis equal tight;
% 子图2:点集拟合结果
subplot(2, 2, 2);
% 绘制P2点集
scatter(X, Y, 100, 'b', 'filled', 'DisplayName', 'P2点集');
hold on;
% 绘制拟合直线
x_fit = linspace(min(X), max(X), 100);
y_fit = slope * x_fit + intercept;
plot(x_fit, y_fit, 'r-', 'LineWidth', 2, ...
'DisplayName', sprintf('拟合直线: y = %.4fx + %.4f', slope, intercept));
% 绘制残差
for i = 1:n
plot([X(i), X(i)], [Y(i), slope*X(i)+intercept], 'k:', 'HandleVisibility', 'off');
end
title(sprintf('P2点集直线拟合 (R² = %.4f)', R2));
xlabel('X坐标'); ylabel('Y坐标');
legend('Location', 'best');
grid on;
axis tight;
% 子图3:拟合参数展示
subplot(2, 2, 4);
axis off;
% 创建信息文本
infoText = {
'==== 原始线段参数 ===='
sprintf('起点: (%.5f, %.1f)', xs, ys)
sprintf('终点: (%.3f, %.3f)', xe, ye)
sprintf('斜率: %.6f', slope_original)
''
'==== 点集信息 ===='
sprintf('P1点数: %d', n)
sprintf('P2点数: %d', n)
''
'==== 拟合结果 ===='
sprintf('拟合斜率: %.6f', slope)
sprintf('拟合截距: %.6f', intercept)
sprintf('决定系数 R²: %.6f', R2)
sprintf('拟合方程: y = %.4fx + %.4f', slope, intercept)
};
% 显示文本
text(0.1, 0.5, infoText, 'FontSize', 12, 'VerticalAlignment', 'middle');
% 阶段4:结果输出
fprintf('\n==== 完整流程结果 ====\n');
fprintf('原始线段: 起点(%.5f, %.1f) -> 终点(%.3f, %.3f)\n', xs, ys, xe, ye);
fprintf('原始斜率: %.6f\n', slope_original);
fprintf('P1点集: %d个点\n', n);
fprintf('P2点集: %d个点\n', n);
fprintf('拟合斜率: %.6f\n', slope);
fprintf('拟合截距: %.6f\n', intercept);
fprintf('决定系数 R²: %.6f\n', R2);
end
```
#### 算法详解
1. **输入与点集生成阶段**
- 固定起点`(0.69762, 0)`和终点横坐标`8.607`
- 用户输入终点纵坐标`Ye`
- 计算原始线段斜率:`(Ye - 0)/(8.607 - 0.69762)`
- 根据用户输入的`X1`生成原始点集`P1`
- 根据用户输入的`X2`生成匹配点集`P2`(复用`P1`的纵坐标)
2. **直线拟合阶段**
- 使用最小二乘法拟合`P2`点集
- 计算斜率:`Σ((x_i - x̄)(y_i - ȳ))/Σ((x_i - x̄)²)`
- 计算截距:`ȳ - slope * x̄`
- 计算决定系数R²:`1 - (残差平方和/总平方和)`
3. **可视化阶段**
- **左上子图**:原始线段、P1点集和P2点集
- 连续原始线段
- P1点集(红色)和P2点集(蓝色)带索引标签
- 起点(绿色)和终点(紫色)标记
- **右上子图**:P2点集拟合结果
- 拟合直线(红色)
- 残差线(黑色虚线)
- R²值显示
- **右下子图**:参数汇总
- 原始线段参数
- 点集信息
- 拟合结果参数
4. **输出阶段**
- 命令行输出完整参数
- 返回生成点集和拟合参数
- 综合可视化展示全流程
#### 算法特点
1. **端到端流程**
- 从用户输入到最终拟合结果的全流程解决方案
- 自动处理中间计算和数据传递
2. **健壮性设计**
- 全面的输入验证
- 除零错误处理
- 超出范围警告
3. **信息可视化**
- 多子图展示不同阶段结果
- 点集索引标签
- 参数汇总面板
- 残差可视化
4. **结果分析**
- 原始线段斜率与拟合斜率对比
- R²值评估拟合质量
- 命令行详细输出
#### 使用示例
```matlab
% 执行完整流程
[P1, P2, slope_fit, intercept_fit, R2] = fullLineFittingPipeline();
% 示例输入:
% Ye = 1.5
% X1 = [1, 3, 5, 7]
% X2 = [0.5, 2, 4.5, 8]
% 使用拟合结果进行预测
newX = 3.5;
predictedY = slope_fit * newX + intercept_fit;
fprintf('在X=%.1f处的预测值: %.4f\n', newX, predictedY);
```