Given 2 points A and B belonging to a sphere with a given Radius R.
I want to find the sphere whose center has the minimum distance to a given point G.
Thanks
The centers of a sphere defined by two points and a radius is a circle. You can connect C (the center of the circle) and G and create a 90° projection on the circle plane. The minimum distance is where the projection intersects the circle tangent by 90°. There are two solutions. You have to take the smaller one.
The point C you want is in the plane that contains A, B, and G. You compute
AG = G - A;
BG = G - B;
N = cross(AG, BG);
N = N / norm( N ); % the normal to the plane
Now you solve for C in this plane. Three equations:
dot((C-G), N)=0;
sqrt(sum(A-C).^2) = R;
sqrt(sum(B-C).^2) = R;
Three unknowns are the three elements of C. You end up with two solutions, so compute the distance to G and pick the closer one.
Related
Assume that I have a vector with 6 distance elements as
D = [10.5 44.8 30.01 37.2 23.4 49.1].
I'm trying to create random pair positions of a given distances, inside a 200 meters circle. Note that the distance D created by using (b - a).*rand(6,1) + a, with a = 10 and b = 50 in Matlab. I do not know how to generate the random pairs with given the distances.
Could anybody help me in generating this kind of scenario?
This is an improvement to Alessiox's answer. It follows same logic, first generate a set of points ([X1 Y1]) that have at least distance D from the main circle border, then generate the second set of points ([X2 Y2]) that have exact distance D from the first set.
cx = 50; cy = -50; cr = 200;
D = [10.5 44.8 30.01 37.2 23.4 49.1]';
n = numel(D);
R1 = rand(n, 1) .* (cr - D);
T1 = rand(n, 1) * 2 * pi;
X1 = cx+R1.*cos(T1);
Y1 = cy+R1.*sin(T1);
T2 = rand(n, 1) * 2 * pi;
X2 = X1+D.*cos(T2);
Y2 = Y1+D.*sin(T2);
You can tackle the problem using a two-steps approach. You can
randomly generate the first point and then you can consider the circle whose center is that point and whose radius is the distance in D
once you did draw the circle, every point lying on that circle will have distance D from the first point previously created and by random selection of one of these candidates you'll have the second point
Let's see with an example: let's say you main circle has radius 200 and its center is (0,0) so we start by declaring some main variables.
MAINCENTER_x=0;
MAINCENTER_y=0;
MAINRADIUS=200;
Let's now consider the first distance, D(1)=10.5 and we now generate the first random point which (along with its paired point - I reckon you don't want one point inside and the other outside of the main circle) must lie inside the main circle
r=D(1); % let's concentrate on the first distance
while true
x=((MAINRADIUS-2*r) - (-MAINRADIUS+2*r))*rand(1,1) + (-MAINRADIUS+2*r);
y=((MAINRADIUS-2*r) - (-MAINRADIUS+2*r))*rand(1,1) + (-MAINRADIUS+2*r);
if x^2+y^2<=(MAINRADIUS-2*r)^2
break;
end
end
and at the end of this loop x and y will be our first point coordinates.
Now we shall generate all its neighbours, thus several candidates to be the second point in the pair. As said before, these candidates will be the points that lie on the circle whose center is (x,y) and whose radius is D(1)=10.5. We can create these candidates as follows:
% declare angular spacing
ang=0:0.01:2*pi;
% build neighbour points
xp=r*cos(ang)+x;
yp=r*sin(ang)+y;
Now xp and yp are two vectors that contain, respectively, the x-coordinates and y-coordinates of our candidates, thus we shall now randomly select one of these
% second point
idx=randsample(1:length(xp),1);
secondPoint_x=xp(idx);
secondPoint_y=yp(idx);
Finally, the pair (x,y) is the first point and the pair (secondPoint_x, secondPoint_y) is our second point. The following plot helps summarizing these steps:
The red circle is the main area (center in (0,0) and radius 200), the red asterisk is the first point (x,y) the blue little circle has center (x,y) and radius 10.5 and finally the black asterisk is the second point of the pair (secondPoint_x, secondPoint_y), randomly extracted amongst the candidates lying on the blue little circle.
You must certainly can repeat the same process for all elements in D or rely on the following code, which does the very same thing without iterating through all the elements in D.
MAINCENTER_x=0;
MAINCENTER_y=0;
MAINRADIUS=200;
D = [10.5 44.8 30.01 37.2 23.4 49.1];
% generate random point coordinates
while true
x=((MAINRADIUS-2*D) - (-MAINRADIUS+2*D)).*rand(1,6) + (-MAINRADIUS+2*D);
y=((MAINRADIUS-2*D) - (-MAINRADIUS+2*D)).*rand(1,6) + (-MAINRADIUS+2*D);
if all(x.^2+y.^2<=(MAINRADIUS-2*D).^2)
break;
end
end
% declare angular spacing
ang=0:0.01:2*pi;
% build neighbour points
xp=bsxfun(#plus, (D'*cos(ang)),x');
yp=bsxfun(#plus, (D'*sin(ang)),y');
% second points
idx=randsample(1:size(xp,2),length(D));
secondPoint_x=diag(xp(1:length(D),idx));
secondPoint_y=diag(yp(1:length(D),idx));
%plot
figure(1);
plot(MAINRADIUS*cos(ang)+MAINCENTER_x,MAINRADIUS*sin(ang)+MAINCENTER_y,'r'); %main circle
hold on; plot(xp',yp'); % neighbours circles
hold on; plot(x,y,'r*'); % first points (red asterisks)
hold on; plot(secondPoint_x,secondPoint_y,'k*'); %second points (black asterisks)
axis equal;
Now x and y (and secondPoint_x and secondPoint_y by extension) will be vector of length 6 (because 6 are the distances) in which the i-th element is the i-th x (or y) component for the first (or second) point.
This question is from my last post,
But I will just focus on a particular part,
If I have a 3d matrix M, 256*256*124,and a plane defined by 3 points that intersect the 3d matrix, A,B,C, how to find the distance of all points in M to the plane defined by A,B,C
Here is the suggestion I got,
[X Y Z] = meshgrid(1:256,1:256,1:124)
A = [X(:)';Y(:)';Z(:)'];
n = cross([coor_A-coor_B],[coor_B-coor_C]); %The norm vector of the plane
d = norm(mean([coor_A,coor_B,coor_C]),2); %The distance from origin to the plane
According to Hesse normal form,
L = ((n*A)-d); %The distance from all points in M to the plane
But all the values in L are huge, which indicates that no points are found on the intersection plane.
Can anyone tell me what's wrong?
You missed one line on the Wikipedia page
where
So add this line
n0 = n / norm(n);
and change the final line to
L = ((n0*A)-d);
I'm trying to build a function in MATLAB, in which you input a segment (defined by two points) and a polygon (4-sides) by indicating on an array its vertices.
I have the following code:
function intersection = intersectSegmentPolygon (s, p)
% Create a vector with X coords of vertices and same for Y coords.
xv = [p(1,1) p(2,1) p(3,1) p(4,1)];
yv = [p(1,2) p(2,2) p(3,2) p(4,2)];
% Read the segment
x = [s.A(1) s.B(1)];
y = [s.A(2) s.B(2)];
[in,on] = inpolygon(x,y,xv,yv);
% Return vectors containing the coords of the intersecting points
intersection = [x(on), y(on)];
I am intersted in obtaining the points at the position on (the intersecting points) but, obviously the function is only checking the points A and B (the initial and final coordinates of the segment), what can I do in order to check all the points contained on the segment AB? Thank you.
Use the parametric equation of the line segment, P = (1-t) A + t B, with 0<=t<=1.
Find the intersections between the polygon edges and the line of support of the segment, expressing the position of the intersection in terms of t (momentarily ignore the constraint on t).
You will find 0 or 2 intersections, not more, hence 0 or 2 values of t, forming an interval. The solution is given by the intersection of this interval with the interval [0,1], an elementary 1D problem.
I'm currently using MatLab as part of a Digital Imaging course and trying to get the values of a circle of pixels on an image. The idea is to start with a central pixel (x, y) and then collect all of the pixels with the radius r and return their values.
So far, all I've managed to create is this (where A_grey is an image):
function [localMean] = getLocalMean(x, y, radius)
for x = 1:size(A_grey, 1)
for y = 1:size(A_grey, 2)
<code>
end
end
But I'm not entirely sure what I'm doing and I could really do with some beginner level advice here. Any tips?
I'll throw you a bone. This is actually quite easy. Given the size of the image / viewing window, stored in width and height that you want to examine, generate a meshgrid of points, then search for those (x,y) values that satisfy the equation of the circle. In other words, you want to search for all (x,y) values given a centre of your circle (x0,y0) such that:
(x - x0)^2 + (y - y0)^2 = r^2
r is the radius of your desired circle. As such, it's as simple as:
[x,y] = meshgrid(1:width, 1:height);
p = (x - x0).^2 + (y - y0).^2 == r^2;
pts = [x(p) y(p)];
We first generate a meshgrid of points. Think of a meshgrid as a set of 2D arrays where each unique spatial location in the same spot of these arrays gives you the x and y coordinates at that spatial location in 2D. Take a look at the following example:
[x,y] = meshgrid(1:3, 1:3)
x =
1 2 3
1 2 3
1 2 3
y =
1 1 1
2 2 2
3 3 3
In terms of pixel coordinates, the top-left corner is (x,y) = (1,1). The top right corner is (x,y) = (3,1) and so on. Note that the convention is that x is horizontal while y is vertical, as what most digital image processing literature will give you. If this is not what you want, replace meshgrid with ndgrid to respect the row/column convention.
Once we generate this grid of points, we simply put this through our circle equation and see which values of (x,y) at a given centre (x0,y0) satisfy the equation of the circle. Once we find such locations, we simply index into our meshgrid of points and return those (x,y) values, corresponding to those points that lie along the perimeter of your circle.
Let's say i want to generate a set of coordinates(x,y), using rand. Take any one point of the generated random set, the distance between this point and those points( nearest/the first layer) surround it could be limited in certain range. The overview effect looks 'these random points are uniformly distributed.
Limiting random co-ordinates about a point (x,y) with in a distance 'r' is more like selecting random points in a circle with centre (x,y) and radius 'r'.
Below should help
http://www.mathworks.com/matlabcentral/answers/294-generate-random-points-inside-a-circle
All n points must be inside a circle. The diameter of this circle is the maximum distance (d_max) between any two points. Use polar coordinates: r = (d_max / 2) * sqrt(rand(n, 1)); phi = 2 * pi * rand(n, 1); The square root is needed to get uniform areal density. Convert polar coordinates to Descartes coordinates the usual way: x = x0 + r .* cos(phi); y = y0 + r .* sin(phi); where (x0, y0) gives the center of the circle.
The result for d_max = 10:
The histogram of the distances between points:
Use Modulus
mod([1:5],3)
ans =
1 2 0 1 2
http://www.mathworks.co.uk/help/techdoc/ref/mod.html