# Points

A point is a 2D or 3D object that has a location, but no surface, or volume. An `OrientedPoint` is a point with an orientation. This orientation describes the rotations, relative to the reference orientation of the object, that must be applied to draw an object at its location.

In the code examples below, please note that the djutils `Point2d` class is written with a lower-case `d`; unlike the `Point2D` class in `java.awt.geom`.

To create a 2D point and print it write:

``````    Point2d point2d = new Point2d(123.45, 234.56);
System.out.println(point2d);``````

This outputs:

```Point2d [x=123.450000, y=234.560000]
```

The individual coordinates can be retrieved by calling the `getX` and `getY` methods, but they are also directly accessible as `point2d.x` and `point2d.y`. The latter ways are not significantly better or faster, but your source code tends to be shorter and more readable and, when debugging the code, the debugger will not have to step into those getters.

Like all `Drawable` objects the `Point2d` class also implements the `getPoints` method which creates an `Iterator<Point2d>` that generates all points of the object in sequence. For a `Point` that `Iterator` will only provide one object. The `Point2d` object also implements the `getBounds` method that creates a `Bounds2d` object.

There are three constructors for `Point2d` objects:

``````    Point2d point1 = new Point2d(123.45, 234.56);
System.out.println(point1);
double[] coordinates = new double[] { 123.45, 234.56 };
Point2d point2 = new Point2d(coordinates);
System.out.println(point2);
java.awt.geom.Point2D awtPoint2D = new java.awt.geom.Point2D.Double(123.45, 234.56);
Point2d point3 = new Point2d(awtPoint2D);
System.out.println(point3);
java.awt.geom.Point2D awtPoint2DCopy = point3.toPoint2D();
System.out.println(awtPoint2DCopy);``````

Outputs:

```Point2d [x=123.450000, y=234.560000]
Point2d [x=123.450000, y=234.560000]
Point2d [x=123.450000, y=234.560000]
```

That last example created a djutils `Point2d` object from a `java.awt.geom.Point2D` object. The inverse is also possible:

``    java.awt.geom.Point2D awtPoint2DCopy = point2d.toPoint2D();``

Which outputs:

```Point2D.Double[123.45, 234.56]
```

With two Point2d objects many operations become possible:

``````    Point2d point2d = new Point2d(123.45, 234.56);
Point2d secondPoint2d = new Point2d(234.56, 345.78);
System.out.println("Direction to: " + point2d.directionTo(secondPoint2d));
System.out.println("Distance: " + point2d.distance(secondPoint2d));
System.out.println("Distance squared " + point2d.distanceSquared(secondPoint2d));
System.out.println("Interpolation at fraction 0.3: " + point2d.interpolate(secondPoint2d, 0.3));``````

This outputs:

```Direction to: 0.7858929233984577
Distance: 157.21106990285384
Distance squared 24715.320499999994
Interpolation at fraction 0.3: Point2d [x=156.783000, y=267.926000]
```

The direction is in radians where the X-axis direction is 0, and the Y-axis direction is π/2; etc. The distance is computed using the `Math.hypot` method; this suffers less from loss of precision problems than taking the square root of the squares of the x-difference and the y-difference. The `distanceSquared` is the sum of the squares of the differences in x and y. The interpolate method can just as easy perform extrapolation. When the fraction (`0.3` in the example) is `0.0`; a new `Point2d` at the same location the existing `Point2d` is created. fraction `1.0` returns a new `Point2d` at the location of `secondPoint2d`. Fraction `-1.0` creates a new `Point2d` that is the distance between the points before `point2d`; etc.

Computations with double precision coordinates generally leads to rounding errors. In some cases it is necessary to compare points allowing for some loss of precision. This can be done with the `epsilonEquals` method:

``````    Point2d point1 = new Point2d(123.45, 234.56);
System.out.println("Almost equals to another Point2d: " + point1.epsilonEquals(new Point2d(123, 235), 0.5));``````

This example prints:

```Almost equals to another Point2d: true
```

A Point can not be modified (it is immutable), but there are various methods that create a translated, normalized, or scaled version of a Point.

``````    System.out.println("The point: " + point1);
System.out.println("The point translated over 10, -20: " + point1.translate(10, -20));
System.out.println("The point scaled by 2: " + point1.scale(2.0));
System.out.println("The point negated: " + point1.neg());
System.out.println("The point normalized: " + point1.normalize());
System.out.println("The point with absolute values: " + point1.abs());
System.out.println("The point negated, then absolute: " + point1.neg().abs());``````

Output:

```The point: Point2d [x=123.450000, y=234.560000]
The point translated over 10, -20: Point2d [x=133.450000, y=214.560000]
The point scaled by 2: Point2d [x=246.900000, y=469.120000]
The point negated: Point2d [x=-123.450000, y=-234.560000]
The point normalized: Point2d [x=0.465739, y=0.884922]
The point with absolute values: Point2d [x=123.450000, y=234.560000]
The point negated, then absolute: Point2d [x=123.450000, y=234.560000]
```

A Point2d has two directly accessible fields: `x` and `y`. There are also getters for these: `getX()` and `getY()`. Using the former access method leads to slightly shorter code with fewer parenthesis. When stepping through code with a debugger, using the former makes life a bit easier. With modern compilers, we do not believe there is a runtime speed advantage in using the fields directly.

A `Point3d` is a `Point` with three coordinates (x, y, z). A `Point3d` is very similar to a `Point2d`. The main difference is that everything is done with three coordinates. The `directionTo` method does not make much sense. It is replaced by two methods: `horizontalDirection` (the angle from the X-axis) and `verticalDirection` (the angle from the Z-axis). The z coordinate can be accessed directly as the `z` field, or with the `getZ()` getter method.

An `OrientedPoint2d` is a `Point2d` with an direction value. This direction is a rotation from the X-axis. The X-axis has rotation `0`, the Y-axis has rotation `π/2`, etc.. The rotation of the `OrientedPoint2d` is totally independent of the `x` and `y` values. The rotation can be retrieved by directly accessing the `dirZ` field, or calling the `getDirZ()` method. An `OrientedPoint2d` can be used to describe the position and rotation of an object in 2D-space.

``````    OrientedPoint2d orientedPoint2d = new OrientedPoint2d(123.45, 234.56, -0.2);
System.out.println(orientedPoint2d);``````

Prints

```OrientedPoint2d [x=123.450000, y=234.560000, rot=-0.200000]
```

There is also an `OrientedPoint3d` class. This object stores x, y, z, dirX, dirY, dirZ. The `dirZ` property is exactly like the `dirZ` property of an OrientedPoint2d. The `dir` values can be interpreted as `roll`, `pitch` and `jaw`. There are several such naming conventions depending on the field of use: see Wikipedia It is important to understand that combining rotations is not commutative. The `OriendedPoint3d` class does not define the order in which these rotations are to be applied. When you use `Oriented` points in a project, you should clearly document the ordering that your project uses.