Rotating a rectangle based on the direction vector - matlab

I am constructing a rectangle based on a point with a parameter of length and width. and I want am trying to rotate this rectangle based on the calculated direction vector
[d1 d2] = [(x_old - X_cur) (Y_old - YCur)]
Code:
% Point coordinates current positon (small dark circle)
P = [2; 2];
% Direction vector
d = [1 1];
% Dimensions of rectangle
l = 20;
w = 10;
% %direction angle:
A = (atan2(d(1), d(2)));
% Original corner points of rectangle (straight rectangle)
x1 = P(1) -w/2;
y1 = P(2)+l;
x2 = P(1)+ w/2;
y2 = P(2)+l;
x3 = P(1)+ w/2;
y3 = P(2);
x4 = P(1) -w/2;
y4 = P(2);
rect = [x1 x2 x3 x4; y1 y2 y3 y4];
%rotated rectangles coordinates:
x1_new = P(1)+ ((x1 - P(1))* cos(A)) - (y1 - P(2))*sin(A);
y1_new = P(2) +(x1-P(1))*sin(A) + (y1-P(2))*cos(A);
x2_new = P(1)+ (x2 - P(1))* cos(A) - (y2 - P(2))*sin(A);
y2_new = P(2) +(x2-P(1))*sin(A) + (y2-P(2))*cos(A);
x3_new = P(1)+ (x3 - P(1))* cos(A) - (y3 - P(2))*sin(A);
y3_new = P(2) +(x3-P(1))*sin(A) + (y3-P(2))*cos(A);
x4_new = P(1)+ (x4 - P(1))* cos(A) - (y4 - P(2))*sin(A);
y4_new = P(2) +(x4-P(1))*sin(A) + (y4-P(2))*cos(A);
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', 41);
hold on;
plot([P(1) P(1)+d(1)*10], [P(2) P(2)+d(2)*10], 'b'); %plot the direction
patch(new_rect(1,:),new_rect(2,:), 'b', 'FaceAlpha', 0.2); %plot rotated rectangle
patch(rect(1,:),rect(2,:),'b') %plot straight rectangle
hold off
I know there is some mistake in rotating the rectangle because its rotating on the other side. I tried all the possible combinations while creating the new coordinates.
any suggestions on where I am going wrong would be helpful

You can use a rotation matrix. The rotation will be applied to each coordinate at once:
% Rectangle coordinate
% x y
R = [2, 3
5, 3
5, 8
2, 8]
%Anonymous function that will create the rotation matrix (input in radian)
romat = #(a)[cos(a), -sin(a); sin(a), cos(a)];
%Rotation of the Rectangle, with A = atan2(d(1), d(2));
Rrot = ((R-mean(R))*romat(A))+mean(R)
During the operation we have to substract the center of mass of the rectangle so the rotation will occur around the [0,0] point.
Results:
hold on
%Rectangle
patch(R(:,1),R(:,2),'green')
%Rotated rectangle
patch(Rrot(:,1),Rrot(:,2),'red','facealpha',0.5)
%Euclidian vector
quiver(mean(R(:,1)),mean(R(:,2)),d(1),d(2),...
'ro','MarkerFaceColor','red','linewidth',3)
axis equal
What's wrong with your code:
You apply the following rotation matrix:
M = [cos(a) sin(a)
-sin(a) cos(a)]
instead of
M = [cos(a) -sin(a)
sin(a) cos(a)]

Related

how to plot a sphere on top of Gaussian 3D?

I want to create a shape that is a sphere on top of the 3D Gaussian.
something like this:
for plotting Gaussian I wrote tihs:
% isotropic Gaussian parameters
n = 100; % resolution
s = 2; % width
x = linspace(-5,5,n);
[X,Y] = meshgrid(x);
gaus2d = exp( -(X.^2 + Y.^2 )/(2*s^2));
figure(1), clf
surf(x,x,gaus2d)
and for sphere:
rotate3d on
hold on
[x1,y1,z1] = sphere;
% adjusting the radius of sphere
x1 = x1*s;
y1 = y1*s;
z1 = z1*s;
surf(x1,y1,z1)
The problem is: I don't know how to shift the sphere on top of the Gaussian. How to transfer sphere on top of the Gaussain?
You can add a constant to the sphere's z-values in ordner to 'lift' it up:
% isotropic Gaussian parameters
n = 100; % resolution
s = 2; % width
x = linspace(-5,5,n);
[X,Y] = meshgrid(x);
gaus2d = exp( -(X.^2 + Y.^2 )/(2*s^2));
figure(1), clf
surf(x,x,gaus2d)
rotate3d on
hold on
[x1,y1,z1] = sphere;
% adjusting the radius of sphere
x1 = x1*s;
y1 = y1*s;
z1 = z1;
% add a constant to sphere, so that it is on top of gauss
addi = max(gaus2d(:)) - min(z1(:));
z1 = z1 + addi;
surf(x1,y1,z1)

Find the third set of coordaintes (x3 y3) of right angle triangle - Matlab

How can I find the third set of coordinates (X3 Y3) of right angle triangle based on the distances between all coordinates and the other two set of coordinates (X1 Y1; X2 Y2)
Code:
clc;
clear all;
close all;
axis on;
%Example of initial parameters
X1 = 0
Y1 = 2
X2 = 6
Y2 = 7
DX2Y2X3Y3 = 10
%Draw line
line([X1, X2], [Y1, Y2])
text(X1,Y1-0.05,strcat(string(X1),",",string(Y1)))
text(X2,Y2-0.05,strcat(string(X2),",",string(Y2)))
%Calculations
DX1Y1X2Y2 = sqrt((X2-X1)^2+(Y2-Y1)^2) %distance x1,y1 x2,y2
DX1Y1X3Y3 = sqrt(DX2Y2X3Y3+DX1Y1X2Y2)%distance x1,y1 x3,y3 based on Pythagoras
So assuming you have
P1 = [X1 Y1]
P2 = [X2 Y2]
Assertion that the angle at P2 is 90
Length DX2Y2X3Y3
Then we can do the following:
vP1P2 = [X2; Y2] - [X1; Y1]; % Direction vector
vP2P3 = [1; -1] .* flipud(vP1P2); % Negative inverse for rightangle
vP2P3 = vP2P3 ./ sqrt(vP2P3(1)^2 + vP2P3(2)^2); % Scale to unit length
P3 = [X2; Y2] - DX2Y2X3Y3 .* vP2P3; % Calc P3 from P2 + vP2P3
X3 = P3(1); Y3 = P3(2); % Break down into coordinates
line([X2, X3], [Y2, Y3])
line([X1, X3], [Y1, Y3])
axis equal % to make the plot clearer
Note that there are two valid solutions to this problem, reflected in the line from P1 to P2. The choice of direction (+ve / -ve) for vP2P3 will dictate which solution you get.
This code gives the following output:

normal to plane & closest point on a plane to the origin - matlab

I am trying to find a point on the plane that is closest to the origin. When I plot the normal, somehow it is not perpendicular to the plane! Also, the point on the plane closest to origin does not appear correct from the plot. I cannot figure out what is wrong. Any ideas?
c = 2;
x1 = [1, 0, 0] * c;
x2 = [0, 1, 0] * c;
x3 = [0, 0, 1] * c;
x = [x1(1), x2(1), x3(1)];
y = [x1(2), x2(2), x3(2)];
z = [x1(3), x2(3), x3(3)];
figure(1); plot3(x,y,z,'*r'); hold on; grid on;
normal = cross(x1-x2, x1-x3);
% Find all coefficients of plane equation
D = -dot(normal, x1);
range = [-10 10]; [X, Z] = meshgrid(range, range);
Y = (-normal(1) * X - normal(3) * Z - D)/ normal(2);
order = [1 2 4 3]; patch(X(order),Y(order),Z(order),'b');
alpha(0.3);
plot3([x(1), x(3)], [y(1), y(3)], [z(1), z(3)]);
plot3([x(1), x(2)], [y(1), y(2)], [z(1), z(2)]);
x1=x1-x3;
plot3([normal(1), x1(1)], [normal(2), x1(2)], [normal(3), x1(3)], 'k');
%% Get the point on the plane closest point to (0,0,0)
p = normal * (-D / sum(normal.^2,2));
plot3(p(1), p(2), p(3), '*g');
I appreciate your help.
normalize your normal:
normal = normal /norm(normal);
and plot the normal correctly:
plot3([x1(1)+normal(1), x1(1)], [x1(2)+normal(2), x1(2)], [x1(3)+normal(3), x1(3)], 'k');
and for a proper visualization, the axis should be of equal scale:
axis equal
Does not look bad, does it?

mesh gaussian after rotation matrix in matlab

I am trying to rotate the derivative of a gaussian (or the original guassian for that matter) by applying a rotation matrix to the X,Y coordinates and then plotting it as a mesh in matlab, but I'm running into an issue that the plot will only rotate by 90 degress each time and for all n*pi points there is no mesh appearing at all. I am wondering what I am doing wrong, hopefully someone can spot my error. I'm fairly new to matlab so forgive me if the code is not pretty. Thank you!
This is the code that I have:
sigma = 4;
[x,y] = deal(-3*sigma:.5:3*sigma);
[X,Y] = meshgrid(x,y);
B = [transpose(x) transpose(y)];
for i=1:1:16
figure(i);
theta = i*pi/8;
rotation = [cos(theta) sin(theta); -sin(theta) cos(theta)];
A = B * rotation;
[x_new, y_new] = meshgrid(A(:,1)', A(:,2)');
mesh(x_new, y_new, dgauss_x(x_new, y_new, sigma));
end
function f = dgauss_x(x, y, sigma)
%first order derivative of Gaussian
f = -x .* gaussian(x, y, sigma) ./ sigma^2;
function f = gaussian(x, y, sigma)
f = exp(-(x .^ 2 + y .^ 2)/(2*sigma^2)) / (sqrt(2*pi*(sigma^2)));
I figure it out. It was a dumb error. Basically I had to create a meshgrid for X and Y, reshape it into an Nx2 matrix of X and Y. Apply the rotation matrix, then reshape back and apply the Gaussian.
The code looks as follows (could be cleaned up):
for i=1:1:16
figure(i);
theta = i*pi/8;
rotation = [cos(theta) -sin(theta); sin(theta) cos(theta)];
X1 = reshape(X, length(x)*length(x), 1);
Y1 = reshape(Y, length(y)*length(y), 1);
B2 = [X1 Y1];
A = B2 * rotation;
X1 = A(:,1);
X1 = reshape(X1, length(x), length(x));
Y1 = A(:,2);
Y1 = reshape(Y1, length(y), length(y));
mesh(X1, Y1, dgauss_x(X1, Y1, sigma));
end

MATLAB Rotate and move 2d object in the same time

I made star using this code:
t = 0:4/5*pi:4*pi;
x = sin(t);
y = cos(t);
star = plot(x, y);
axis([-1 11 -1 11])
Now I need to rotate and move this star at the same time. I tried this:
for i=1:0.1:10;
zAxis = [0 0 1];
center = [0 0 0];
rotate(star, zAxis, 5, center);
x = x+0.1;
y = y+0.1;
set(star, 'x', x, 'y', y);
pause(0.1);
end
But this code only moves star and doesn't rotate it. If I delete "set" command then it rotates. How can I combine those two actions?
This can do the job..
t = 0:4/5*pi:4*pi;
x = sin(t);
y = cos(t) ;
y = y-mean(y);
x = x-mean(x); % # barycentric coordinates
% # rotation and translation
trasl = #(dx,dy) [dy; dx]; % # this vector will be rigidly added to each point of the system
rot = #(theta) [cos(theta) -sin(theta); sin(theta) cos(theta)]; % # this will provide rotation of angle theta
for i = 1:50
% # application of the roto-translation
% # a diagonal translation of x = i*.1 , y = i*.1 is added to the star
% # once a rotation of angle i*pi/50 is performed
x_t = bsxfun(#plus,rot(i*pi/50)*([x;y]), trasl(i*.1,i*.1) );
star = plot(x_t(1,:), x_t(2,:));
axis([-1 11 -1 11])
pause(.1)
end
In principle, homogeneous coordinates (in this case in the 2D projective space) allow one to do the same job in a neater way; in fact, they would allow one to use just one linear operator (3x3 matrix).
Homogeneous coordinates version:
Op = #(theta,dx,dy) [ rot(theta) , trasl(dx,dy) ; 0 0 1];
for i = 1:50
x_t = Op(i*pi/50,i*.1,i*.1)*[x;y;ones(size(x))];
star = plot(x_t(1,:), x_t(2,:));
axis([-1 11 -1 11])
pause(.1)
end
You can just use a rotation matrix to compute the correct transformation on the vectors [x; y]:
theta = 5 * (pi / 180); % 5 deg in radians
Arot = [cos(theta) -sin(theta); sin(theta) cos(theta)];
xyRot = Arot * [x; y]; % rotates the points by theta
xyTrans = xyRot + 0.1; % translates all points by 0.1
set(star, 'x', xyTrans(1, :), 'y', xyTrans(2, :));