三次元で、ある座標か​らある座標に矢印を引​きたいです。

質問のように、三次元空間で矢印を引きたいと考えています。
座標は一点ではなく、複数ある場合、それぞれの座標の始点と終点を結ぶ直線矢印を引いて、まとめて表したいです。
こちらにあるデータは、始点と終点の座標データのみです。
X, Y, Z軸の範囲も自動で設定できるようなプログラムもあれば◎です。
よろしくお願いします。

Answers (1)

Akira Agata
Akira Agata on 21 May 2018

2 votes

quiver3 関数を使う以下の方法では如何でしょうか。
p0 = [0,0,0; 1,0,0; 0,1,0; 1,1,0]; % 始点の座標
p1 = [0,0,1; 1,0,1; 0,1,1; 1,1,1]; % 終点の座標
v = p1 - p0; % ベクトル
figure
quiver3(p0(:,1),p0(:,2),p0(:,3),v(:,1),v(:,2),v(:,3),0)

11 Comments

Haru Kame
Haru Kame on 21 May 2018
ご回答ありがとうございます。 とても助かります。
基本的な質問で申し訳ないのですが、quiver3のうしろは何を設定しているのでしょうか??
Akira Agata
Akira Agata on 21 May 2018
quiver3 関数の入力引数ですが、1~3番目は矢印の始点の x,y,z 座標を、4~6番目はベクトル(矢印)の x,y,z 成分を、それぞれ示しています。ちなみに、 quiver3 関数で複数のベクトルを描画する場合、ベクトルが重なり合わないように自動的にベクトルがスケーリングされてしまいます。このため上記のサンプルスクリプトでは、自動的なスケーリングをoffにするため、7番目の引数にゼロを設定しています。
quiver3 関数の詳細については、下記のヘルプページをご参照下さい。
Haru Kame
Haru Kame on 23 May 2018
ご回答ありがとうございます。 またご連絡が遅くなり、申し訳ありません。
このベクトルの例では4本のベクトルを引いておりますが、実際のデータは座標が200個近くあり、それらすべての座標に対して矢印を作るためにはどうしたら良いのでしょうか。。。
forを用いた繰り返しを用いるとは思うのですが、どのように書けばいいのか見当がつきません。。
お教えいただけますでしょうか?
Akira Agata
Akira Agata on 23 May 2018
データが200個の場合でも、forループを使わずに同様の方法で表示することができます。例えば 200個の始点のxyz座標と200個のベクトルを、それぞれ 200×3の配列として作成した場合は、下記のようになります。
% p: 始点の(x,y,z)座標×200個, v: 各始点に配置するベクトル
p = rand(200,3)*20;
v = ones(200,3)+rand(200,3);
figure
quiver3(p(:,1),p(:,2),p(:,3),v(:,1),v(:,2),v(:,3),0)
Haru Kame
Haru Kame on 27 May 2018
ご返信が遅くなりました。。 とりあえず下記のようなプログラムで矢印は引くことができました。。
filename = 'test.xlsx';
p0 = xlsread('test.xlsx','Sheet1');
p1 = xlsread('test.xlsx','Sheet2');
v = p1-p0;
figure quiver3(p0(:,1),p0(:,2),p0(:,3),v(:,1),v(:,2),v(:,3),0)
ただ、p = rand(200,3)*20; v = ones(200,3)+rand(200,3);の意味がよくわかりません。
エクセルファイルから読み込むようなことをしているのですが、その際に自動的に200×3の行列として読み込まれているのでしょうか。
座標を何度も貼り付けるのは面倒なので、エクセルからと思ったのですが、問題があれば教えてください。
よろしくお願いいたします。
Akira Agata
Akira Agata on 29 May 2018
ご返信ありがとうございます。
p = rand(200,3)*20 についてですが、これは区間 (0,1) の一様乱数を200行3列の配列したうえで、各要素を20倍して p という変数に保存するという意味です。この1行を実行すると、MATLAB右側のワークスペースに、下記のような表示が出てくると思います。また、v = ones(200,3)+rand(200,3) は、要素がすべて1の200行3列の配列と、区間 (0,1) の一様乱数を要素とする200行3列の配列を足して v という変数に保存しています。
>エクセルファイルから読み込むようなことをしているのですが、その際に自動的に200×3の行列として読み込まれているのでしょうか。
読み込んだ後にワークスペースを見ることで確認できます。Excelファイルを読み込んだ後、下記の図と同様に値が 200x3 double、サイズが200x3、クラスが double の変数が2つ(p0, p1) 生成されていれば問題ありません。
Haru Kame
Haru Kame on 29 May 2018
迅速なご対応、ありがとうございます。 とても助かります。
ワークペース、確認いたしました。doubleの変数が2つ生成されているようです。
さらにこれらのベクトルに色々な修飾をつけていきたいのですが、可能でしょうか。各ベクトルの視点にマーカーを表示させ、そのマーカーを領域ごと (例えばz方向の大→小)に擬似カラーで表したいと考えております。
可能でしょうか。。
Akira Agata
Akira Agata on 29 May 2018
修飾の内容にもよりますが、記載頂いた内容であれば scatter3 関数と組み合わせることで実現できます。例えば以前のサンプルコードに少し手を加えると、以下のようなプロットを生成できます。
% p: 始点の(x,y,z)座標×200個, v: 各始点に配置するベクトル
p = rand(200,3)*20;
v = ones(200,3)+rand(200,3);
markerSize = 30;
figure
quiver3(p(:,1),p(:,2),p(:,3),v(:,1),v(:,2),v(:,3),0)
hold on
scatter3(p(:,1),p(:,2),p(:,3),markerSize,p(:,3),'filled')
colorbar
Haru Kame
Haru Kame on 30 May 2018
ご返信ありがとうございます。 いろいろ表現ができてとても面白いですね。。
矢印で表示させる方はなんとかできそうな気がしています。 ありがとうございました。
各座標のマーカーを添付資料のようにグラーデーションで色をつけることはできたのですが、まだ課題があります。
ある座標が変化していくとします。 一番初めに色をつけた状態のまま、その後の全てのタイムポイントでもその色を維持させられることは可能でしょうか。
添付いたしました2枚の写真は、それぞれの座標に対して色をつけていますが、理想的には上述のようにはじめのタイムポイントの色を維持させたいと考えています。
基本的な情報ですが、座標は各タイムポイント120個くらいあり、タイムポイントは40個くらいあります。
よろしくお願いいたします。
Akira Agata
Akira Agata on 1 Jun 2018
Edited: Akira Agata on 1 Jun 2018
各点のマーカーの色情報を保持しておいて、 scatter3 関数に引数として与えることで実現できます。例えば以下の例では、color という変数に初期状態での色情報 (ここでは初期状態における p の3列目の値) を保持しています。そのうえで、点の位置を更新した後、この変数を scatter3 関数の引数として与えることで、各点の位置が変わっても元の色で表示するようにしています。
% p: 始点の(x,y,z)座標×N個, v: 各始点に配置するベクトル
N = 50;
p = rand(N,3)*20;
p = sortrows(p,3,'descend'); % 3列目でソート
color = p(:,3);
v = ones(N,3)+rand(N,3);
markerSize = 30;
% 初期状態を表示
figure
quiver3(p(:,1),p(:,2),p(:,3),v(:,1),v(:,2),v(:,3),0)
hold on
scatter3(p(:,1),p(:,2),p(:,3),markerSize,color,'filled')
text(p(:,1),p(:,2),p(:,3),num2str((1:N)'))
view(-20,10)
title('Before')
h = colorbar;
h.Label.String = 'Initial value';
% 始点の位置を更新
p = rand(N,3)*20;
% 更新後の状態を表示(ただし各点の色は初期状態を維持)
figure
quiver3(p(:,1),p(:,2),p(:,3),v(:,1),v(:,2),v(:,3),0)
hold on
scatter3(p(:,1),p(:,2),p(:,3),markerSize,color,'filled')
text(p(:,1),p(:,2),p(:,3),num2str((1:N)'))
view(-20,10)
title('After')
h = colorbar;
h.Label.String = 'Initial value';
Haru Kame
Haru Kame on 4 Jun 2018
ご返信ありがとうございます。
現在、全ての座標がはじめの色を維持するような図を考えております。 試行錯誤しておりますので、不明な点がありましたら再度ご質問させて頂きます。
その途中で少し気になったことがありましたので、ご質問させて頂きます。 ベクトルを図示し、オブジェクトを回転させたところ、添付図のように角度によって矢印が見えづらくなっていることに気づきました。 ある角度からは、矢印が棒に見えてしまい、改善したいと考えております。
矢印の太さを変更しても変わりなく、どうやら矢印が扁平の表示であることが原因のようです。
よろしくお願いいたします。

Sign in to comment.

Asked:

on 19 May 2018

Commented:

on 4 Jun 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!