How can I find co-ordiantes of points inside a circle in 3D space using MATLAB? - matlab

I created a circle in MATLAB using following code.
I need to find the points inside the circle in 3D space
radius = 5;
theta=linspace(0,2*pi);
rho=ones(1,100).*radius;
[x,z]=pol2cart(theta,rho);
y=center(2)*ones(1,length(x))
fill3(x,y,z,'yellow')
How can I find Cartesian co-ordinates of points inside this circle?

Not sure I'm understanding well your question. Obviously there are infinite points inside the circle so I guess you want to check whether a point (or a set of points) is inside or not. If you loop through a list of points, those who meet the following criteria are inside (or in the perimeter of the circle):
norm([xi,zi]) <= radius
yi = 0 (same plane)
Was this what you were asking?
Edit: you can do it pretty quickly in matlab without a loop. Lets imagine you have x = [1 2 3] and z = [4 5 6]. To check all combinations you can use repmat with x and z' (transverse) to obtain: xr = [ 1 2 3; 1 2 3; 1 2 3] and zr = [ 4 4 4 ; 5 5 5 ; 6 6 6]. So you have 2 matrixes with the coordinates of all possible points. Now you can calculate the norm as: N = sqrt(xr.^2+zr.^2). All i,j with Nij <= radius are inside your circle (considering all your x and z are <= radius of course)

Related

Extrapolate from triangulation

Suppose we have five vertices:
X = [0 1;
2 1;
4 1;
1 0;
3 0];
a triangulation:
T = [1 4 2;
4 5 2;
5 3 2];
and function values defined on the vertices:
Fx = [1;
2;
3;
4;
-5];
then we can easily compute the function value for any point inside the triangle by using the barycentric coordinates. For point P = [1 .5], which lies in the first triangle, the barycentric coordinates are B = [.25 .5 .25], so the function evaluates to Fxi = 1/4 + 4/2 + 2/4 = 2.75.
However, I have difficulty to see how one would extrapolate this surface. We could find the closest triangle and extrapolate from that. The problem is that this results in a discontinuous function. Consider e.g. point P = [2 2]. According to triangle 1, its value would be -0.5, whereas according to triangle 3 its value would be 9.5.
Is there a "standard" or generally accepted approach to extrapolate from piecewise linear functions? Any pointers to existing material also greatly appreciated.
A possibility is Shepard's method:
https://en.wikipedia.org/wiki/Inverse_distance_weighting
The resulting function interpolates the input values defined at the vertices and is non-linear but continuous everywhere else.
The choice p=2 usually gives decent results.
Another technique to look for are "Barycentric coordinates for non-convex polygons".
The following publication shows (page 8 etc.) how the weight functions behave outside the polygons
https://www.in.tu-clausthal.de/fileadmin/homes/techreports/ifi0505hormann.pdf
However, even this solution does not behave piecewise-linear on your given triangulation.

How can I plot filled rectangles as a backdrop for a desired target in MATLAB?

I have two datasets, one of which is a target position, and the other is the actual position. I would like to plot the target with a +/- acceptable range and then overlay with the actual. This question is only concerning the target position however.
I have unsuccessfully attempted the built in area, fill, and rectangle functions. Using code found on stackoverflow here, it is only correct in certain areas.
For example
y = [1 1 1 2 1 1 3 3 1 1 1 1 1 1 1]; % Target datum
y1 = y+1; %variation in target size
y2 = y-1;
t = 1:15;
X=[t,fliplr(t)]; %create continuous x value array for plotting
Y=[y1,fliplr(y2)]; %create y values for out and then back
fill(X,Y,'b');
The figure produced looks like this:
I would prefer it to be filled within the red boxes drawn on here:
Thank you!
If you would just plot a function y against x, then you could use a stairs plot. Luckily for us, you can use the stairs function like:
[xs,ys] = stairs(x,y);
to create the vectors xs, ys which generate a stairs-plot when using the plot function. We can now use these vectors to generate the correct X and Y vectors for the fill function. Note that stairs generates column vectors, so we have to transpose them first:
y = [1 1 1 2 1 1 3 3 1 1 1 1 1 1 1]; % Target datum
y1 = y+1; %variation in target size
y2 = y-1;
t = 1:15;
[ts,ys1] = stairs(t,y1);
[ts,ys2] = stairs(t,y2);
X=[ts.',fliplr(ts.')]; %create continuous x value array for plotting
Y=[ys1.',fliplr(ys2.')]; %create y values for out and then back
fill(X,Y,'b');
Again, thank you hbaderts. You answered my question perfectly, however when I applied it to the large data set I needed for, I obtained this image
https://dl.dropboxusercontent.com/u/37982601/stair%20fill.png
I think it is because the fill function connects vertices to fill?
In any case, for the potential solution of another individual, combined your suggested code with the stair function and used the area function.
By plotting them on top of one another and setting the color of the lower area to be white, it appears as the rectangular figures I was after.
%sample code. produces image similar to o.p.
y = [1 1 1 2 1 1 3 3 1 1 1 1 1 1 1];
y1 = y+1;
y2 = y-1;
t = 1:15;
[ts,ys1] = stairs(t,y1);
[ts,ys2] = stairs(t,y2);
area(ts,ys1,'FaceColor','b','EdgeColor','none')
hold on
area(ts,ys2,'FaceColor','w','EdgeColor','none')
https://dl.dropboxusercontent.com/u/37982601/stair%20area.png
Thanks again for your help and for pointing me in the right direction!

Pixels between 2 intersecting lines

I need to find pixel values that are between the intersection of 2 lines. The following image shows the points that I want namely the brown region.
These 4 co-ordinates can change and are not necessarily the corner points.
What is the fastest way to get the pixel values ? Is there any function that can give me the necessary mask.
You should calculate for each point, whether it is above the line or below. If the line is given in its equation form Ax+By+C, then it is as simple as calculating the sign of this expression, per your point (x,y). If your lines are given in any other form, you should first calculate the form above. (See here and here)
Let L1 be the set of all points below the first line, and L2 the set of all points below the second line. Then, your set is X = Xor(L1,L2)
[ ] Xor []
Equals:
Here is a Matlab code that solves you problem for the corner points, based on the solution that I've described. You can adjust the line equations in your code.
function CreateMask()
rows = 100;
cols = 200;
[X,Y] = ndgrid(1:cols,1:rows);
belowFirstLine = X*(1/cols) + Y*(-1/rows) + 0 < 0;
belowSecondLine = X*(-1/cols) + Y*(-1/rows) + 1 < 0;
figure;imshow( transpose(xor(belowSecondLine,belowFirstLine)));
end
Here is geometrical, rather than analytic solution.
First, you need to construct a mask image, initially filled with all zeroes. Then you should draw both lines using Bresenham's algorithm. There is no default implementation in Matlab, but you can pick one at Matlab Central. I assume, you have coordinates of intersections of the lines with image borders.
After that your image is divided into four areas and you need to flood-fill two of them using bwfill. And now you have the mask.
You can start with generating two matrices with x & y coordinates:
1 2 3 4 5 1 1 1 1 1
1 2 3 4 5 vs. 2 2 2 2 2 sized as the region
1 2 3 4 5 3 3 3 3 3
Then one needs 4 line equations that convert x*a + y*b < c into 4 masks:
diagonals have to be XORED and top/bottom masks ANDED
or without logical expressions: mask=mod(diag1+diag2,2)*top_mask*bot_mask;
The line width can be controlled by adding to 'c' half of the line width, assuming that a and b are normalized.

MATLAB: Four-part color logo(polygon)

My task is to write MATLAB code to produce a 4-part logo as shown in the screenshot. The top left should be black and the bottom right should be white. The other
two colours should be chosen randomly by the program.
I have taken the following approach:
clear all
clc
close all
x = [1 4 1 4 1 6.5 7 7];
y = [3 4 5.5 5 8 7 8 3];
fill(x,y,'k')
which creates the upper left black part. I wonder if that approach is good enough and if it is, what is the next step. I thought of storing those two variables in a shape object or something (I'm not familiar with Matlab) and rotate it somehow. Could you help me with that?
You don't need to rotate, just use the symmetry
clear all
clc
close all
x = [1 4 1 4 1 6.5 7 7];
y = [3 4 5.5 5 8 7 8 3]-3;
clrs=jet(10);
fill(x,y,'k')
hold on;
fill(2*max(x)-x,y,clrs(round(rand*10),:))
fill(x,-y,clrs(round(rand*10),:))
fill(2*max(x)-x,-y,'w')
The easiest way to do this all this, is to make sure that your center point (i.e. the point where the different colors meet), is positioned at [0,0]. Then a rotation of the figure (by multiple of 90°) boils down to changing the sign of either the x and/or y values of your contour.
If you need the figure to be at a point different from [0 0], just add these coordinates after you did the rotation.
So starting from your code, you can do this:
x = [1 4 1 4 1 6.5 7 7]-7;
y = [3 4 5.5 5 8 7 8 3]-3;
c = [5 6];
col = [0 0 0;
rand(2,3);
1 1 1];
fill( x+c(1), y+c(2),col(1,:)); hold on;
fill(-x+c(1), y+c(2),col(2,:));
fill( x+c(1),-y+c(2),col(3,:));
fill(-x+c(1),-y+c(2),col(4,:)); hold off;
edit: Clarification for the col and c variables.
The variable col contains the colors to be used in rgb style, where each row is a color. rand generates uniformly random numbers in the range [0,1], which is also where the values for the colors are expected to be. In the code above a 2x3 random matrix is generated, so that means 2 random colors which fits perfectly within the col matrix.
The variable c contains the center of your figure. If you look at the plot, the center will be at [5 6] (so 5 along the x axis and 6 along the y axis). You could use two variables instead, but I think that keeping both together in a variable is easier to deal with. I would personally do the same for your x and y variables, as that would allow you to use rotation matrices more easily, but that's just a matter of choice.

Generalize this matlab code for non-square matrices

I am working on some fourier transform code in matlab, and have come across the following:
xx = meshgrid(1:N);
% Center on DC
xx = xx - dcN;
% normalize dynamic range from -1 to 1
xx = xx./max(abs(xx(:)));
% form y coordinate from negative transpose of x coordinate (maintains symmetry about DC)
yy = -xx';
% compute the related radius of the x/y coordinates centered on DC
rr = sqrt(xx.^2 + yy.^2);
How can I generalize this for non-square matrices? This code is assuming my matrix is square, so dcN is the center of the square matrix (in other words, with 11x11, dcN = 6).
The math doesnt work out for that yy variable when the transpose is taken for a non-square matrix.
I have tried to figure out if I can make a meshgrid going from "top to bottom" instead of left to right - but I havent been able to figure taht out either.
Thanks
I have tried to figure out if I can
make a meshgrid going from "top to
bottom" instead of left to right - but
I havent been able to figure taht out
either.
>> N=5
N =
5
>> rot90(meshgrid(N:-1:1))
ans =
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
From your question I guess that you want to find rr, i.e. the distance of any element in the matrix from the center.
If you want this for a M-by-N array, you'd do the following
%# note that using meshgrid instead of ndgrid will swap xx and yy
[xx,yy] = ndgrid(-(M-1)/2:(M-1)/2,-(N-1)/2:(N-1)/2);
%# normalize to the max of xx,yy
nrm = max((M-1)/2,(N-1)/2);
xx = xx./nrm;
yy = yy./nrm;
rr = sqrt(xx.^2+yy.^2)