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

ここでは接触しない一対の歯車を例にとります。
お互いが回転しているときに、その最短距離となる場所が表示されるようにしたいです。
gear2.PNG

 采纳的回答

michio
michio 2020-2-5
编辑:michio 2020-2-5

1 个投票

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

0 个投票

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 个评论

ありがとうございます!
とても参考になりました。

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 基本的な多角形 的更多信息

产品

版本

R2019a

标签

Community Treasure Hunt

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

Start Hunting!