Constructing a square from a point with respect to the direction of the point

坚强是说给别人听的谎言 提交于 2019-12-13 04:08:18

问题


I make a square around/below a given point with given width (w) and length (l) like shown below

But now I have to induce the direction of the point (or heading so to say). I want to create a rectangle directed towards that direction like shown below. I have never worked with headings before, if anyone can point me in the right directions, that would be helpful.

-----------------EDIT--------------- Thank you @MBo & @HansHirse, I implemented as suggested by your people. for simplicity, I chose the point to be on the top line of the rectangle rather to be away from the rectangle. my code is as shown below:

% 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

The way it is rotating is not what I wanted: I am not able to upload a pic, imgur is acting weird. You can run the exact code, you will get the output I am getting.


回答1:


So you have point P, and rectangle R (defined by coordinates).

Now you want to rotate rectangle by angle A around point P (as far as I understand)
New coordinates for every vertex are:

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)

If you have direction vector D = [d1, d2], you don't need to operate with trig. functions: just exploit components of normalized vector (perhaps matlab contains function for normalizing):

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

Also you can omit creating coordinates of axis-aligned rectangle and calculate vertices immediately (perhaps more possibilities for mistakes)

//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



回答2:


The general concept was already mentioned in MBo's answer. Nevertheless, since I was working on some code, here is my solution:

% 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]);

This will produce an output image like this:

Caveat: In my rotation matrix R, you'll find -theta, since the way, how theta was determined is just some simple approach. This might be improved, so that R could also be set up properly.



来源:https://stackoverflow.com/questions/56109467/constructing-a-square-from-a-point-with-respect-to-the-direction-of-the-point

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!