Swift Draw a line from center of one circle to the edge of another - swift

I am trying to draw a UIBezierPath in swift where i can get it to go from the center of a circle to another circles center but what i really want is for the line to stop at the edge of the end circle but at the point where the line would have intersected the circles edge if the line was continuating to the center of the circle and not stopping at the edge.
I need somehow to calculate the intersection point between the line and the circle. how would i be able to do that when the circles are UIImageViews with width and height of 30 (so radius 15) and i now the centers coordinates of the two circles.

I have found a solution.
From the the set of x and y (center of circles) from now called (x, y) and (x2, y2) a vector can be made that is (x2 - x, y2 - y) where x2 - x i will call a and y2 - y i will call b then the distance of the vector can be calculates as sqrt(a^2 + b^2) where the result of i will call dist.
From this a Unit vector can be made with is (a/dist, b/dist) now all i need to do to get my new coordinates for the arrow is (x,y) as starting coordinates and (x2 + ra/dist, y2 + rb/dist) as the end coordinates where r is the radius of the circle at (x2, y2).

Related

Matlab - isolating x/y values of a circle within a circle

I am looking for a way to isolate the x and/or y coord of a circle within a circle, as shown in the image.
I need to isolate this so i can set a condition that when a ball enters a circle, i can change some qualities of the ball, i have been able to do this for the outer circle, which is centred at [0 0] using the code below,
while sqrt(XY(1)^2 + XY(2)^2) < 5
but cannot figure out how to do it for the interior circles.
Thanks
If you know the center and the radius of the inner circles you are able to calculate the X and Y coordinates of the circles then, you can use the inpolygon function to thest if a point is inside a circle (inpolygon returns 1 if a point is inside the polygon, 0 otherwise). In this case the polygon is constitued by the points of the circles.
In the following code a point moves across three circles (two of them placed inside the bigger one).
The inpolygon function is used to test if the point (the ball) is inside a circle and in change its colour according to the circle it is inside to.
% Define the radius and centre of three circles
r1=10;
r2=3
r3=4
c1=[0 0];
c2=[3 3];
c3=[-4 -4]
% Calculate the X and Y coord of the three circles
t=0:.01:2*pi;
x=cos(t)*r1
y=sin(t)*r1
x1=cos(t)*r2+c2(1)
y1=sin(t)*r2+c2(2)
x2=cos(t)*r3+c3(1)
y2=sin(t)*r3+c3(2)
% Plot the circles
plot(x,y,'r')
hold on
plot(x1,y1,'g')
plot(x2,y2,'b')
daspect([1 1 1])
% Define the ball trajectory
mx=-10:1:10;
my=-10:1:10;
for i=1:length(mx)
% Plot the ball: black if outside of all the circle
mh=plot(mx(i),my(i),'o','markerfacecolor','k','markeredgecolor','k')
% If the ballk is inside the first circle, make it red
if(inpolygon(mx(i),my(i),x,y))
mh.MarkerFaceColor='r';
mh.MarkerEdgeColor='r';
end
if(inpolygon(mx(i),my(i),x1,y1))
% If the ballk is inside the second circle, make it green
mh.MarkerFaceColor='g';
mh.MarkerEdgeColor='g';
end
if(inpolygon(mx(i),my(i),x2,y2))
% If the ballk is inside the third circle, make it blue
mh.MarkerFaceColor='b';
mh.MarkerEdgeColor='b';
end
pause(1)
end
Hope this helps.
Qapla'

Periodic boundary condition in Matlab for random spheres in a cube model

I have random non-overlapping spheres (stationary) in a cube. I am trying to implement periodic boundary condition on the walls, so that if there are any half sphere on the edge it appears on the other side. This seems to be a well studied problem, but am not sure how should i implement it on spheres.
At the start of the code, i would have random sphere position (c, r), where c = [ x y z] inside or on the edges of cube of dimension (dims), where dims = [ l b h ].
Code for selecting a random sphere in a cube:
function [ c, r ] = randomSphere_1( dims )
% creating one sphere at random inside [0..dims(1)]x[0..dims(2)]x...
% radius and center coordinates are sampled from a uniform distribution
% over the relevant domain.
%
% output: c - center of sphere (vector cx, cy,... )
% r - radius of sphere (scalar)
r = 0.15 + ( 0.55 - 0.15) .* rand(1);% radius varies between 0.15mm - 0.55mm
c = bsxfun (#times,(dims) , rand(1,3)) + r; % to make sure sphere is placed inside or on the edge of the cube
% periodic condition
*if*
I am trying to build a code if the center co-ordinates fall on the edge or over them then there should be periodicity in spheres that is the the other half should be on the other side. I have added an image just to give an idea about what i mean by periodic boundary condition. So the spheres on the edges are exactly how i want. How should i proceed with the problem?

Turtle line intersection, coordinates

I need to make a small program that draws three circles, a line between the first two, and then determines if the third touches or intersects the line. I have done everything but the last part. I am trying to use the points to determine if the area is 0, which would mean that the third point is, in fact, intersecting the line. Right? Or I could use another way. Technically the third circle can be within 3 pixels of the line. The problem is near the bottom at the hashtag. I would appreciate any help or suggestions that move this in another direction. Thank you.
import turtle
x1, y1 = eval(input("Enter coordinates for the first point x, y: "))
x2, y2 = eval(input("Enter coordinates for the second point x, y: "))
x3, y3 = eval(input("Enter coordinates for the third point x, y: "))
turtle.penup()
turtle.goto(x1, y1)
turtle.pendown()
turtle.circle(3)
turtle.penup()
turtle.goto(x2, y2)
turtle.pendown()
turtle.circle(3)
turtle.penup()
turtle.goto(x3, y3)
turtle.pendown()
turtle.circle(3)
turtle.penup()
turtle.color("red")
turtle.goto(x1, y1)
turtle.pendown()
turtle.goto(x2, y2)
a = (x1, y1)
c = (x3, y3)
#can't multiply sequence by non-int of type 'tuple'
area = (a * c) / 2
if area == 0:
print("Hit")
else:
print("Miss")
Ther center of 3rd circle is (x3,y3) and have a radius 3 and you are trying to determine any intersection with ([x1,y1],[x2,y2]) line segment.
If any point in the line is within the circle, then there is an intersection.
Circle region formula is: (x-x3)^2 + (y-y3)^2 < 3^2
You should test for every point on the line whether this inequality holds and if any single point satisfies this condition, then you can conclude that the line and circle intersect.
The first step would be to determine coordinate points of line segment (all points between [x1,y1],[x2,y2] points in a straight line) then you can try to test these points in a loop.
You can calculate the area of the triangle by defining vectors from one vertex to the other two (adding a third constant coordinate to embed the plane in 3-dimensional space (so cross-products make sense)),
#pseudocode
b = (x2, y2, 1) - (x1, y1, 1) = (x2-x1, y2-y1, 0)
c = (x3, y3, 1) - (x1, y1, 1) = (x3-x1, y3-y1, 0)
then take the cross-product of these,
a = b cross c = (by*cz-bz*cy, bz*cx-bx*cz, bx*cy-by*cx)
then take the magnitude of this resulting vector which is the area of the parallelogram defined by the two vectors,
pa = |a| = ax^2 + ay^2 + az^2
then divide by two to get the area of the triangle (half of the parallelogram).
ta = pa/2
Source: http://en.wikipedia.org/wiki/Triangle_area#Using_vectors
Am I wright? The position of the circles to each other does not matter?
Make a linear function from the line between the two center points. (ax+b=y)
Where a is the gradient and b is the y-intersection.
To rotate a through 90° is easy. Inverse and negate a.
Find b of the second linear function. b'=y-a'*x .
At once replace the x,y with the coordinates of your 3. circle point.
Now you have a linear function which is rectangular to the old one and where the third circle point is part of.
Intersect the old linear function with the new one.
You'll get the lot point.
You need to find out the distance between the 3. circle point and the lot point and whether it is greater than the radius.
You need there functions (JS):
function makelinear (x1,y1,x2,y2){
var temp=x2-x1;
if(temp==0)temp=0.00000000000001;//not clean but fast.
var a=(y2-y1)/temp,
b=y1-a*x1;
return[a,b];
}
function ninetydeg(a,b,x,y){
var aout=1/a,
bout=y+aout*x;
return [aout,bout];
}
function lineintersection(a1,b1,a2,b2){
var temp=a1-a2;
if(temp==0)temp=0.00000000000001;
var x=(b2-b1)/temp,
y=a1*x+b1;
return[x,y];
}
function distance(x1,y1,x2,y2){
var x=x1-x2,
y=y1-y2;
return(Math.sqrt(x*x+y*y));
}
Sorry for to be complicate, I've found no other solution in short time. May be there is a vector solution.

How can I detect if a point is inside a cone or not, in 3D space?

How is possible to detect if a 3D point is inside a cone or not?
Ross cone = (x1, y1, h1)
Cone angle = alpha
Height of the cone = H
Cone radius = R
Coordinates of the point of the cone = P1 (x2, y2, h2)
Coordinates outside the cone = P2( x3, y3, h3)
Result for point1 = true
Result for point2 = false
To expand on Ignacio's answer:
Let
x = the tip of the cone
dir = the normalized axis vector, pointing from the tip to the base
h = height
r = base radius
p = point to test
So you project p onto dir to find the point's distance along the axis:
cone_dist = dot(p - x, dir)
At this point, you can reject values outside 0 <= cone_dist <= h.
Then you calculate the cone radius at that point along the axis:
cone_radius = (cone_dist / h) * r
And finally calculate the point's orthogonal distance from the axis to compare against the cone radius:
orth_distance = length((p - x) - cone_dist * dir)
is_point_inside_cone = (orth_distance < cone_radius)
The language-agnostic answer:
Find the equation of the line defining the main axis of your cone.
Compute the distance from the 3D point to the line, along with the intersection point along the line where the distance is perpendicular to the line.
Find the radius of your cone at the intersection point and check to see if the distance between the line and your 3D point is greater than (outside) or less than (inside) that radius.
A cone is simply an infinite number of circles whose size is defined by a linear equation that takes the distance from the point. Simply check if it's inside the circle of the appropriate size.
Wouldn't it be easier to compute angle between vector to center of cone and vector from apex pointing at point under evaluation. If vector projection is used and the length of the resultant vector is shorter then the vector pointing at the center of the cone the between the angle and length you know if you are inside a cone.
https://en.wikipedia.org/wiki/Vector_projection

Circles misplaced in MATLAB

I'm trying to draw a circle on an image in MATLAB with given X,Y coordinates and radius. Here's the chuck of code of method that draws multiple circles for me -
function circle( Xs, Ys, Rs, LineWidth, LineColor)
radius = Rs;
centerX = Xs;
centerY = Ys;
for i=1:length(centerX)
rectangle('Position',[centerX(i), centerY(i), radius(i), radius(i)],...
'Curvature',[1,1],...
'LineWidth',LineWidth,...
'LineStyle','-',...
'EdgeColor',LineColor);
end
end
But whenever I see the circles in an image, I see that the circles are a little bit misplaced from the given coordinates (for example, they moved a little bit right/down). How do I fix this problem?
What you are drawing is actually a rectangle. But you have a curvature defined, which makes it look like a circle. The circle is then defined by a bounding box with the coordinates of the rectangle. The Position of the rectangle is the upper left corner (or in a regular plot the lower left corner) and what you called the radius is actually the width and height of that bounding box.
This is what I mean:
>> figure, imshow(I)
>> rectangle('Position',[100,100,120,120],'Curvature',[1,1])
>> rectangle('Position',[100,100,120,120],'Curvature',[0,0],'EdgeColor','r')
>> axis on
This code will produce a circle and a rectangle both in the same position defined by the same rectangle coordinates in the upper left corner. The red one is the bounding box I am speaking of.
Edit: If you don't want to use the rectangle function you could maybe do the following:
>> figure,imshow(I)
>> hold on
>> plot(centerX+radius*sin(0:0.1:2*pi),centerY+radius*cos(0:0.1:2*pi))
Try the following:
function circle( Xs, Ys, Rs, LineWidth, LineColor)
radius = Rs;
centerX = Xs;
centerY = Ys;
xStart = centerX - radius;
yStart = centerY - radius;
for i=1:length(centerX)
rectangle('Position',[xStart(i) , yStart(i) , radius(i), radius(i)],...
'Curvature',[1,1],...
'LineWidth',LineWidth,...
'LineStyle','-',...
'EdgeColor',LineColor);
end
end
I hope this will work.
By subtracting the radius from the center points we can get the starting point(Top left corner) of the rectangle with curvature [1,1], that is nothing but the circle.