I had a question regarding 2 line segments. Say we have 2 line segments whose origin and lengths are given as: (P0, L0) and (P1, L1) respectively. I need to find when can they end at the same point. The line segments lie anywhere in 3D space.
One of the approaches I could think of is: Let's say this common end point is T and the points are A and B. So for the line segments with A and B as origins, A,B and T must form a triangle. Length of vector AT = L0 and length of vector BT = L1. But since the orientation of the line segment is not known, there can be a lot of possibilities. Lets say we choose a particular orientation for line segment AT as (i,j,k) - 1st octant. So now we can move anywhere in space from T but only by a distance L1 to find BT.
This is where I m not sure how to move forward.
The line segments can end in the same point if and only if the distance between P0 and P1 is less than or equal to L0 + L1. In the special case where this distance is equal to L0 + L1 the line segments have the same orientation in space and lie on the same line.
A way to think about this is to ask if two spheres around P0 and P1 with radii L0 and L1 intersect or at least touch each other. The circle (point) of intersection (touch) is where your line segments can have the same end point.
Related
I need to ensure that a point is no more than x distance from a line derived from multiple other points.
If I plot lat/long points every 3 miles, I can infer a 'line' to travel. I want to make sure that 'potential' destinations are no more than 1 mile from that line. (the "multiple" points wont always be the same from instance to instance, BUT will be consistent per instance, and the "acceptable" distance from the line can vary per instance).
The tricky part is I have points, not a line...(the line is implied). Things work out "ok" if my "acceptable distance" is greater then my distance between the multiple points. however... If, say, my multiples are 2.5 apart, and I say a distance of 1 is acceptable for any point of interest. Then there are points between the two original points, that lie along the line but I can figure easily.
So I though since I have ONE measurement, I know the length of a line (on x axis, the distance between 2 of the multiple points..). I could treat that as one of two equal sides of a triangle and figure the hypotenuse.
d = distance between (each, multiple) points.
a = ( d/2 )
b = ( d/2 )
c = sq root of ( a^2 + b^2 )
C is going to be slightly larger then my initial "acceptable distance", so I'll use that.
Is there an better way to figure???
thx
Lets see if I can illustrate
point A point B
O----------------------------------O
distance form point A to point B is 5 miles...
Now...
point A point B
O----------------------------------O
point C
O
Question: is point C inside of 1 mile from the line that connects point A and B?????
How does one express this with math? such that the distance between points can be expressed as a variable.
This is a mapping problem, points of interest close to a 'road' or 'path' that has sample points as Lat/long the point of interest also has a lat/long.
If I use a triangle or intersecting circles, I end up with peaks or humps that are well outside of my 'acceptable distance off path', just to accommodate the space between my samples.
I hope that makes sense.
You can find the distance from a line which is defined by two points using the formula here -> http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
A perpendicular line segment will be your friend in this problem. Find a line segment perpendicular to AB which contains point C.
The intersection of the line segments would be point D.
Get the distance of segment CD and you have your answer.
I have a two segments AB and CD (in red). These two segments are facing each others. They are not completely parallel but will never be perpendicular to each others either.
From that, I need to find the two normals of these segments (in blue) that oppose each others (i.e. the two normals are outside ABCD). I know how to calculate the normals of the segments but obviously each segment has two normals, and I cannot figure out how to programmatically select the ones I need. Any suggestion?
Calculate the vector v between the midpoints of the two segments, pointing from AB to CD. Now the projection of the desired normal to AB onto v must be negative and the projection of the desired normal to CD onto v must be positive. So just calculate the normals, check against v, and negate the normals if needed to make them satisfy the condition.
Here it is in Python:
# use complex numbers to define minimal 2d vector datatype
def vec2d(x,y): return complex(x,y)
def rot90(v): return 1j * v
def inner_prod(u, v): return (u * v.conjugate()).real
def outward_normals(a, b, c, d):
n1 = rot90(b - a)
n2 = rot90(d - c)
mid = (c + d - a - b) / 2
if inner_prod(n1, mid) > 0:
n1 = -n1
if inner_prod(n2, mid) < 0:
n2 = -n2
return n1, n2
Note that I assume the endpoints define lines meeting the conditions in the problem. Nor do I check for the edge case when the lines have the same midpoint; the notion of "outside" doesn't apply in that case.
I think there are two cases to consider:
Case 1: Intersection between lines occurs outside the endpoints of either segment.
In this case the midpoint method suggested by #Michael J. Barber will work for sure. So form a vector between the midpoints of the segments, compute the dot product of your normal vectors with this midpoint vector and check the sign.
If you're computing the normal for lineA, the dot product of the normal with the vector midB -> midA should be +ve.
Case 2: Intersection between lines occurs inside the endpoints of one segment.
In this case form a vector between either one of the endpoints of the segment that does not enclose the intersection point and the intersection point itself.
The dot product of the normal for the segment that does enclose the intersection point and this new vector should be +ve.
You can find the outward normal for the other segment by requiring that the dot product between the two normals is -ve (which would only be ambiguous in the case of perpendicular segments).
I've assumed that the segments are not co-linear or actually intersecting.
Hope this helps.
You can reduce the four combinations for the signs as follows:
Calculate the dot product of the normals, a negative sign indicates that both show outside or inside.
As I suppose that your normals have unit lenght, you can detect parallelity if the dot product has magnitude one. A positive value indicates that both show in the same direction, a negative value says that both show in different directions.
It the normals are not parallel: parametrize lines as x(t) = x0 + t * n for a normal n and calculate the t for which both intersect. A negative t will indicate that both show outside. It is enough if you do this for one of the normals, as you reduced your combinations from 4 to 2 in step 1.
If both normals are parralel: Calculate the time t for which the normals hit the midpoint between of your segments. As in 2. is enough if you do this for one of the normals, as you reduced your combinations from 4 to 2 in step 1.
I am trying to find circumcenter of Given Three point of Triangle……..
NOTE: all these three points are with X,Y and Z Co-Ordinate Means points are in 3D
I know that the circumcenter is the point where the right bisectors intersect….
But for that I have to find middle point of each side then the right bisectors and then intersection point of that …..this is long and error some process……
Is there not any formula which just takes as input these three points of triangle and giving us the Circumcenter of Triangle ……?
Thanks………
The wiki page on Circumscribed circle has it in terms of dot and cross products of the three vertex vectors. It also has a formula for the radius of the circle, if you are so interested.
First of all, you need to make sure that points are not collinear. i.e. do not lie in the same line. For that you need to find the direction cosines of the lines made by three points, and if they have same direction cosines, halt, you can't get circle out of it.
For direction cosine please check this article on wikipedia.
(A way of finding coordinate-geometry and geometry -- based on the theorem that, a perpendicular line from center of circle bisects a chord)
Find the equation of the plane.
This equation must reduce to the form
and the direction cosines (of the line perpendicular to plane determines the plane), so direction cosines of the line perpendicular to this line is
given by this link equations -- 8,9,10 (except replace it for l, m, n).
Find the equation of the lines (all three) in 3-d
(x-x1)/l=(y-y1)/m=(z-z1)/n (in terms of direction cosines) or
(x-x1)/(x2-x1)=(y-y1)/(y2-y1)=(z-z1)/(z2-z1)
Now we need to find the equation of line
a) this perpendicular to the line, from 2 (let l1, m1, n1 be direction cosines of this line)
b) must be contained in place from 1 (let l2, m2, n2 be direction cosines of this line perpendicular to plane)
Find and solve (at least two lines) from 3, sure you will be able to find the center of the circle.
How to find out equation ??? as we are finding the circum-center, we will get our points (i.e. it is the midpoint of the two points) and for a) we have
l1*l+m1*m+n1*n = 0 and l2*l+m2*m+n2*n = 0 where l, m, n are direction cosines of our, line, now solving this two equation, we can get l, m interms of n. And we use this found out (x1,y1,z1) and the value of l, m, 1 and we will have out equation.
The other process is to solve the equation given in this equation
https://stackoverflow.com/questions/5725871/solving-the-multiple-math-equations
Which is the deadliest way.
The other method is using the advantage of computer(by iteration) - as I call it (but for this you need to know the range of the coordinates and it consumes lot of memory)
it's like this (You can make it more precise by incrementing at 1/10) but certainly bad way.
for(i=minXrange, i>=maxXrange; i++){
for(j=minYrange, j>=maxYrange; j++){
for(i=minZrange, i>=maxZrange; k++){
if(((x1-i)^2 + (y1-j)^2 + (z1-k)^2) == (x2-i)^2 + (y2-j)^2 + (z2-k)^2) == for z)){
return [i, j, k];
}
}
}
}
I have a line that I must do calculations on for each grid square the line passes through.
I have used the Superline algorithm to get all these grid squares. This gives me an array of X,Y coordinates to check.
Now, here is where I am stuck, I need to be able to calculate the distance traveled through each of the grid squares... As in, on a line not on either 90 degree or 45 degree angles, each grid square accommodates a different 'length' of the total line.
Image example here, need 10 reputation to post images
As you can see, some squares have much more 'line length' in them than others - this is what I need to find.
How do I work this out for each grid square? I've been at this for a while and request the help of the Stack Overflowers!
There may be some clever way to do this that is faster and easier, but you could always hack through it like this:
You know the distance formula: s=sqrt((x2-x1)^2+(y2-y1)^2). To apply this, you must find the x and y co-ordinates of the points where the line intersects the edges of each grid cell. You can do this by plugging the x and y co-ordinates of the boundaries of the cell into the equation of the line and solve for x or y as appropriate.
That is, each cell extends from some point (x0,y0) to (x0+1,y0+1). So we need to find y(x0), y(x0+1), x(y0), and x(y0+1). For each of these, the x or y value found may or may not be within the ranges for that co-ordinate for that cell. Specifically, two of them will be and two won't. The two that are correspond to the edges that the line passes through, and the two that aren't are edges that it doesn't pass through.
Okay, maybe this sounds pretty confusing, so let's work through an example.
Let's say your line has the equation x=2/3 * y. You want to know where it intersects the edges of the cell extending from (1,0) to (2,1).
Plug in x=1 and you get y=2/3. 2/3 is in the legal range for y -- 0 to 1 -- so (1,2/3) is a point on the edge where the line intersects this cell. Namely, the left edge.
Plug in x=2 and you get y=4/3. 4/3 is outside the range for y. So the line does not pass through the right edge.
Plug in y=0 and you get x=0. 0 is not in the range for x, so the line does not pass through the bottom edge.
Plug in y=1 and you get x=3/2. 3/2 is in the legal range for x, so (3/2,1) is another intersection point, on the top edge.
Thus, the two points where the line intersects the edges of the cell are (1,2/3) and (3/2,1). Plug these into the distance formula and you'll get the length of the line segement through this cell, namely sqrt((1-3/2)^2+(2/3-1)^2)=sqrt(1/4+1/9)=sqrt(13/36). You can approximate that to any desired level of precision.
To do this in a program you'd need something like: (I'll use pseudo code because I don't know what language you're using)
// Assuming y=mx+b
function y(x)
return mx+b
function x(y)
return (y-b)/m
// cellx, celly are co-ordinates of lower left corner of cell
// Upper right must therefore be cellx+1, celly+1
function segLength(cellx, celly)
// We'll create two arrays pointx and pointy to hold co-ordinates of intersect points
// n is index into these arrays
// In an object-oriented language, we'd create an array of point objects, but whatever
n=0
y1=y(cellx)
if y1>=celly and y1<=celly+1
pointx[n]=cellx
pointy[n]=y1
n=n+1
y2=y(cellx+1)
if y2>=celly and y2<=celly+1
pointx[n]=cellx+1
pointy[n]=y2
n=n+1
x1=x(celly)
if x1>=cellx and x1<=cellx+1
pointx[n]=x1
pointy[n]=celly
n=n+1
x2=x(celly+1)
if x2>=cellx and x2<=cellx+1
pointx[n]=x2
pointy[n]=celly+1
n=n+1
if n==0
return "Error: line does not intersect this cell"
else if n==2
return sqrt((pointx[0]-pointx[1])^2+(pointy[0]-pointy[1])^2)
else
return "Error: Impossible condition"
Well, I'm sure you could make the code a little cleaner, but that's the idea.
have a look at Siddon's algorithm: "Fast calculation of the exact radiological path for a three-dimensional CT array"
unfortunately you need a subscription to read the original paper, but it is fairly well described in this paper
Siddon's algorithm is an O(n) algorithm for finding the length of intersection of a line with each pixel/voxel in a regular 2d/3d grid.
Use the Euclidean Distance.
sqrt((x2-x1)^2 + (y2-y1)^2)
This gives the actual distance in units between points (x1,y1) and (x2,y2)
You can fairly simply find this for each square.
You have the slope of the line m = (y2-y1)/(x2-x1).
You have the starting point:
(x1,y2)
What is the y position at x1 + 1? (i.e. starting at the next square)
Assuming you set your starting point to 0 the equation of this line is simply:
y_n = mx_n
so y_n = (y2-y1)/(x2-x1) * x_n
Then the coordinates at the first square are (x1,y1) and at the nth point:
(1, ((y2-y1)/(x2-x1))*1)
(2, ((y2-y1)/(x2-x1))*2)
(3, ((y2-y1)/(x2-x1))*3)
...
(n, ((y2-y1)/(x2-x1))*n)
Then the distance through the nth square is:
sqrt((x_n+1 - x_n)^2 + (y_n+1 - y_n)^2)
I'm using CML to manage the 3D math in an OpenGL-based interface project I'm making for work. I need to know the width of the viewing frustum at a given distance from the eye point, which is kept as a part of a 4x4 matrix that represents the camera. My goal is to position gui objects along the apparent edge of the viewport, but at some distance into the screen from the near clipping plane.
CML has a function to extract the planes of the frustum, giving them back in Ax + By + Cz + D = 0 form. This frustum is perpendicular to the camera, which isn't necessarily aligned with the z axis of the perspective projection.
I'd like to extract x and z coordinates so as to pin graphical elements to the sides of the screen at different distances from the camera. What is the best way to go about doing it?
Thanks!
This seems to be a duplicate of Finding side length of a cross-section of a pyramid frustum/truncated pyramid, if you already have a cross-section of known width a known distance from the apex. If you don't have that and you want to derive the answer yourself you can follow these steps.
Take two adjacent planes and find
their line of intersection L1. You
can use the steps here. Really
what you need is the direction
vector of the line.
Take two more planes, one the same
as in the previous step, and find
their line of intersection L2.
Note that all planes of the form Ax + By + Cz + D = 0 go through the origin, so you know that L1 and L2
intersect.
Draw yourself a picture of the
direction vectors for L1 and L2,
tails at the origin. These form an
angle; call it theta. Find theta
using the formula for the angle
between two vectors, e.g. here.
Draw a bisector of that angle. Draw
a perpendicular to the bisector at
the distance d you want from the
origin (this creates an isosceles
triangle, bisected into two
congruent right triangles). The
length of the perpendicular is your
desired frustum width w. Note that w is
twice the length of one of the bases
of the right triangles.
Let r be the length of the
hypotenuses of the right triangles.
Then rcos(theta/2)=d and
rsin(theta/2)=w/2, so
tan(theta/2)=(w/2)/d which implies
w=2d*tan(theta/2). Since you know d
and theta, you are done.
Note that we have found the length of one side of a cross-section of a frustrum. This will work with any perpendicular cross-section of any frustum. This can be extended to adapt it to a non-perpendicular cross-section.