Построение квадрата из точки относительно направления точки - PullRequest
0 голосов
/ 13 мая 2019

Я делаю квадрат вокруг / ниже заданной точки с заданной шириной (w) и длиной (l), как показано ниже

enter image description here

Но теперь я должен определить направление точки (или, так сказать, курс). Я хочу создать прямоугольник, направленный в этом направлении, как показано ниже. Я никогда раньше не работал с заголовками, если кто-нибудь может указать мне правильные направления, это было бы полезно.

enter image description here

----------------- EDIT --------------- Спасибо @MBo & @HansHirse, я реализовал, как предложили ваши люди. для простоты я выбрал точку на верхней линии прямоугольника, а не на удалении от прямоугольника. мой код, как показано ниже:

% Point coordinates
P = [5; 5];

% Direction vector
d = [1; -5];

%normalizing 
Len = sqrt(d(1)*d(1)+d(2)*d(2));
cs = d(1)/Len;
sn = d(2)/Len;

% Dimensions of rectangle
l = 200;
w = 100;

% Original corner points of rectangle

x1 = P(1) -w/2;
y1 = P(2);
x2 = P(1)+ w/2;
y2 = P(2);
x3 = P(1)+ w/2;
y3 = P(2) - l;
x4 = P(1) -w/2;
y4 = P(2) - l;
rect = [x1 x2 x3 x4; y1 y2 y3 y4];

%rotated rectangles coordinates:
x1_new = P(1)+ (x1 - P(1))* cs - (y1 - P(2))*sn;
y1_new = P(2) +(x1-P(1))*sn + (y1-P(2))*cs;
x2_new = P(1)+ (x2 - P(1))* cs - (y2 - P(2))*sn;
y2_new = P(2) +(x2-P(1))*sn + (y2-P(2))*cs;
x3_new = P(1)+ (x3 - P(1))* cs - (y3 - P(2))*sn;
y3_new = P(2) +(x3-P(1))*sn + (y3-P(2))*cs;
x4_new = P(1)+ (x4 - P(1))* cs - (y4 - P(2))*sn;
y4_new = P(2) +(x4-P(1))*sn + (y4-P(2))*cs;
new_rect = [x1_new x2_new x3_new x4_new; y1_new y2_new y3_new y4_new];


%plot:
figure(1);
plot(P(1), P(2), 'k.', 'MarkerSize', 21);  
hold on;
plot([P(1) P(1)+d(1)*10], [P(2) P(2)+d(2)*10], 'b');
patch(new_rect(1,:),new_rect(2,:), 'b', 'FaceAlpha', 0.2);
patch(rect(1,:),rect(2,:),'b')
hold off

То, как он вращается, не то, что я хотел: я не могу загрузить картинку, imgur ведет себя странно. Вы можете запустить точный код, вы получите вывод, который я получаю.

Ответы [ 2 ]

1 голос
/ 13 мая 2019

Общая концепция уже упоминалась в ответ MBo .Тем не менее, так как я работал над некоторым кодом, вот мое решение:

% Point coordinates
P = [5; 5];

% Direction vector
d = [1; -5];

% Dimensions of rectangle
l = 200;
w = 100;

% Distance P <-> rectangle
dist = 20;

% Determine rotation angle from direction vector
% (Omitting handling of corner/extreme cases, e.g. d(2) = 0)
theta = atand(d(1) / d(2));
if ((d(1) > 0) && (d(2) < 0))
  theta = theta + 180;
elseif ((d(1) < 0) && (d(2) < 0))
  theta = theta - 180;
end

% Original corner points of rectangle
xMin = P(1) - w/2;
xMax = P(1) + w/2;
yMin = P(2) - dist;
yMax = P(2) - dist - l;
rect = [xMin xMax xMax xMin; yMin yMin yMax yMax];

% Auxiliary matrix for rotation
center = repmat(P, 1, 4);

% Rotation matrix
R = [cosd(-theta) -sind(-theta); sind(-theta) cosd(-theta)];

% Rotation
rotrect = (R * (rect - center)) + center;

% Plot
figure(1);
hold on;
plot(P(1), P(2), 'k.', 'MarkerSize', 21);             % Point
plot([P(1) P(1)+d(1)*10], [P(2) P(2)+d(2)*10], 'b');  % Direction vector
patch(rect(1, :), rect(2, :), 'b', 'FaceAlpha', 0.2); % Original rectangle
patch(rotrect(1, :), rotrect(2, :), 'b');             % Rotated rectangle
hold off;
xlim([-250 250]);
ylim([-250 250]);

. Это приведет к созданию выходного изображения, подобного этому:

Output

Предостережение: В моей матрице вращения R вы найдете -theta, поскольку способ определения theta - это всего лишь простой подход.Это может быть улучшено, так что R также может быть настроен правильно.

1 голос
/ 13 мая 2019

Итак, у вас есть точка P и прямоугольник R (определяемый координатами).

Теперь вы хотите повернуть прямоугольник на угол A вокруг точки P (насколько я понимаю)
Новые координаты для каждой вершины:

NewV[i].X = P.X + (V[i].X - P.X) * Cos(A) - (V[i].Y - P.Y) * Sin(A)
NewV[i].Y = P.Y + (V[i].X - P.X) * Sin(A) + (V[i].Y - P.Y) * Cos(A)

Если у вас есть вектор направления D = [d1, d2], вам не нужно оперировать триггером.Функции: просто используйте компоненты нормализованного вектора (возможно, Matlab содержит функцию для нормализации):

Len = magnitude(D) = sqrt(d1*d1+d2*d2)
//normalized (unit vector)
dx = d1 / Len
dy = d2 / Len
NewV[i].X = P.X + (V[i].X - P.X) * dx - (V[i].Y - P.Y) * dy
NewV[i].Y = P.Y + (V[i].X - P.X) * dy + (V[i].Y - P.Y) * dx

Также вы можете опустить создание координат выровненного по оси прямоугольника и сразу вычислить вершины (возможно, больше возможностей для ошибок)

//unit vector perpendicula to direction
perpx = - dy
perpy = dx

V[0].X = P.X - dist * dx  + w/2 * perpx
V[1].X = P.X - dist * dx  - w/2 * perpx
V[2].X = P.X - dist * dx  - w/2 * perpx - l * dx
V[3].X = P.X - dist * dx  + w/2 * perpx - l * dx

and similar for y-components
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...