- 零:平面上の点 ⇒ 0
- 正:2つの空間のどちらか ⇒ +1
- 負:2つの空間のどちらか ⇒ -1
1つの平面で2つに分けられた3次元空間で各点が2つの空間のどちらに属しているかを知りたい。
6 views (last 30 days)
Show older comments
3次元空間上に複数の点があるとします。
1つの平面によって3次元空間を2つに分けた場合、
各点が2つの空間のどちらに属しているかを知りたいです。
平面をa(x-p)+b(y-q)+c(z-r)=0とします。
この場合、平面上の点はP(x,y,z)です。
インデックスで0か1で分かればいいです。
どのように求めればよいのでしょうか教えてください。
分かりづらいところは質問してください。
お答えします。
宜しくお願いします。
0 Comments
Accepted Answer
Atsushi Ueno
on 30 Aug 2023
function result = judgement(x,y,z)
p = 1; q = 2; r = 3;
a = 5; b = 5; c = 5;
result = sign(a*(x-p)+b*(y-q)+c*(z-r));
end
注意点:浮動小数点数を入力した場合、結果が0(ちょうど平面上)になる事は滅多にありません。代数的に0になるはずでも演算誤差によって正負どちらかに外れる事が起こり得ます。かといって「絶対に0にならない」とも言い切れないので厄介です。代数的に厳密な結果を方法としては symbolic math toolboxを使用する方法があります。
More Answers (1)
交感神経優位なあかべぇ
on 30 Aug 2023
Edited: 交感神経優位なあかべぇ
on 30 Aug 2023
平面を境に空間の点を2分割するコードを書きました。
体力があるときにもうちょっと詳細を解説するかも……
point_cloud = (rand(100,3) - 0.5) .* 100;% 3次元空間上の複数の点 (:,1), (:,2), (:,3)はそれぞれX,Y,Zの値
plane = (rand(2,3) - 0.5) .* 50; % 平面の式 (配列の各要素は[a,b,c;p,q,r]を示す)
is_normal_side = divice_by_plane(point_cloud,plane); % 空間上の各点を平面を境とした分割を判定する。
% 以下データの可視化
conner = get_plane_conner(plane, 75);% 平面の式から、plane_sizeで示す大きさの四角形の4つの頂点座標を取得する。
cData = repmat([0,1,0],size(point_cloud,1),1);
cData(is_normal_side,:) = repmat([1,0,0],nnz(is_normal_side),1);
scatter3(point_cloud(:,1),point_cloud(:,2),point_cloud(:,3),'Marker','.','CData',cData);
hold on;
patch(conner(:,1),conner(:,2),conner(:,3),[0,0,0.3],'FaceAlpha',0.4);
% 空間上の各点を平面を境とした分割を判定する。
function is_normal_side = divice_by_plane(point_cloud,plane)
arguments(Input)
point_cloud(:,3)% 3次元空間上の複数の点 (:,1), (:,2), (:,3)はそれぞれX,Y,Zの値
plane(2,3) % [a,b,c; p,q,r]の配列
end
arguments(Output)
is_normal_side(:,1) logical % 平面を境にした各点の分割判定(1は面の法線方向側)
end
% 体力があるときに以下解説するかも...
point_cloud = point_cloud + plane(2,:);
zRad = atan2(plane(1,2),plane(1,1));
yRad = atan2(-plane(1,3),hypot(plane(1,2),plane(1,1)));
cosZ = cos(-zRad);
sinZ = sin(-zRad);
zmatrix = eye(3,'like',plane);
zmatrix([1,2], [1,2]) = [cosZ,-sinZ;sinZ,cosZ];
cosY = cos(-yRad);
sinY = sin(-yRad);
ymatrix = eye(3,'like',plane);
ymatrix([1,3],[1,3]) = [cosY,sinY;-sinY,cosY];
point_cloud = (ymatrix * zmatrix * (point_cloud)')';
is_normal_side = point_cloud(:,1) > 0;
end
% 平面の式から、plane_sizeで示す大きさの四角形の4つの頂点座標を取得する。
function conner = get_plane_conner(plane, plane_size)
arguments(Input)
plane(2,3) % [a,b,c; p,q,r]の配列
plane_size(1,1) % 平面の大きさ
end
arguments(Output)
conner(4,3) % 四角形の4つの頂点座標
end
zRad = atan2(plane(1,2),plane(1,1));
yRad = atan2(-plane(1,3),hypot(plane(1,2),plane(1,1)));
cosZ = cos(zRad);
sinZ = sin(zRad);
zmatrix = eye(3,'like',plane);
zmatrix([1,2], [1,2]) = [cosZ,-sinZ;sinZ,cosZ];
cosY = cos(yRad);
sinY = sin(yRad);
ymatrix = eye(3,'like',plane);
ymatrix([1,3],[1,3]) = [cosY,sinY;-sinY,cosY];
x = [0,0,0,0];
y = [plane_size,plane_size,-plane_size,-plane_size];
z = [plane_size,-plane_size,-plane_size,plane_size];
conner = (zmatrix * ymatrix * [x;y;z])';
conner = conner - plane(2,:);
end
See Also
Categories
Find more on Import Data in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!