You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
Calculate 2D normal vectors to a plane
10 views (last 30 days)
Show older comments
Hey to all, Im having difficulties on trying to get normal vectors to a 2D plane.
I have a AoI=200 x 200 matrix, composed by zeros and ones( I define the position of the ones in the matrix), so, a binary matrix.
I want to get the normal vectors to the blocks where the ones are, imagine I have a target(1 in matrix) in row 2, column 4:7. I want to get this normal to this plane. And if i have more than one target, get all the normals to all the targets.
Thank you in advance.
10 Comments
Jan
on 4 May 2022
How is the plane defined? What are "blocks"? The vectors should be normal to what?
Remember: A normal vector is a vector which norm is 1. It can have any number of dimensions. The normal vector of all points in a (flat) plane are the same (maybe a 2nd normal vector point in the opposite direction).
Miguel Albuquerque
on 5 May 2022
Edited: Jan
on 6 May 2022
Alright im going to clarify it.
Area-
Lp=1; % Pixel length
Nx= zeros(1,200*Lp); % dimension in x, horizontal of surveillance area
Ny= zeros(200*Lp,1); % dimension in y, vertical of surveillance area
AoI=Nx.*Ny; % Surveillance area
Place the blocks= targets(defined by 1 in a binary matrix)
% Horizontal targets
AoI(2,(5:10)) = 1; % define target, set row 4, from column 7-10 to 1, no correlation to Lp
AoI(1,12) = 1;
AoI(5,(5:7)) = 1;
AoI(6,(10:12)) = 1;
normal_ntarget1=[5 0]; % Define a normal vector to the target
I want to calculate the normal vector to this targets, so I can get the angle between them and a transmitter positioned at:
X_transmitter=8*Lp;
Y_transmitter=5*Lp;
Thank you
Jan
on 6 May 2022
@Miguel Albuquerque: This does not clarify the details.
Nx= zeros(1,200*Lp); % dimension in x
Ny= zeros(200*Lp,1); % dimension in y
So you are talking about a hyper-plane with 200x200 dimensions?
AoI(2,(5:10)) = 1; % define target, set row 4, from column 7-10 to 1
This comment is not useful. While it is obvious, that you set the "row 4, from column 7-10 to 1", it is still not clear, what a "target" is.
normal_ntarget1=[5 0]; % Define a normal vector to the target
[5, 0] is not a normal-vector. What "to the target" means is not explained yet.
X_transmitter=8*Lp;
Y_transmitter=5*Lp;
Because Lp is a contant, the code is running already. What do you want to change?
Remember, that the readers in the forum do not have any idea about what you want to achieve. So explain your problem like you would explain it to a rubber duck. (See: https://en.wikipedia.org/wiki/Rubber_duck_debugging )
So let me ask again: How is the plane defined? What are "blocks"? The vectors should be normal to what? What is a "target"?
Miguel Albuquerque
on 6 May 2022
So I want to define a area where a passive radar will work. This area AoI its a square area, defined by 200 elements by 200 elements.
Lp=1; % Pixel length
Nx= zeros(1,200*Lp); % dimension in x, horizontal of surveillance area
Ny= zeros(200*Lp,1); % dimension in y, vertical of surveillance area
AoI=Nx.*Ny; % Surveillance area
In this area i will have zones with targets, for example a car, and zones without targets.
The targets are defined in this matrix by one, and the zones without targets are defined by 0 in the matrix.
AoI(2,(5:10)) = 1; % define target, set row 4, from column 7-10 to 1, no correlation to Lp
AoI(1,12) = 1;
AoI(5,(5:7)) = 1;
AoI(6,(10:12)) = 1;
I will have a transmitter antenna(8,5) and a receiver antenna(8,15).
In order to calculate the incident angle between transmitter-target, I need to define a normal vector to this target, a normal vector to this plane. This plane is a plane considered where the targets are. So in this example, AoI(6,(10:12)) = 1; I consider a plane in row 6, column 10-12. I need to calculate this normals, so that I can get the incident angles between transmitter and normal.
I hope its better clarified now,
Thank you
Matt J
on 6 May 2022
Edited: Matt J
on 6 May 2022
@Miguel Albuquerque You mean lines, not planes. Planes are regions existing in 3D, not 2D.
Jan
on 6 May 2022
Edited: Jan
on 6 May 2022
@Miguel Albuquerque: The physical meaning does not matter, because it does not appear in the Matlab code also.
In other words, you have some 1s in a 200x200 matrix of zeros. In addition you have two points P=[8,5] and Q=[8,15].
Now You want to calculate an angle. This does not need normal vectors, but only the vectors from P to the location of a "target" and from the "target" to Q:
a = Target + P;
b = Q - Target;
ang = atan2(norm(cross(a,b)), dot(a,b));
Now the only point to clarify is, what a "target" is. You've mentioned AoI(5, 5:7) = 1. Is the one target or three targets? Does the orientation of the short "line" matter or only the position or e.g. the center?
AS far as I can see, this is a 2D problem and neither planes nor normal vectors are required.
Miguel Albuquerque
on 6 May 2022
Yes its, a normal to the line, not a plane.
In that case there are 3 targets. The way you are calculating the angles, if instead a horizontal line i had a vertical line AoI(5:7, 5) = 1, for instance, that ang should be different?
Matt J
on 6 May 2022
@Miguel Albuquerque Incidentally, in all of your example, the lines have been either perfectly horizontal or vertical. Will that always be the case?
Miguel Albuquerque
on 6 May 2022
yes it will always be the case, either horizontal or vertical lines. If they are horziontal lines, it is only needed to calculate one normal, since that normal will always be orthogonal to every horizontal line. But in case I have a vertical one, that should be different.
Thanks for the help so far
David Goodmanson
on 6 May 2022
Hi Jan, re the comment of May 4 According to common usage and, for example the Wolfram Mathworld site, a 'normal vector' is a vector of any length that is perpendicular to a plane (or more generally one of many vectors perpendicular to a line), and a 'normalized vector' is one of unspecified direction that has unit length.
Accepted Answer
Matt J
on 6 May 2022
Edited: Matt J
on 6 May 2022
reg=regionprops(bwconncomp(AoI,4),'Image');
N=numel(reg);
normals=nan(2,N);
for i=1:N
I=reg(i).Image; %EDITED
if isscalar(I)
continue;
elseif iscolumn(I)
normals(:,i)=[0;1];
elseif isrow(I)
normals(:,i)=[1;0];
end
end
13 Comments
Miguel Albuquerque
on 6 May 2022
Edited: Miguel Albuquerque
on 6 May 2022
In this case, when i have a line AoI(1,(5:10)) = 1;
A normal to this line should be [5 0] for instance, in the code you did it gave me [0 -1]
I need a normal for each line, if i have more than 1 line for instance AoI(1,(1:10)) = 1
AoI(1:24,5) = 1, i needed a normal to the first one and one different to the second, since the first is horizontal and the second vertical
Thanks
Matt J
on 6 May 2022
Edited: Matt J
on 6 May 2022
For a generic coordinate [x,y], the code assumes the x-axis to be horizontal, so [0,-1] does point along the y-axis as it should. If that's not the coordinate system you wish to use,you can interchange x and y.
Miguel Albuquerque
on 6 May 2022
Thanks a lot, that was what I was looking for.
Thanks once more,
Miguel Albuquerque
on 6 May 2022
I was trying to figure out something if you could still help me, I have this code:
for xx=1:200
for yy=1:200
if AoI(xx,yy) ~= 0 % Target detection
X_target= xx*Lp;
Y_target= yy*Lp;
reg=regionprops(logical(AoI),'Image');
N=numel(reg);
normals=nan(2,N);
for i=1:N
I=reg(i).Image;
if isscalar(I)
continue;
elseif iscolumn(I)
normals(:,i)=[0 1];
else
normals(:,i)=[1 0];
end
end
This give me the normals, as you helped me. But im reading the entire matrix and identifying all the targets, but with your code, how could I apply it to this for cycle that is reading the matrix, so it could identify if its a horizontal or vertical line and then get its normal.
Thanks again
Miguel Albuquerque
on 6 May 2022
I understand that, but i still need the targets positions in order to calculate the angles between transmitter-target(main objective) by this way:
VTransmitter_target=[X_target-X_transmitter Y_target-Y_transmitter]; % Vector transmitter-target
Vectors_product=dot( VTransmitter_target,normal_ntarget1);
angle_transmitter =180-acosd(Vectors_product/(norm(VTransmitter_target)*norm(normals)));
Matt J
on 6 May 2022
Edited: Matt J
on 6 May 2022
I don't know how you define the position of the targets. If it's their centroids, regionprops can get those as well,
reg=regionprops(bwconncomp(AoI,4),'Image','Centroid');
N=numel(reg);
for i=1:N %loop over targets
I=reg(i).Image;
if isscalar(I)
continue;
elseif iscolumn(I)
normal_ntarget=[0 1];
else
normal_ntarget=[1 0];
end
X_target=reg(i).Centroid(2);
Y_target=reg(i).Centroid(1);
VTransmitter_target=[X_target-X_transmitter Y_target-Y_transmitter]; % Vector transmitter-target
Vectors_product=dot( VTransmitter_target,normal_ntarget)/norm(VTransmitter_target);
angle_transmitter =180-acosd(Vectors_product);
end
Miguel Albuquerque
on 6 May 2022
Im sorry I dont know this code, I am very thankfull for your help.
Basically I want to read all targets( positions different from zero in the matrix) and get its coordinates(x target,y target). But I want to know first in its a vertical or horizontal one( I dont identify by the centroid but as individual targets, so it is as each coordinate(x target, y target) was a individual target. If its a vertical one, calculate its normal to get the incident angle by this:
VTransmitter_target=[X_target-X_transmitter Y_target-Y_transmitter]; % Vector transmitter-target
Vectors_product=dot( VTransmitter_target,normals);
angle_transmitter =180-acosd(Vectors_product/(norm(VTransmitter_target)*norm(normals)));
if its a horizontal one, get incident angle by the same. In your last code, its only reading targets by the centroid and gives always the same normal [1 0] even if the targets and verticals.
Thanks for your help, if u could still help im would appreciate
Matt J
on 8 May 2022
Edited: Matt J
on 8 May 2022
So you mean if the target consists of 4 vertically connected points, you want o compute 4 angles for that target?
In your last code, its only reading targets by the centroid and gives always the same normal [1 0] even if the targets and verticals.
No, I don't know why you think so. You can see in the simplified example below where AoI contains a single horizontal and single vertical target, it is able to recognize the orientation of each and select the correct normal.
AoI=zeros(10); AoI(1:4)=1; AoI(7,4:9)=1
AoI = 10×10
1 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
reg=regionprops(bwconncomp(AoI,4),'Image','Centroid');
N=numel(reg);
for i=1:N %loop over targets
I=reg(i).Image;
if isscalar(I)
continue;
elseif iscolumn(I)
normal_ntarget=[0 1];
else
normal_ntarget=[1 0];
end
normal_ntarget
end
normal_ntarget = 1×2
0 1
normal_ntarget = 1×2
1 0
Miguel Albuquerque
on 8 May 2022
Yes but as you asked , if there is 4 targets vertically I want to compute 4 angles, with the normal to a vertical line.
And if there are 4 targets horizontal, I want to calculate 4 angles with a normal to a horizontal line.
Thanks
Matt J
on 8 May 2022
Edited: Matt J
on 8 May 2022
Then you could do as follows,
reg=regionprops(bwconncomp(AoI,4),'Image','PixelList');
N=numel(reg);
for i=1:N %loop over vertical/horizontal target groups
X_target=reg(i).PixelList(:,2);
Y_target=reg(i).PixelList(:,1);
VTransmitter_target=[X_target-X_transmitter Y_target-Y_transmitter];
distances=vecnorm(VTransmitter_target,2,2); %transmitter to target
I=reg(i).Image;
if iscolumn(I)
Vectors_product=VTransmitter_target(:,2)./distances;
else
Vectors_product=VTransmitter_target(:,1)./distances;
end
reg(i).angle_transmitter = 180-acosd(Vectors_product);
end
Miguel Albuquerque
on 8 May 2022
So now I have this: I also calculated angle receiver, between target and receiver (8,15). But In order to proceed with my code, to calculate status and so on, I needed for angle receiver, and angle transmitter to be calculate individually. So imagine in (2,5) there is a target, for this I will check if its vertical or horziontal, calculate vector-transmitter, vector-receiver and its angles to the normal to the line. And then check for that target status and so on, proceed with my code. In your code i have this solution
Angle_transmitter=[180;170;35;...]
I needed angle transmitter=[180] and on next iteration angle transmitter=[170] .... Same with distances, vectors_product
Thanks a lot for saving my skin on this code... Is there anyway I can show my apreciation?
Lp=1; % Pixel length
Nx= zeros(1,400); % dimension in x, horizontal of surveillance area
Ny= zeros(400,1); % dimension in y, vertical of surveillance area
AoI=Nx.*Ny; % Surveillance area
% Horizontal targets
AoI(2,(5:10)) = 1; % define target, set row 4, from column 7-10 to 1, no correlation to Lp
AoI(5,(5:7)) = 1;
AoI(6,10) = 1;
normal_ntarget1=[1 0]; % Define a normal vector to the target
% Receiver antenna position
X_receiver=8;
Y_receiver=15;
% Transmitter antenna position
X_transmitter=8;
Y_transmitter=5;
reg=regionprops(bwconncomp(AoI,4),'Image','PixelList');
N=numel(reg);
for i=1:N %loop over vertical/horizontal target groups
X_target=reg(i).PixelList(:,2);
Y_target=reg(i).PixelList(:,1);
VTransmitter_target=[X_target-X_transmitter Y_target-Y_transmitter];
VTarget_receiver=[X_receiver-X_target Y_receiver-Y_target]; % Vector Target-receiver
distances=vecnorm(VTransmitter_target,2,2); %transmitter to target
distances2=vecnorm(VTarget_receiver,2,2); %transmitter to target
I=reg(i).Image;
if iscolumn(I)
Vectors_product=VTransmitter_target(:,2)./distances;
Vectors_product2=VTarget_receiver(:,2)./distances2;
else
Vectors_product=VTransmitter_target(:,1)./distances;
Vectors_product2=VTarget_receiver(:,1)./distances2;
end
angle_transmitter = 180-acosd(Vectors_product);
angle_receiver = acosd(Vectors_product);
status=snell_function(angle_transmitter,angle_receiver);
Pr = LoS_receiver(X_receiver,Y_receiver,X_target,Y_target,AoI);
Pt = LoS_transmitter(X_transmitter,Y_transmitter,X_target,Y_target,AoI);
continue
if status ==1 && Pt ==1 && Pr ==1
R1=sqrt( (X_transmitter-X_target).^2 + (Y_transmitter-Y_target).^2); % Distance transmitter-target in meters
R2=sqrt( (X_receiver-X_target).^2 + (Y_receiver-Y_target).^2); % Distance Receiver-target in meters
Rd=sqrt( (X_receiver-X_transmitter).^2 + (Y_receiver-Y_transmitter).^2); % Distance Transmitter-Receiver in meters
fprintf('\n Coordenadas do alvo(%d,%d)',X_target,Y_target);
fprintf('\n Distância transmissor-alvo R1 %4.2f metros',R1);
fprintf('\n Distância alvo-recetor R2 %4.2f metros',R2);
fprintf('\n Distância transmissor-recetor Rd %4.2f metros',Rd);
continue
end
end
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)