Talk:Trilateration

From Wikipedia, the free encyclopedia
Jump to: navigation, search



Archives
Threads older than 180 days may be archived by MiszaBot I.

Contents

[edit] Definition of trilateration should conform to method of solution

Trilateration is a method for determining the intersections of three sphere surfaces given the centers and radii of the three spheres.


Above is the definition which I say should be used for trilateration and it was the definition that was used until Woodstong started changing it. It is simple, straightforward and to the point. It is in conformance with the method of solution that is provided.


Woodstone has claimed that trilateration is the process of deriving the position of a point from the distances to points of known location.


This is vague, ambiguous, and does not conform to the method of solution in the article. This appears to be a made up definition inspired by vandalism.

RHB100 (talk) 19:40, 11 April 2010 (UTC)

You might have a look at this, stating
"A node N has determined the distances from itself to each of three (or more) other nodes A, B, C, and so on. The other nodes' geographic locations (coordinates) are known ... The trilateration problem is to find the coordinates of node N ... from the given information. A complicating factor is that the known nodes' coordinates and distances typically include measurement errors. Two methods of solving the trilateration problem are nonlinear least squares and circle intersections with clustering."
Woodstone (talk) 04:35, 12 April 2010 (UTC)

This paper referred to above appears to be a two dimensional application and in that sense is less comprehensive than the Wikipedia trilateration article. This paper does not make any reference to Wikipedia and Wikipedia should not change the definition of trilateration because of this paper. The most Wikipedia should do is perhaps make a brief mention of a different usage of trilateration in other papers. It is important that the Wikipedia definition of trilateration conform to the problem solved in the Wikipedia article. RHB100 (talk) 19:13, 12 April 2010 (UTC)

One other point should be made with regard to links. There is a link to the Wikipedia article on the sphere. This article on the sphere adequately covers the sphere surface, radius, and center. We do not need additional links to the article on surfaces, the article on radius, or the article on centers. The article on surfaces considers surfaces as a topological concept. This serves more to distract and confuse the reader than for enlightenment. Similar remarks could be made with regard to the articles on radius and center. Therefore we need only the link to the sphere. RHB100 (talk) 19:38, 12 April 2010 (UTC)

The definition of trilateration that Woodstone has recently (01:47, 7 May 2010) forced upon us is not a rephrase of the source provided as he claims. It is a completely new definition that has practically nothing to do with the source provided. It is something that he has made up and appears to be deliberately designed to confuse. It is vague, confusing, and ambiguous. It certainly does not conform to the problem that is solved. Woodstone appears to be determined to engage in vandalism. There are some of us who have labored to make trilateration an interesting and useful article for the readers. Now we have this vandal, Woodstone, who attempts to ruin everything. RHB100 (talk) 20:29, 7 May 2010 (UTC)

I resent being called a vandal. That does not enable a serious discussion. My intentions are fully serious. I added a very respectable source that backs up my understanding of the concept. Instead, you narrow down the subject to one specific solution method for a basic case. The heading here says "definition ... should conform to method of solution". Yes, but it's the other way around: "method of solution ... should conform to definition". You cannot change the definition of a concept, just because the article describes only a part of it. You do not cite a source for your interpretation. I have a perfect one for mine. My rephrasing is definitely a valid reflection of the source. But if you insist on a closer one, I will do that. Trilateration is an originally geodetic process, in which relative locations of points are determined by measurement of their distances. If some points are known, other ones can be derived. The intersection of spheres (circles) plays a role in the algorithms, but is not the whole thing. By the way, my definition in the article was the one before you started restricting it to your liking. −Woodstone (talk) 00:31, 8 May 2010 (UTC)

Woodstone has no source for his vague, ambiguous, and confusing remarks. He makes up his writing. The sentence, "The remainder of this article describes a method for the simplest case of determining the intersections of three sphere surfaces given the centers and radii of the three spheres." has no source. It is just Woodstone's idiotic nonsense which has no basis in fact. RHB100 (talk) 04:20, 8 May 2010 (UTC)

What exactly is vague in that phrase? It is the very content you want to be the lead section. Do you agree that determining the intersection of 3 spheres is a special case of determining the relative positions of points based on their distances? −Woodstone (talk) 07:02, 8 May 2010 (UTC)

Well I think the first paragraph should tell what is in the article even if it does not define trilateration. In defining trilateration methods, we must say that they include both spheres and triangles. A few other editing changes may eliminate the vagueness while leaving most of this definition. I do think it may be possible to work out our differences. RHB100 (talk) 21:38, 8 May 2010 (UTC)

Starting by talking about triangles has the benefit of explaining the word. A trilateral is another word for triangle (compare quadrilateral), used in several branches of science. It shifts thinking about the same triangle from angles to sides (compare lateral=sideways). In 3D this would become a tetrahedron as the most basic form, bounded by four adjoining triangles. A tetrahedron is fully defined (apart from reflection) by its side lengths. The most elementary problem is posed by knowing the location of 3 corners of a tetrahedron, plus their distances to the fourth corner and then computing the location of the fourth corner. You will readily see that this is an equivalent problem to the intersection of three spheres of known radius around the first three corners. So yes, it involves triangles or spheres, but the name is reminiscent of triangles, so that is the best choice for the first definition line. I think we should use the general definition as primary meaning. It is justified to explain in detail only the most fundamental case (3 spheres as is), on which more complicated cases are based. −Woodstone (talk) 04:55, 9 May 2010 (UTC)

As I recall a tetrahedron has 4 triangular faces, 4 vertices, and 6 edges. I understand that if you know the location of 3 vertices and the distance from each of these vertices to the fourth vertex, you could regard these distances as the radii of 3 spheres. You could then compute the intersections of these 3 sphere surfaces by the methods discussed in the article. One of the intersections would be the fourth vertex of the tetrahedron. The other intersection would define the fourth vertex of another tetrahedron which has the same distances from the first three but in a different direction. RHB100 (talk) 20:40, 10 May 2010 (UTC)

So on the basis of this and to explain the etymology of trilateration better you want to change "geometry of spheres or triangles" to "geometry of triangles". Is that what you want to do? RHB100 (talk) 20:49, 10 May 2010 (UTC)

That is right. The definition can be fully expressed in triangles. It explains the word. The symmetry of the solution is indeed easy to see that way. The spheres are part of a particular way of looking at the problem and can be stated after the definition. We can point out the equivalence. −Woodstone (talk) 22:41, 10 May 2010 (UTC)

I think the sentence "Trilateration is mainly used in surveying and navigation, including global positioning systems (GPS)." should be moved to the application section. RHB100 (talk) 20:12, 10 May 2010 (UTC)

It is usual that the lead not only contains the definition, but also a summary of the content. So application and how many reference points are needed belongs there as well. −Woodstone (talk) 22:41, 10 May 2010 (UTC)

Well the applications certainly do not form a significant part of the contents. There is only a single sentence in the applications section, so that is certainly not enough to justify inclusion in a summary. RHB100 (talk) 23:42, 10 May 2010 (UTC)

We should consider that section a stub, for expansion later. Information on application ought to be there. −Woodstone (talk) 03:22, 11 May 2010 (UTC)

What is it that should be in the Application section other than surveying and navigation based on current knowledge of the uses of trilateration? RHB100 (talk) 19:45, 11 May 2010 (UTC)

I think something of the history could be added. Who started applying it. How is the relative usage frequency developing compared to triangulation. What made it possible (laser, gps). I'm personally not much of a historian and am not going to dig into this. A single person does not have to make an article complete. That's the beauty of WP, other people may come in and add things. −Woodstone (talk) 02:13, 12 May 2010 (UTC)

[edit] More than 3 points

Another point. We may want to add some information on errors and redundancy. Using more than 3 (in 3D) reference points leads to an overdetermined system. Possible methods to reconcile are:

  • one dimensional goal seek over clock error (RHB100's favorite); only for 4 points
  • newton raphson, with clock error variable; only for 4 points; perhaps not always stable
  • clustering (mentioned higher up); several combinations of 3 points will lead to a cluster around the intended solution and a few points scattered over space (the reflections); difficult to generalise
  • least squares plus newton raphson; probably the most common
  • what else?

Or do you think it's better to expand the sections in GPS dealing with that. −Woodstone (talk) 02:13, 12 May 2010 (UTC)

I made a minor upgrade to the Application leaving the rest unchanged. I am reasonably well satisfied with the article as it is right now. There are probably ways that it could be improved, but as far as I am concerned, it is good enough for now. RHB100 (talk) 19:06, 12 May 2010 (UTC)
Wouldn't Multilateration be the "solution" for an overdetermind system? I've never managed to get a good hold on why Multilateration is so strongly connected to TDOA on wikipedia, it doesn't make any sense to me... Haakoo (talk) 09:05, 7 June 2010 (UTC)

[edit] Simplified solution without extra assumptions

Because I have not contributed to other articles, I did not dare replace most of the article; I only added a short version as an alternative. The current solution is unnecessarily complex and hard to follow, and I think something like below would be much clearer. Since there have been no opinions on this at all, I'm really inclined to just go ahead and edit the article.

Note that this solution is applicable to any 3D coordinates. No trigonometric functions are needed, only addition, substraction, multiplication, division and square root.

The method uses three-component vectors, their Euclidean norm, and dot and cross products:

{\bar a} = (x_a, \  y_a, \  z_a)
\lVert {\bar a} \rVert = \sqrt{ x_a^2 + y_a^2 + z_a^2 }
{\bar a} \cdot {\bar b} = x_a x_b + y_a y_b + z_a z_b
{\bar a} \times {\bar b} = (y_a z_b - z_a y_b, \ z_a x_b - x_a z_b, \ x_a y_b - y_a x_b)

These are of course described in detail elsewhere in Wikipedia. Notation is not important, but for the sake of clarity, bar ({\bar p}) indicates any vector, and hat ({\hat p}) indicates a unit vector. (Unit vectors have length 1, i.e. \lVert {\hat p} \rVert = 1.)

To the problem at hand:

In general coordinates, three spheres intersect at (x, \  y, \  z) if

(x-x_1)^2+(y-y_1)^2+(z-z_1)^2=r_1^2
(x-x_2)^2+(y-y_2)^2+(z-z_2)^2=r_2^2
(x-x_3)^2+(y-y_3)^2+(z-z_3)^2=r_3^2

but it is rather hard to solve these three equations directly.

To simplify the problem, define basis vectors

\hat e_x = \frac{{\bar p}_2 - {\bar p}_1}{\lVert {\bar p}_2 - {\bar p}_1 \rVert}, \ \hat e_y = \frac{({\bar p}_3 - {\bar p}_1) - \hat e_x ( \hat e_x \cdot ( {\bar p}_3 - {\bar p}_1 ) )}{\lVert ({\bar p}_3 - {\bar p}_1) - \hat e_x ( \hat e_x \cdot ( {\bar p}_3 - {\bar p}_1 ) )\rVert}, \  \hat e_z = \hat e_x \times \hat e_y

to represent the axes of a new coordinate system. (Because there are only three points, the system is essentially planar, and we do not need the third axis, {\hat e_z}, yet.)

In this new coordinate system, you can write the three points as

{\bar p}_1 = (x_1, y_1, z_1)
{\bar p}_2 = (x_2, y_2, z_2) = {\bar p}_1 + \hat e_x h
{\bar p}_3 = (x_3, y_3, z_3) = {\bar p}_1 + \hat e_x i + \hat e_y j

where

h = \hat e_x \cdot ({\bar p}_2 - {\bar p}_1) = \lVert {\bar p}_2 - {\bar p}_1 \rVert
i = \hat e_x \cdot ({\bar p}_3 - {\bar p}_1)
j = \hat e_y \cdot ({\bar p}_3 - {\bar p}_1)

If h = 0, the first two spheres are concentric, and there can be no solution. (If the two first spheres have different radii, they cannot intersect at all. If they have the same radii, they are the same sphere.)

If j = 0, the three spheres are in line. (Oops, I guess there are two possible intersection points, {\bar p}_1 \pm r_1 {\hat e}_x, one of which may be a valid solution. I overlooked this earlier, and the test program below does not check these.)

One should probably reorder the spheres to maximize min(h, | j | ) to get a good numerical stability and accuracy. See the end of this section for the reasoning. Note that reordering the spheres does not change the result (other than via numerical stability and accuracy); just remember to reorder both the points and the radii the same way.

Using the three variables h, i, and j, with {\bar p}_1 at the origin, the system of three equations can now be written as

X^2 + Y^2 + Z^2 = r_1^2
(X - h)^2 + Y^2 + Z^2 = r_2^2
(X - i)^2 + (Y - j)^2 + Z^2 = r_3^2

and the point we are looking for is (x,y,z) = {\bar p}_1 + \hat e_x X + \hat e_y Y + \hat e_z Z in this coordinate system.

As promised, the above system of three equations is easy to solve. Substract the second equation from the first, and solve for X to get

X = \frac{r_1^2 - r_2^2 + h^2}{2 h}

Then, substract the third equation from the first, and solve for Y to get

Y = \frac{r_1^2 - r_3^2 + i^2 + j^2 - 2 i X}{2 j}

and then, using the first equation, solve for Z to get

Z = \pm \sqrt{r_1^2 - X^2 - Y^2}

In the original coordinates, the solution is

\bar p = {\bar p}_1 + \hat e_x X + \hat e_y Y \pm \hat e_z Z

Some considerations for when solutions may not exist, and when errors are large:

If h = 0, the first two spheres are concentric. If r1 = r2, they are the same sphere, so there are really just two spheres.

If {\bar p}_1 and {\bar p}_2 are very close to each other, h is very small, and any errors in the input values are magnified in X.

If {\bar p}_1, {\bar p}_2 and {\bar p}_3 are on the same line, j will be zero. One of {\bar p}_1 \pm {\hat e}_x r_1 might be a solution. If angle {\bar p}_2{\bar p}_1{\bar p}_3 is small or near 180 degrees, the correction term for basis vector \hat e_y is large, and therefore j very small compared to i; any errors in the input values are magnified in Y.

Because the order of the spheres is the only free variable (to maximize accuracy and stability with), and there are only six possible combinations, it should be enough to make sure neither h nor | j | are very small; selecting the order which gives the largest min(h, | j | ) does that. Error analysis on the equations above would show if maximizing min(h, | j | ) gives the best accuracy and numerical stability; in any case, that choice is never particularly susceptible to numerical errors because neither h nor | j | are small.

(Edited my own text for clarity, to fix a missing \rVert, and forgot to login. Several times. Sorry.) Nominal animal (talk) 16:46, 14 June 2010 (UTC)

Although I did not check all details, the concept is clear and a good improvement on the current article. Generality and avoidance of trigonometry make the solution cleaner. You would need to point out where the pathological cases are sidestepped. −Woodstone (talk) 17:10, 14 June 2010 (UTC)
The method is only generic, it does not really sidestep the pathological cases. The pathological cases are fortunately very easy to detect. One can only work around the pathological cases by reordering the spheres; for three spheres, there are only 6 possibilities: 123, 132, 213, 231, 312, and 321. I added a couple of paragraphs on the pathological cases into the middle, and expanded a bit on the problems at the very end. To verify the math and the method, compile and run the example C code I added to the next section. Nominal animal (talk) 21:55, 14 June 2010 (UTC)

[edit] Example C program

This is an enhanced version of the example program I submitted earlier. It is a lightly-tested implementation of the trilateration algorithm.

The program reads the coordinates and the radius for each sphere from standard input, then calculates the intersection point, if any.

This version handles correctly the situation where the three spheres are colinear. For example,

{\bar p}_1 = (0, \  0, \  0), \  r_1 = 1
{\bar p}_2 = (3, \  0, \  0), \  r_2 = 2
{\bar p}_3 = (9, \  0, \  0), \  r_3 = 8

which intersect at (1, \ 0, \  0).

(I tested the function with six billion intersecting but otherwise random spheres, and maxzero = 0.000000000001 \ min(r_1, r_2, r_3). All solutions were found, no false negatives were reported. The maximum relative error in the distances (compared to radii) in the solutions was less than 0.0000000001. The tests did not include any non-intersecting sphere configurations. Nominal animal (talk) 16:09, 19 June 2010 (UTC))

#include <stdio.h>
#include <math.h>
 
/* No rights reserved (CC0, see http://wiki.creativecommons.org/CC0_FAQ).
 * The author has waived all copyright and related or neighboring rights
 * to this program, to the fullest extent possible under law.
*/
 
/* Largest nonnegative number still considered zero */
#define   MAXZERO  0.0
 
typedef struct vec3d  vec3d;
struct vec3d {
        double x;
        double y;
        double z;
};
 
/* Return the difference of two vectors, (vector1 - vector2). */
vec3d vdiff(const vec3d vector1, const vec3d vector2)
{
        vec3d v;
        v.x = vector1.x - vector2.x;
        v.y = vector1.y - vector2.y;
        v.z = vector1.z - vector2.z;
        return v;
}
 
/* Return the sum of two vectors. */
vec3d vsum(const vec3d vector1, const vec3d vector2)
{
        vec3d v;
        v.x = vector1.x + vector2.x;
        v.y = vector1.y + vector2.y;
        v.z = vector1.z + vector2.z;
        return v;
}
 
/* Multiply vector by a number. */
vec3d vmul(const vec3d vector, const double n)
{
        vec3d v;
        v.x = vector.x * n;
        v.y = vector.y * n;
        v.z = vector.z * n;
        return v;
}
 
/* Divide vector by a number. */
vec3d vdiv(const vec3d vector, const double n)
{
        vec3d v;
        v.x = vector.x / n;
        v.y = vector.y / n;
        v.z = vector.z / n;
        return v;
}
 
/* Return the Euclidean norm. */
double vnorm(const vec3d vector)
{
        return sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z);
}
 
/* Return the dot product of two vectors. */
double dot(const vec3d vector1, const vec3d vector2)
{
        return vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z;
}
 
/* Replace vector with its cross product with another vector. */
vec3d cross(const vec3d vector1, const vec3d vector2)
{
        vec3d v;
        v.x = vector1.y * vector2.z - vector1.z * vector2.y;
        v.y = vector1.z * vector2.x - vector1.x * vector2.z;
        v.z = vector1.x * vector2.y - vector1.y * vector2.x;
        return v;
}
 
/* Return zero if successful, negative error otherwise.
 * The last parameter is the largest nonnegative number considered zero;
 * it is somewhat analoguous to machine epsilon (but inclusive).
*/
int trilateration(vec3d *const result1, vec3d *const result2,
                  const vec3d p1, const double r1,
                  const vec3d p2, const double r2,
                  const vec3d p3, const double r3,
                  const double maxzero)
{
        vec3d   ex, ey, ez, t1, t2;
        double h, i, j, x, y, z, t;
 
        /* h = |p2 - p1|, ex = (p2 - p1) / |p2 - p1| */
        ex = vdiff(p2, p1);
        h = vnorm(ex);
        if (h <= maxzero) {
                /* p1 and p2 are concentric. */
                return -1;
        }
        ex = vdiv(ex, h);
 
        /* t1 = p3 - p1, t2 = ex (ex . (p3 - p1)) */
        t1 = vdiff(p3, p1);
        i = dot(ex, t1);
        t2 = vmul(ex, i);
 
        /* ey = (t1 - t2), t = |t1 - t2| */
        ey = vdiff(t1, t2);
        t = vnorm(ey);
        if (t > maxzero) {
                /* ey = (t1 - t2) / |t1 - t2| */
                ey = vdiv(ey, t);
 
                /* j = ey . (p3 - p1) */
                j = dot(ey, t1);
        } else
                j = 0.0;
 
        /* Note: t <= maxzero implies j = 0.0. */
        if (fabs(j) <= maxzero) {
                /* p1, p2 and p3 are colinear. */
 
                /* Is point p1 + (r1 along the axis) the intersection? */
                t2 = vsum(p1, vmul(ex, r1));
                if (fabs(vnorm(vdiff(p2, t2)) - r2) <= maxzero &&
                    fabs(vnorm(vdiff(p3, t2)) - r3) <= maxzero) {
                        /* Yes, t2 is the only intersection point. */
                        if (result1)
                                *result1 = t2;
                        if (result2)
                                *result2 = t2;
                        return 0;
                }
 
                /* Is point p1 - (r1 along the axis) the intersection? */
                t2 = vsum(p1, vmul(ex, -r1));
                if (fabs(vnorm(vdiff(p2, t2)) - r2) <= maxzero &&
                    fabs(vnorm(vdiff(p3, t2)) - r3) <= maxzero) {
                        /* Yes, t2 is the only intersection point. */
                        if (result1)
                                *result1 = t2;
                        if (result2)
                                *result2 = t2;
                        return 0;
                }
 
                return -2;
        }
 
        /* ez = ex x ey */
        ez = cross(ex, ey);
 
        x = (r1*r1 - r2*r2) / (2*h) + h / 2;
        y = (r1*r1 - r3*r3 + i*i) / (2*j) + j / 2 - x * i / j;
        z = r1*r1 - x*x - y*y;
        if (z < -maxzero) {
                /* The solution is invalid. */
                return -3;
        } else
        if (z > 0.0)
                z = sqrt(z);
        else
                z = 0.0;
 
        /* t2 = p1 + x ex + y ey */
        t2 = vsum(p1, vmul(ex, x));
        t2 = vsum(t2, vmul(ey, y));
 
        /* result1 = p1 + x ex + y ey + z ez */
        if (result1)
                *result1 = vsum(t2, vmul(ez, z));
 
        /* result1 = p1 + x ex + y ey - z ez */
        if (result2)
                *result2 = vsum(t2, vmul(ez, -z));
 
        return 0;
}
 
int main(void)
{
        vec3d   p1, p2, p3, o1, o2;
        double r1, r2, r3;
        int    result;
 
        while (fscanf(stdin, "%lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg",
                             &p1.x, &p1.y, &p1.z, &r1,
                             &p2.x, &p2.y, &p2.z, &r2,
                             &p3.x, &p3.y, &p3.z, &r3) == 12) {
                printf("Sphere 1: %g %g %g, radius %g\n", p1.x, p1.y, p1.z, r1);
                printf("Sphere 2: %g %g %g, radius %g\n", p2.x, p2.y, p2.z, r2);
                printf("Sphere 3: %g %g %g, radius %g\n", p3.x, p3.y, p3.z, r3);
                result = trilateration(&o1, &o2, p1, r1, p2, r2, p3, r3, MAXZERO);
                if (result)
                        printf("No solution (%d).\n", result);
                else {
                        printf("Solution 1: %g %g %g\n", o1.x, o1.y, o1.z);
                        printf("  Distance to sphere 1 is %g (radius %g)\n", vnorm(vdiff(o1, p1)), r1);
                        printf("  Distance to sphere 2 is %g (radius %g)\n", vnorm(vdiff(o1, p2)), r2);
                        printf("  Distance to sphere 3 is %g (radius %g)\n", vnorm(vdiff(o1, p3)), r3);
                        printf("Solution 2: %g %g %g\n", o2.x, o2.y, o2.z);
                        printf("  Distance to sphere 1 is %g (radius %g)\n", vnorm(vdiff(o2, p1)), r1);
                        printf("  Distance to sphere 2 is %g (radius %g)\n", vnorm(vdiff(o2, p2)), r2);
                        printf("  Distance to sphere 3 is %g (radius %g)\n", vnorm(vdiff(o2, p3)), r3);
                }
        }
 
        return 0;
}

Note that the trilateration() function takes an extra parameter, maxzero, which is the largest nonnegative number still considered zero.

By default maxzero = 0, which is too small to find the solution in some cases. Something like min(r_1, r_2, r_3) \cdot 0.0000001 should work well with double precision floating-point numbers.

If best precision is desired, the trilateration() function should be modified to return min(h,fabs(j)) instead of zero when successful. Call the function with each of the six sphere order permutations, with maxzero = 0, and select the result which corresponds the largest return value; this should have the least numerical instability.

If all six calls return negative, set maxzero to, say, maxzero = min(r1,r2,r3) / 100, and retry. If these calls also fail, there is no solution. Otherwise, use e.g. binary search (halving maxzero each round) to find the smallest working maxzero. Select the result with corresponds to the largest return value (using the smallest working maxzero).

The function is unoptimized, but still rather cheap: on an Athlon64, each call to the trilateration() function takes roughly 2000 - 6000 clock cycles. Nominal animal (talk) 18:58, 18 June 2010 (UTC)

[edit] Real improvement to preliminary computation section by User:Nominal animal

Nominal animal's recent edit to the Preliminary computation section of the trilateration article appears to be a very good simplification. Thank you for a useful contribution. RHB100 (talk) 21:54, 17 June 2010 (UTC)

Thanks! Also, thank you for the language cleanup; English is obviously not my native language. Nominal animal (talk) 16:04, 19 June 2010 (UTC)
Personal tools
Namespaces
Variants
Actions
Navigation
Interaction
Toolbox
Print/export