平面(ax+by+cz+d=0)への近似part2
Show older comments
前回は回答者様のおかげで解決することができました。ありがとうございます。
続きですが、質問させていただきます。
ランダムな点(約1000点)から平面(ax+by+cz+d=0)への近似を行うことができました。 しかし、この方法により算出した方程式は図の青緑の面の形とは違うものになってしまいました。
図にあるような面を5000個の点で作成したいのですが、どのようなコードになりますか。 範囲は図のようなx、y、zの範囲でお願いします。
係数の使い方(p00やp10など)を理解できていないのかもしれません。 初心者ですがどなたかアドバイスをよろしくお願い致します。

以下、近似と面作成のコードです
--
%CREATEFIT(PLANE01_X,PLANE01_Y,PLANE01_Z)
% 近似を作成します。
%
% '新規近似 1' に対するデータを近似:
% X 入力: plane01_x
% Y 入力: plane01_y
% Z 出力: plane01_z
% 出力:
% fitresult: 近似を表す fit オブジェクト。
% gof: 適合性情報をもつ構造体。
%
% 参考 FIT, CFIT, SFIT.
% MATLAB からの自動生成日: 16-Dec-2016 15:35:47
%%近似: '新規近似 1'。
[xData, yData, zData] = prepareSurfaceData( plane01_x, plane01_y, plane01_z );
% 近似タイプとオプションを設定します。
ft = fittype( 'poly11' );
% モデルをデータに近似します。
[fitresult, gof] = fit( [xData, yData], zData, ft, 'Normalize', 'on' );
% データの近似をプロットします。
figure( 'Name', '新規近似 1' );
h = plot( fitresult, [xData, yData], zData );
legend( h, '新規近似 1', 'plane01_z vs. plane01_x, plane01_y', 'Location', 'NorthEast' );
% ラベル Axes
xlabel plane01_x
ylabel plane01_y
zlabel plane01_z
grid on
view( 32.1, 12.4 );
%係数の抽出
Coe1_d = fitresult.p00;
Coe1_a = fitresult.p10;
Coe1_b = fitresult.p01;
plane01_x = plane0000001(:,1);
plane01_y = plane0000001(:,2);
plane01_z = plane0000001(:,3);
%推定面の作成
maxX = max(plane0000001(:,1));
maxY = max(plane0000001(:,2));
maxZ = max(plane0000001(:,3));
minX = min(plane0000001(:,1));
minY = min(plane0000001(:,2));
minZ = min(plane0000001(:,3));
a_plane = zeros(5000,3);
for k = 1:5000
randpointX = minX + (maxX - minX)*rand(1,1);
randpointY = minY + (maxY - minY)*rand(1,1);
randpointZ = Coe1_d + Coe1_a*randpointX + Coe1_b*randpointY;
a_plane(k,1) = randpointX;
a_plane(k,2) = randpointY;
a_plane(k,3) = randpointZ;
end
Accepted Answer
More Answers (1)
michio
on 18 Dec 2016
実行結果と fitresult を直接使った場合についての情報、ありがとうございます。
改めてコードを見たところ、近似の際にデータ(x,y) の正規化を行っていることに気が付きました。GUI上ですと「データのセンタリングとスケーリング」チェック、コードですと
% モデルをデータに近似します。
[fitresult, gof] = fit( [xData, yData], zData, ft, 'Normalize', 'on' );
の 'Normalize' = 'on' の部分が該当します。
fitresult
と実行すると(*数値は適当な値です)
ここで、x は平均 0.5236 と標準偏差 0.2943 で正規化されます
ここで、y は平均 0.5232 と標準偏差 0.2881 で正規化されます
などと出力されると思います。
5000点のランダムな x,y から z を計算する際に
randpointZ = fitresult(randpointX, randpointY);
と fitresult を使用する場合は、新しいデータに対しても正規化を実施しますが、係数をそのまま使用して計算する場合(提示頂いたコードで)は別途近似モデルを作成したときと同じ正規化を実施する必要があります。
1 Comment
Ichiro Suzuki
on 20 Dec 2016
Categories
Find more on Measurements and Feature Extraction in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!