2つの回転体(非接触​歯車)の最小位置を表​示させたい。

조회 수: 1 (최근 30일)
Norihisa Shimamura
Norihisa Shimamura 2020년 2월 5일
댓글: Norihisa Shimamura 2020년 2월 5일
ここでは接触しない一対の歯車を例にとります。
お互いが回転しているときに、その最短距離となる場所が表示されるようにしたいです。
gear2.PNG

채택된 답변

michio
michio 2020년 2월 5일
편집: michio 2020년 2월 5일
dsearchn 関数を使いました。データ点が多くなると処理速度面が心配ですが、数百点程度であれば特に気になりませんでした。データも添付しましたので下記のコードで確認してみてください。
% サンプルデータ(注:手書きの歯車, x,y 座標、32x2)
load Data001.mat
data = [Data001;Data001(1,:)];
% polyshape 作成(少しずらして 2 つ作成)
gear1 = polyshape(data);
gear2 = translate(gear1,0.7,0);
% 回転させるために重心取得
[refx1,refy1] = centroid(gear1);
[refx2,refy2] = centroid(gear2);
% 30度回転(かみ合うように)
gear1 = rotate(gear1,30,[refx1,refy1]);
% プロット
plot([gear1, gear2]);
% 境界(外枠の座標取得)
[x1,y1] = boundary(gear1);
[x2,y2] = boundary(gear2);
% 座標点の内挿
d1 = cumsum([0;sqrt(diff(x1).^2 + diff(y1).^2)]);
d2 = cumsum([0;sqrt(diff(x2).^2 + diff(y2).^2)]);
data1 = interp1(d1,[x1,y1],linspace(0,max(d1),100));
data2 = interp1(d2,[x2,y2],linspace(0,max(d2),100));
% ここまではデータ準備(もともと密なデータがあればここからスタート可)
% data2 (gear2)の全座標点から最も近い data1 (gear1) の座標点を検索
[k,d] = dsearchn(data1,data2);
% k が最も近いデータのインデックス in data1、 d が距離
% 距離が近い順に並べ替え
[~,idx] = sort(d,'ascend');
idx2 = idx(1); % もっとも近いとされた点のインデックス in data2
idx1 = k(idx(1)); % もっとも近いとされた点のインデックス in data1
% もっとも近い点同士を線で結合
point1 = data1(idx1,:);
point2 = data2(idx2,:);
% gear1 上の点
line(point1(1),point1(2),'Marker','o','MarkerFaceColor','b');
% gear2 上の点
line(point2(1),point2(2),'Marker','o','MarkerFaceColor','r');
% 上の 2 つをつなぐ線
line([point1(1),point2(1)],[point1(2),point2(2)],'LineWidth',2);

추가 답변 (1개)

michio
michio 2020년 2월 5일
GIFを作るコードも付けておきます。水平に回転していないように見えるのが気になりますが・・。
output.gif
% サンプルデータ(注:手書きの歯車, x,y 座標、32x2)
load Data001.mat
data = [Data001;Data001(1,:)];
% polyshape 作成(少しずらして 2 つ作成)
gear1 = polyshape(data);
gear2 = translate(gear1,0.7,0);
% 回転させるために重心取得
[refx1,refy1] = centroid(gear1);
[refx2,refy2] = centroid(gear2);
% 30度回転(かみ合うように)
gear1 = rotate(gear1,30,[refx1,refy1]);
filename = 'output.gif';
for ii=1:50
% ちょっとづつ回転させて動画にします。
gear1 = rotate(gear1,ii/10,[refx1,refy1]);
gear2 = rotate(gear2,-ii/10,[refx2,refy2]);
if ii==1
hpoly = plot([gear1, gear2]);
% 座標軸の設定等
set(gca,'XLim',[0,1.8]);
set(gca,'YLim',[0,1]);
axis equal
set(gca,'XColor','white');
set(gca,'YColor','white');
set(gcf,'Color','white');
else
hpoly(1).Shape = gear1;
hpoly(2).Shape = gear2;
end
% 境界(外枠の座標取得)
[x1,y1] = boundary(gear1);
[x2,y2] = boundary(gear2);
% 座標点の内挿
d1 = cumsum([0;sqrt(diff(x1).^2 + diff(y1).^2)]);
d2 = cumsum([0;sqrt(diff(x2).^2 + diff(y2).^2)]);
data1 = interp1(d1,[x1,y1],linspace(0,max(d1),100));
data2 = interp1(d2,[x2,y2],linspace(0,max(d2),100));
% ここまではデータ準備(もともと密なデータがあればここからスタート可)
% data2 (gear2)の全座標点から最も近い data1 (gear1) の座標点を検索
[k,d] = dsearchn(data1,data2);
% k が最も近いデータのインデックス in data1、 d が距離
% 距離が近い順に並べ替え
[~,idx] = sort(d,'ascend');
idx2 = idx(1); % もっとも近いとされた点のインデックス in data2
idx1 = k(idx(1)); % もっとも近いとされた点のインデックス in data1
% もっとも近い点同士を線で結合
point1 = data1(idx1,:);
point2 = data2(idx2,:);
if ii==1
% gear1 上の点
h_p1 = line(point1(1),point1(2),'Marker','o','MarkerFaceColor','b');
% gear2 上の点
h_p2 = line(point2(1),point2(2),'Marker','o','MarkerFaceColor','r');
% 上の 2 つをつなぐ線
h_line12 = line([point1(1),point2(1)],[point1(2),point2(2)],'LineWidth',2);
else
h_p1.XData = point1(1);
h_p1.YData = point1(2);
h_p2.XData = point2(1);
h_p2.YData = point2(2);
h_line12.XData = [point1(1),point2(1)];
h_line12.YData = [point1(2),point2(2)];
end
frame = getframe(gcf); %#ok<UNRCH> % Figure 画面をムービーフレーム(構造体)としてキャプチャ
tmp = frame2im(frame); % 画像に変更
[A,map] = rgb2ind(tmp,256); % RGB -> インデックス画像に
if ii == 1 % 新規 gif ファイル作成
imwrite(A,map,filename,'gif','LoopCount',Inf,'DelayTime',0.1);
else % 以降、画像をアペンド
imwrite(A,map,filename,'gif','WriteMode','append','DelayTime',0.1);
end
pause(0.2)
end
  댓글 수: 1
Norihisa Shimamura
Norihisa Shimamura 2020년 2월 5일
ありがとうございます!
とても参考になりました。

댓글을 달려면 로그인하십시오.

태그

제품


릴리스

R2019a

Community Treasure Hunt

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

Start Hunting!