두 선분 사이의 각도는 내적의 arc cos을 통해서 쉽게 구할 수 있다.
하지만 문제는 어느 방향으로 회전했는가이다. 즉 acos의 range는 0~180이기 때문에 360도를 모두 표현하기 힘들다. 그래서 이를 처리하는 매트랩 함수를 만들어 봤다.
수행 동영상
테스트 코드
%% getDegBtwLines 를 테스트
clc;
clear all
close all;
%%
saveVideo = 1;
if saveVideo
vidObj = VideoWriter('vids/getDegBtwLines.avi');
vidObj.FrameRate = 10;
open( vidObj );
end
%%
org = [10 -10];
nr_data = 40;
rads = degspace(0, 360, nr_data)*pi/180;
pntA_list = repmat([20 10], nr_data, 1);
pntB_list = repmat(org, nr_data, 1) + [10*cos(rads) 10*sin(rads) ];
fig = figure(1);
for i = 1:nr_data
pntA = pntA_list(i, :);
pntB = pntB_list(i, :);
deg_diff = getDegBtwLines(org, pntA, pntB);
clf;
hold on;
plot(org(1), org(2), 'ro', 'MarkerFaceColor', 'r');
text(org(1), org(2), ' O');
plot(pntA(1), pntA(2), 'go', 'MarkerFaceColor', 'g');
text(pntA(1), pntA(2), ' A');
plot([org(1) pntA(1)], [org(2) pntA(2)], 'g');
plot(pntB(1), pntB(2), 'bo', 'MarkerFaceColor', 'b');
text(pntB(1), pntB(2), ' B');
plot([org(1) pntB(1)], [org(2) pntB(2)], 'b');
hold off; axis([-15 40 -30 25]); % axis equal;
grid on;
title(sprintf('OA를 기준으로 OB의 각도: %.1f deg', deg_diff) ...
, 'FontSize', 12);
drawnow;
if saveVideo
writeVideo( vidObj, getframe(gcf) );
end
pause(.1);
end
if saveVideo
close( vidObj );
end
getDegBtwLines 함수
function deg_diff = getDegBtwLines(org, pntA, pntB)
%
% org를 기준으로 하는 pntA와 pntB를 잇는 두 선 사이의 각도를 구한다.
%
% 원점 기준으로 변경한다.
pntA = pntA - org;
pntB = pntB - org;
% 길이를 1로 normalize한다.
pntA = pntA / norm(pntA);
pntB = pntB / norm(pntB);
% 방향을 확인하기 위한 변수 (A를 90도 회전)
pntC = [-pntA(2) pntA(1)];
flag = sign(pntB(1)*pntC(1) + pntB(2)*pntC(2));
% 각도를 구한다.
deg_diff = flag*acos(pntA(1)*pntB(1) + pntA(2)*pntB(2))*180/pi;
'Enginius > Matlab' 카테고리의 다른 글
Square Matrix를 여러개의 Sub Matrix로 나누기 (0) | 2014.03.21 |
---|---|
Double indexing (두 개의 for loop을 하나로 줄이기) (0) | 2014.03.19 |
[cprintf] colored print in console (0) | 2014.02.20 |
libsvm 을 사용하자 (0) | 2014.02.05 |
figure에서 동영상 저장하기 (2) | 2014.01.14 |