Vector Reference¶
Geodetic::Vector represents a geodetic displacement — a combination of distance (magnitude) and bearing (direction). It is the fundamental type for expressing "how far and which way" between two points on Earth.
A Vector solves the Vincenty direct problem: given an origin point, a bearing, and a distance, compute the destination point on the WGS84 ellipsoid.
Constructor¶
# From numeric values (meters and degrees)
v = Geodetic::Vector.new(distance: 10_000, bearing: 90.0)
# From Distance and Bearing objects
v = Geodetic::Vector.new(
distance: Geodetic::Distance.km(10),
bearing: Geodetic::Bearing.new(90.0)
)
Numeric arguments are automatically coerced: distance wraps into Distance.new(value) and bearing wraps into Bearing.new(value).
Attributes¶
| Attribute | Type | Description |
|---|---|---|
distance |
Distance | The magnitude of the vector |
bearing |
Bearing | The direction of the vector (0-360 degrees from north) |
Components¶
A Vector decomposes into north/east components in meters, treating bearing as an angle measured clockwise from north.
| Method | Returns | Description |
|---|---|---|
north |
Float | North component: distance * cos(bearing) |
east |
Float | East component: distance * sin(bearing) |
v = Geodetic::Vector.new(distance: 1000, bearing: 45.0)
v.north # => 707.107 (meters north)
v.east # => 707.107 (meters east)
A due-north vector has a full north component and zero east component. A due-east vector has zero north and full east.
Factory Methods¶
Vector.from_components(north:, east:)¶
Reconstruct a Vector from north/east components in meters.
v = Geodetic::Vector.from_components(north: 1000, east: 0)
v.bearing.degrees # => 0.0 (due north)
v.distance.meters # => 1000.0
Near-zero magnitudes (< 1e-9 meters) snap to a clean zero vector to avoid floating-point artifacts.
Vector.from_segment(segment)¶
Create a Vector from an existing Segment's length and bearing.
seg = Geodetic::Segment.new(seattle, portland)
v = Geodetic::Vector.from_segment(seg)
v.distance.meters # => same as seg.length_meters
v.bearing.degrees # => same as seg.bearing.degrees
Also available as segment.to_vector.
Vincenty Direct¶
destination_from(origin)¶
Given an origin coordinate, compute the destination point by traveling the vector's distance along the vector's bearing. Uses the full Vincenty direct formula on the WGS84 ellipsoid.
v = Geodetic::Vector.new(distance: 100_000, bearing: 45.0)
dest = v.destination_from(seattle) # => LLA 100km northeast of Seattle
Accepts any coordinate type — non-LLA inputs are converted automatically. A zero-distance vector returns the origin unchanged.
Round-trip accuracy:
v = Geodetic::Vector.new(distance: 50_000, bearing: 135.0)
dest = v.destination_from(origin)
origin.distance_to(dest).meters # => 50000.0 (within ~1 meter)
Arithmetic¶
Vector arithmetic uses north/east component decomposition. The result is always a new Vector.
Vector + Vector¶
Component-wise addition. Combines two displacements into a single resultant vector.
north = Geodetic::Vector.new(distance: 1000, bearing: 0.0)
east = Geodetic::Vector.new(distance: 1000, bearing: 90.0)
result = north + east
result.bearing.degrees # => 45.0
result.distance.meters # => 1414.21
Vector - Vector¶
Component-wise subtraction.
Vector * Scalar¶
Scales the distance. Negative scalars reverse the bearing.
v = Geodetic::Vector.new(distance: 1000, bearing: 45.0)
(v * 3).distance.meters # => 3000.0, bearing 45
(v * -1).bearing.degrees # => 225.0 (reversed)
Scalar * Vector also works via coerce:
Vector / Scalar¶
Scales the distance down. Raises ZeroDivisionError for zero. Negative divisors reverse the bearing.
Unary Minus¶
Same distance, reversed bearing.
Identity: V + (-V)¶
Opposite vectors cancel to zero:
Products¶
dot(other)¶
Scalar dot product using north/east components. Returns a Float.
north = Geodetic::Vector.new(distance: 100, bearing: 0.0)
east = Geodetic::Vector.new(distance: 100, bearing: 90.0)
north.dot(north) # => 10000.0 (parallel)
north.dot(east) # => 0.0 (perpendicular)
cross(other)¶
2D cross product (scalar). Returns a Float. Positive means other is to the left of self.
angle_between(other)¶
Returns a Bearing representing the angular difference.
north = Geodetic::Vector.new(distance: 100, bearing: 0.0)
east = Geodetic::Vector.new(distance: 100, bearing: 90.0)
north.angle_between(east).degrees # => 90.0
Properties¶
| Method | Returns | Description |
|---|---|---|
magnitude |
Float | Distance in meters |
zero? |
Boolean | True if distance is zero |
normalize |
Vector | Unit vector (1 meter) in the same bearing |
reverse |
Vector | Same distance, opposite bearing (alias for -self) |
inverse |
Vector | Alias for reverse |
v = Geodetic::Vector.new(distance: 5000, bearing: 135.0)
v.magnitude # => 5000.0
v.normalize.magnitude # => 1.0
v.reverse.bearing.degrees # => 315.0
Comparison¶
Vectors include Comparable, ordered by distance (magnitude). Two vectors are equal (==) only if both distance and bearing match.
short = Geodetic::Vector.new(distance: 100, bearing: 0.0)
long = Geodetic::Vector.new(distance: 200, bearing: 0.0)
short < long # => true
# Same magnitude, different bearing
a = Geodetic::Vector.new(distance: 100, bearing: 0.0)
b = Geodetic::Vector.new(distance: 100, bearing: 90.0)
(a <=> b) == 0 # => true (same magnitude)
a == b # => false (different bearing)