Compute the tortuosity of a polyline - polyline

I have series of (x, y) coordinates, if joined this represent a polyline. This polyline is a geographic track.
All that I need is to get the polyline tortuosity. It should be usefull a sort of percentage. E.g. The path has x% tortuosity.

well, it all depends on how you define tortuosity. there is a wikipedia article regarding tortuosity, which may shed some light on the subject.
an interesting sentence in the article tells us that: "roughness (or tortuosity) could be measured by relative change of curvature". that makes a good starting point.
your polyline is made of adjacent line segments. you can compute the angle between each adjacent line segment. using this information you can get a good idea of tortuosity for your polyline. for example, let seg(n) be the line segment between point n and point n+1:
tortuosity = sum(abs(angle(seg(n), seg(n+1))) for n in 1 to number of segment)
(computing the angle between 2 line segments is left as an exercise, but does not require a degree in mathematics)
the above measure is not scaled: the more points you have, the higher the value might be. you can easily scale this result according to the number of line segments you have:
unit_tortuosity = tortuosity / (n * pi)
(the maximum angle between 2 line segments is pi, adjust your angle() function so that it returns a result between 0 and pi. so your tortuosity would be at most n*pi, hence the above scaling factor which allows to have a value between 0 and 1 with 0 representing a perfectly straight polyline)

Related

how to calculate the coordinates on a polyline perpendicular to point (in 3D)?

I have two approximately parallel polylines representing railway tracks, consisting of hundreds (maybe thousands) of x, y, z coordinates. The two lines stay approximately 1.435m apart, but bend and curve as a railway would.
If I pick a point on one of the polylines, how do find the point which is perpendicular on the other parallel polyline?
I take it CAD programs use the cross product to find the distance / point and it chooses the line to snap to based on where your mouse is hovering.
I would like to achieve the same thing, but without hovering your mouse over the line.
Is there a way to simply compute the closest line segment on the parallel line? Or to see which segment of the polyline passes through a perpendicular plane at the selected point?
It isn't practical to loop through the segments as there are so many of them.
In python the input would be something like point x, y, z on rail1 and I would be looking to output point x, y, z on rail2.
Many thanks.
You want the point of the minimum distance to the other track.
If the other track is defined by line segments, each spanning two points with a parameter t going between 0 and 1
pos(t) => pos_1 + t * ( pos_2 - pos_1 )
You need to find the t value that produces the minimum distance to the point. Place a temporary coordinate system on the point and express the ends of each line segment pos_1 and pos_2 in relative coordinates to the point of interest.
The value of t is for the closest point is
dot(pos_1,pos_1) - dot(pos_1,pos_2)
t = ------------------------------------------------------
dot(pos_1,pos_1)-2*dot(pos_1,pos_2)+dot(pos_2,pos_2)
where dot(a,b)=ax*bx+ay*by+az*bz is the vector dot product.
Now if the resulting t is between 0 and 1, then the closest point is on this segment, and its coordinates are given by
pos(t) => pos_1 + t * ( pos_2 - pos_1 )

finding if a point lies within a set distance from a line, knowing only points along the line

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.

3D Trilateration using given distances of unknown fixed points

I am new to this forum and not a native english speaker, so please be nice! :)
Here is the challenge I face at the moment:
I want to calculate the (approximate) relative coordinates of yet unknown points in a 3D euclidean space based on a set of given distances between 2 points.
In my first approach I want to ignore possible multiple solutions, just taking the first one by random.
e.g.:
given set of distances: (I think its creating a pyramid with a right-angled triangle as a base)
P1-P2-Distance
1-2-30
2-3-40
1-3-50
1-4-60
2-4-60
3-4-60
Step1:
Now, how do I calculate the relative coordinates for those points?
I figured that the first point goes to 0,0,0 so the second one is 30,0,0.
After that the third points can be calculated by finding the crossing of the 2 circles from points 1 and 2 with their distances to point 3 (50 and 40 respectively). How do I do that mathematically? (though I took these simple numbers for an easy representation of the situation in my mind). Besides I do not know how to get to the answer in a correct mathematical way the third point is at 30,40,0 (or 30,0,40 but i will ignore that).
But getting the fourth point is not as easy as that. I thought I have to use 3 spheres in calculate the crossing to get the point, but how do I do that?
Step2:
After I figured out how to calculate this "simple" example I want to use more unknown points... For each point there is minimum 1 given distance to another point to "link" it to the others. If the coords can not be calculated because of its degrees of freedom I want to ignore all possibilities except one I choose randomly, but with respect to the known distances.
Step3:
Now the final stage should be this: Each measured distance is a bit incorrect due to real life situation. So if there are more then 1 distances for a given pair of points the distances are averaged. But due to the imprecise distances there can be a difficulty when determining the exact (relative) location of a point. So I want to average the different possible locations to the "optimal" one.
Can you help me going through my challenge step by step?
You need to use trigonometry - specifically, the 'cosine rule'. This will give you the angles of the triangle, which lets you solve the 3rd and 4th points.
The rules states that
c^2 = a^2 + b^2 - 2abCosC
where a, b and c are the lengths of the sides, and C is the angle opposite side c.
In your case, we want the angle between 1-2 and 1-3 - the angle between the two lines crossing at (0,0,0). It's going to be 90 degrees because you have the 3-4-5 triangle, but let's prove:
50^2 = 30^2 + 40^2 - 2*30*40*CosC
CosC = 0
C = 90 degrees
This is the angle between the lines (0,0,0)-(30,0,0) and (0,0,0)- point 3; extend along that line the length of side 1-3 (which is 50) and you'll get your second point (0,50,0).
Finding your 4th point is slightly trickier. The most straightforward algorithm that I can think of is to firstly find the (x,y) component of the point, and from there the z component is straightforward using Pythagoras'.
Consider that there is a point on the (x,y,0) plane which sits directly 'below' your point 4 - call this point 5. You can now create 3 right-angled triangles 1-5-4, 2-5-4, and 3-5-4.
You know the lengths of 1-4, 2-4 and 3-4. Because these are right triangles, the ratio 1-4 : 2-4 : 3-4 is equal to 1-5 : 2-5 : 3-5. Find the point 5 using trigonometric methods - the 'sine rule' will give you the angles between 1-2 & 1-4, 2-1 and 2-4 etc.
The 'sine rule' states that (in a right triangle)
a / SinA = b / SinB = c / SinC
So for triangle 1-2-4, although you don't know lengths 1-4 and 2-4, you do know the ratio 1-4 : 2-4. Similarly you know the ratios 2-4 : 3-4 and 1-4 : 3-4 in the other triangles.
I'll leave you to solve point 4. Once you have this point, you can easily solve the z component of 4 using pythagoras' - you'll have the sides 1-4, 1-5 and the length 4-5 will be the z component.
I'll initially assume you know the distances between all pairs of points.
As you say, you can choose one point (A) as the origin, orient a second point (B) along the x-axis, and place a third point (C) along the xy-plane. You can solve for the coordinates of C as follows:
given: distances ab, ac, bc
assume
A = (0,0)
B = (ab,0)
C = (x,y) <- solve for x and y, where:
ac^2 = (A-C)^2 = (0-x)^2 + (0-y)^2 = x^2 + y^2
bc^2 = (B-C)^2 = (ab-x)^2 + (0-y)^2 = ab^2 - 2*ab*x + x^2 + y^2
-> bc^2 - ac^2 = ab^2 - 2*ab*x
-> x = (ab^2 + ac^2 - bc^2)/2*ab
-> y = +/- sqrt(ac^2 - x^2)
For this to work accurately, you will want to avoid cases where the points {A,B,C} are in a straight line, or close to it.
Solving for additional points in 3-space is similar -- you can expand the Pythagorean formula for the distance, cancel the quadratic elements, and solve the resulting linear system. However, this does not directly help you with your steps 2 and 3...
Unfortunately, I don't know a well-behaved exact solution for steps 2 and 3, either. Your overall problem will generally be both over-constrained (due to conflicting noisy distances) and under-constrained (due to missing distances).
You could try an iterative solver: start with a random placement of all your points, compare the current distances with the given ones, and use that to adjust your points in such a way as to improve the match. This is an optimization technique, so I would look up books on numerical optimization.
If you know the distance between the nodes (fixed part of system) and the distance to the tag (mobile) you can use trilateration to find the x,y postion.
I have done this using the Nanotron radio modules which have a ranging capability.

Calculating the Length of Intersections (through a 2d grid)

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)

Computational geometry, tetrahedron signed volume

I'm not sure if this is the right place to ask, but here goes...
Short version: I'm trying to compute the orientation of a triangle on a plane, formed by the intersection of 3 edges, without explicitly computing the intersection points.
Long version: I need to triangulate a PSLG on a triangle in 3D. The vertices of the PSLG are defined by the intersections of line segments with the plane through the triangle, and are guaranteed to lie within the triangle. Assuming I had the intersection points, I could project to 2D and use a point-line-side (or triangle signed area) test to determine the orientation of a triangle between any 3 intersection points.
The problem is I can't explicitly compute the intersection points because of the floating-point error that accumulates when I find the line-plane intersection. To figure out if the line segments strike the triangle in the first place, I'm using some freely available robust geometric predicates, which give the sign of the volume of a tetrahedron, or equivalently which side of a plane a point lies on. I can determine if the line segment endpoints are on opposite sides of the plane through the triangle, then form tetrahedra between the line segment and each edge of the triangle to determine whether the intersection point lies within the triangle.
Since I can't explicitly compute the intersection points, I'm wondering if there is a way to express the same 2D orient calculation in 3D using only the original points. If there are 3 edges striking the triangle that gives me 9 points in total to play with. Assuming what I'm asking is even possible (using only the 3D orient tests), then I'm guessing that I'll need to form some subset of all the possible tetrahedra between those 9 points. I'm having difficultly even visualizing this, let alone distilling it into a formula or code. I can't even google this because I don't know what the industry standard terminology might be for this type of problem.
Any ideas how to proceed with this? Thanks. Perhaps I should ask MathOverflow as well...
EDIT: After reading some of the comments, one thing that occurs to me... Perhaps if I could fit non-overlapping tetrahedra between the 3 line segments, then the orientation of any one of those that crossed the plane would be the answer I'm looking for. Other than when the edges enclose a simple triangular prism, I'm not sure this sub-problem is solvable either.
EDIT: The requested image.
I am answering this on both MO & SO, expanding the comments I made on MO.
My sense is that no computational trick with signed tetrahedra volumes will avoid the precision issues that are your main concern. This is because, if you have tightly twisted segments, the orientation of the triangle depends on the precise positioning of the cutting plane.
[image removed; see below]
In the above example, the upper plane crosses the segments in the order (a,b,c) [ccw from above]: (red,blue,green), while the lower plane crosses in the reverse order (c,b,a): (green,blue,red). The height
of the cutting plane could be determined by your last bit of precision.
Consequently, I think it makes sense to just go ahead and compute the points of intersection in
the cutting plane, using enough precision to make the computation exact. If your segment endpoints coordinates and plane coefficients have L bits of precision, then there is just a small constant-factor increase needed. Although I am not certain of precisely what that factor is, it is small--perhaps 4. You will not need e.g., L2 bits, because the computation is solving linear equations.
So there will not be an explosion in the precision required to compute this exactly.
Good luck!
(I was prevented from posting the clarifying image because I don't have the reputation. See
the MO answer instead.)
Edit: Do see the MO answer, but here's the image:
I would write symbolic vector equations, you know, with dot and cross products, to find the normal of the intersection triangle. Then, the sign of the dot product of this normal with the initial triangle one gives the orientation. So finally you can express this in a form sign(F(p1,...,p9)), where p1 to p9 are your points and F() is an ugly formula including dot and cross products of differences (pi-pj). Don't know if this can be done simpler, but this general approach does the job.
As I understand it, you have three lines intersecting the plane, and you want to calculate the orientation of the triangle formed by the intersection points, without calculating the intersection points themselves?
If so: you have a plane
N·(x - x0) = 0
and six points...
l1a, l1b, l2a, l2b, l3a, l3b
...forming three lines
l1 = l1a + t(l1b - l1a)
l2 = l2a + u(l2b - l2a)
l3 = l3a + v(l3b - l3a)
The intersection points of these lines to the plane occur at specific values of t, u, v, which I'll call ti, ui, vi
N·(l1a + ti(l1b - l1a) - x0) = 0
N·(x0 - l1a)
ti = ----------------
N·(l1b - l1a)
(similarly for ui, vi)
Then the specific points of intersection are
intersect1 = l1a + ti(l1b - l1a)
intersect2 = l2a + ui(l2b - l2a)
intersect3 = l3a + vi(l3b - l3a)
Finally, the orientation of your triangle is
orientation = direction of (intersect2 - intersect1)x(intersect3 - intersect1)
(x is cross-product) Work backwards plugging the values, and you'll have an equation for orientation based only on N, x0, and your six points.
Let's call your triangle vertices T[0], T[1], T[2], and the first line segment's endpoints are L[0] and L[1], the second is L[2] and L[3], and the third is L[4] and L[5]. I imagine you want a function
int Orient(Pt3 T[3], Pt3 L[6]); // index L by L[2*i+j], i=0..2, j=0..1
which returns 1 if the intersections have the same orientation as the triangle, and -1 otherwise.
The result should be symmetric under interchange of j values, antisymmetric under interchange of i values and T indices. As long as you can compute a quantity with these symmetries, that's all you need.
Let's try
Sign(Product( Orient3D(T[i],T[i+1],L[2*i+0],L[2*i+1]) * -Orient3D(T[i],T[i+1],L[2*i+1],L[2*i+0]) ), i=0..2))
where the product should be taken over cyclic permutations of the indices (modulo 3). I believe this has all the symmetry properties required. Orient3D is Shewchuk's 4-point plane orientation test, which I assume you're using.

Resources