line and circle intersection [duplicate] - matlab

This question already exists:
Closed 10 years ago.
Possible Duplicate:
intersection of line and circle with different slope
I have line which plotted by pp=randi([-400 400],2,2) then x=pp(:,1) and y=pp(:,2). I have a circle with centre (a,b) with radius r
I want to check the intersection point of circle and the line.
I have used polyfit command to check the slope and intercept. Then I used lincirc command but the problem is if the line crosses only one point then the other point is also shown.
For example, if the line crosses one side and stops in the middle, it shows the other point as well which will not cross the boundary

You have a circle radius r centred at (a,b). You have a line. If you have plotted these points, you must have your data stored in x and y vectors, so you take the first and last of elements each as (x,y) coordinates. The first pair form the line start point and last pair the end point. Refer to these points as (c1,d1) and (c2,d2). Assuming that your lincirc function tells you there are 2 intersection points between line and circle, calculate
A1 = (c1-a,d1-b)
A2 = (c2-a,d2-b)
Now if
norm(A1,2) < r
then endpoint (c1,d1) is inside your circle, if
norm(A2,2) < r
then endpoint (c2,d2) is inside your circle.
If one of the points is inside the circle, then you only have one intersection point.
If neither point is inside the circle, then you know that your line crosses the circle twice (assuming that your lincirc function tells you there are 2 points)
If both points are inside the circle, then your lincirc function is lying to you.

Related

Optimizing computation of distance to triangle using barycentric coordinates

Building on the discussions here and here. I'm trying to compute the shortest distance between a 3D line and a 3D triangle.
I'm using barycentric coordinates to determine whether or not the point is inside the triangle. So given a triangle defined by vertices UVW and a line defined by point AB, I first compute the intersection of line AB with the plane defined by UVW. Let's call this intersection P and assume I've already done the checks to verify whether or not the point actually intersects the plane at all.
I then compute barycentric coordinates (S,T) such that S is defined along the edge UV and T is defined along the edge UW. Naturally, if 0≤S and 0≤T and S+T≤1 then P is on the triangle (or its edge) and my distance to the triangle is obviously zero.
If that's not true then P is outside the triangle and I need to compute the distance. The guidance of from the first link says to project point P onto all three edges to get three candidate points. Adding those points to the three triangle's vertices, you then have six points to test against.
Isn't it easier than that, though? If T<0, then don't you already know that UV is the closest edge and you only have to test against the projection of P onto that line? Similarly, if S<0 then UW would be the closest edge. If T>0 and S>0 then VW is the closest edge.
Thus based on the signs of S and T you already know the closest edge and only have to compute the distance from P to its projection onto that edge. If the projection isn't inside the triangle, then the closest point is either vertex. Thus your computations are about 1/3 of the proposed methods.
Am I missing something here, or is this a valid optimization? I'm fairly new to barycentric coordinates and their attributes.
It turns out that the problem of closest distance from a point and from a line are very similar and can both be reduced to a pure 2D problem.
Distance from a point
By Pythagoras, the squared distance from a point to a point of the triangle is the sum of the squared distance to the plane of support of the triangle and the squared distance of the projection of the point to that plane.
The latter distance is precisely the distance from the normal line to the triangle.
Distance from a line
Looking in the direction of the line, you see the projected triangle and the line is reduced to a single point. The requested 3D distance is equal to the 2D distance seen on the projection.
To obtain the desired coordinates, you use an auxiliary coordinate frame such that Z is in the direction of the line (and XY is a perpendicular plane); for convenience, choose the origin of the new frame to be on the line. Then by just ignoring Z, you get a planar problem in XY. The change of coordinates is an affine tranformation.
Point vs. triangle
Consider the three triangles formed by the origin (projection of the point/line) and a pair of triangle vertices (taken in cyclic order). The signed area of these triangles is a mere 2x2 determinant.
If the three areas have the same sign, the point is inside. Otherwise, the signs tell you where you are among the six surrounding regions, either past an edge or past a vertex.
On the upper figure, the point is inside (three positive areas). On the other figure, it is outside of the top-right edge (one negative area). Also note that dividing an area by the length of the corresponding side, you get the distance to the side. (Factor 2 omitted.)
The total work is
compute the affine frame;
convert the coordinates of the 3 or 4 points;
compute the three signed areas;
if inside, you are done;
otherwise, if in an edge region, compute a distance to a line and two distances to points;
otherwise you are in a vertex region, compute two distances to lines and one distance to vertex.

Postgres/PostGIS find if line intersects circle?

I am having trouble figuring this out, I have 2 points A & B, I need to draw a straight line, and then see if this line intersects with circle C
What is the best way to do this? (I am new to Postgres so details would be super appreciated), steps to do:
draw line from A to B
see if line L intersects circle C of radius R
You can use ST_MakeLine to create a line from two points and ST_Intersects to see if it intersects with the circle.
But it is probably easier to use the <-> distance operator to see if the distance of the line from the center is less than the radius.

Given 4 line equation of a convex quadrilateral, how can I find coordinate of 4 corner?

I have four line equations y=mx+b and there is 6 intersections point.
It is known that those line form a convex quadrilateral.
How can I find which four intersection form the quadrilateral (preferably in order)?
First Concave QUAD:
The 6th intersection point should be also in 1) I just forget to draw it there.
compute all the intersection points and pair them to lines
l1: p2,p5,p6
l2: p1,p4,p6
l3: p1,p2,p3
l4: p3,p4,p5
l means line and p means intersection point
determine if point is only edge or also middle
so middle point is if you got another point from each side of line it belongs. In other words if you convert point to its parameter position (or distance from some start point) then middle point is in between the other two points distances. The parameter/distance you directly obtain while intersection computation but in case you don't you can use this:
t(p) = dot(p-A,B-A)
where A,B are line endpoints, p is queried intersection point and t(p) is its scalar "distance" from A.
So find out which points are only edge e and which are middle m:
l1: e2,e5,m6
l2: e1,e4,m6
l3: e1,m2,e3
l4: e3,m4,e5
now if any point is at least once middle then it is partially middle, if it is only edge then it is edge and if it is only middle then it is middle:
edge: p1,p3,p5
partial: p2,p4
middle: p6
construct polygon
So the edge points we have to use. The partial points we skip (as they lie on already used line) and finally we also use middle point. We know our polygon will be:
(p1,p3,p5) + (p6)
Now we need to find where the concave middle point p6 will go. There are 3 combinations:
e1,m6,e3,e5
e1,e3,m6,e5
e1,e3,e5,m6
we know that m6 belong to l1,l2 and l1,l2 has also p2,p5,p1,p4 from which are edge points only: e1,e5 so the m6 will be placed between them so the correct solution is:
e1,e3,e5,m6
Now Convex QUAD:
if we take advantage from #1,#2 then to form convex quad we have to use the middle and partial middle points and chose one of the pure edge points. Select the one that is not belong to line with pure middle point. So we have to use:
(p2,p4) + (m6) + one_from(e1,e3,e5)
the m6 is not belonging to l3,l4 so we need find edge belonging to both which is e3 so
(p2,p4) + (m6) + (e3)
Now we just have to find out the order. middle point and edge point will not be near themselves so you got 2 solutions:
p2,m6,p4,e3
p2,e3,p4,m6
Both are correct they are just reverse of themselves (differend polygon winding rule) so you can chose the one you need based on z coordinate of cross product of any two neighboring vertices.
Solve systems of linear equations for every line pair
y = m[i] * x + b[i]
y = m[j] * x + b[j]
where m[i], b[i] are coefficients of i-th line and get (x,y) for intersection.
If there are exactly 6 intersection (no parallel lines, no degeneracies), then every line has three intersection points in row. Two intersections are "outer" and one (middle) is "inner", so there are three inner and three outer points.
Seems that convex quadrilateral always contains all the three inner points, so we can separate inner points, and get corresponding fourth point.
For example, if lines are designated as A,B,C,D, and intersections AB, AC, CD are inner, then fourth point is intersection BD (B and D are unique in intersection list)
P.S. Note that line equation form y=mx+b is not suitable for all possible lines (not for vertical lines), so it would better to use more general form like A*x + B*y + C = 0 or other.

Plotting a Line from a known point to points in a fitted curve in MATLAB

I have a set of data whose points I have plotted and fitted using a power of 2 fit in MATLAB. I'm trying to draw 3 lines to that curve as tangential lines. Each of these lines start from the co-ordinates of say, (x,y): (2,0) (4,0) (9,0).
Is it possible for MATLAB to draw lines from the curve to the first known point until the line has only one solution (tangent to the curve) with the curve?
I feel that this requires some sort of specified interval which tells MATLAB to step the co-ordinates until it finds the closest point. Does anyone know if this has been done or can be done at all?
From a point not lying on the curve, you want to draw a line that is tangent to it. In case of a convex function like y=2^x this is only possible from a point under the curve (not over it).
Since you already have the point (call it (a,b)), you need the slope of such a line. The slope is determined by the values (y-b)/(x-a) where (x,y) runs over the curve. Specifically, the "forward-looking" tangent has the slope equal to the minimum of (y-b)/(x-a) over all x>a. And the "backward-looking " tangent has the slope equal to the maximum of (y-b)/(x-a) over all x
Here is a very straightforward implementation of the above: I used find to restrict the search to either x>a or x<a and took min and max to find the slopes.
x = 0:0.01:4;
y = 2.^x;
a = 2;
b = 3;
k = min((y(find(x>a))-b)./(x(find(x>a))-a));
plot(x,y)
hold on
plot(x,k*(x-a)+b,'r')
k = max((y(find(x<a))-b)./(x(find(x<a))-a));
plot(x,k*(x-a)+b,'g')

intersection point of circle and a line [duplicate]

This question already exists:
Closed 10 years ago.
Possible Duplicate:
intersection of line and circle with different slope
I have line which plotted by pp=randi([-400 400],2,2) then x=pp(:,1) and y=pp(:,2). I have a circle with centre (a,b) with radius r
I want to check the intersection point of circle and the line.
I have used polyfit command to check the slope and intercept. Then I used lincirc command but the problem is if the line crosses only one point then the other point is also shown.
For example, if the line crosses one side and stops in the middle, it shows the other point as well which will not cross the boundary
You have a circle radius r centred at (a,b). You have a line. If you have plotted these points, you must have your data stored in x and y vectors, so you take the first and last of elements each as (x,y) coordinates. The first pair form the line start point and last pair the end point. Refer to these points as (c1,d1) and (c2,d2). Assuming that your lincirc function tells you there are 2 intersection points between line and circle, calculate
A1 = (c1-a,d1-b)
A2 = (c2-a,d2-b)
Now if
norm(A1,2) < r
then endpoint (c1,d1) is inside your circle, if
norm(A2,2) < r
then endpoint (c2,d2) is inside your circle.
If one of the points is inside the circle, then you only have one intersection point.
If neither point is inside the circle, then you know that your line crosses the circle twice (assuming that your lincirc function tells you there are 2 points)
If both points are inside the circle, then your lincirc function is lying to you.