Class: RGeo::Geographic::SphericalMath::PointXYZ

Inherits:
Object
  • Object
show all
Defined in:
lib/rgeo/geographic/spherical_math.rb

Overview

Represents a point on the unit sphere in (x,y,z) coordinates instead of lat-lon. This form is often faster, more convenient, and more numerically stable for certain computations.

The coordinate system is a right-handed system where the z-axis goes through the north pole, the x-axis goes through the prime meridian, and the y-axis goes through +90 degrees longitude.

This object is also used to represent a great circle, as its axis of rotation.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x_, y_, z_) ⇒ PointXYZ

:nodoc:



60
61
62
63
64
65
66
# File 'lib/rgeo/geographic/spherical_math.rb', line 60

def initialize(x_, y_, z_)
  r_ = ::Math.sqrt(x_ * x_ + y_ * y_ + z_ * z_)
  @x = x_ / r_
  @y = y_ / r_
  @z = z_ / r_
  raise "Not a number" if @x.nan? || @y.nan? || @z.nan?
end

Instance Attribute Details

#xObject (readonly)

Returns the value of attribute x.



74
75
76
# File 'lib/rgeo/geographic/spherical_math.rb', line 74

def x
  @x
end

#yObject (readonly)

Returns the value of attribute y.



75
76
77
# File 'lib/rgeo/geographic/spherical_math.rb', line 75

def y
  @y
end

#zObject (readonly)

Returns the value of attribute z.



76
77
78
# File 'lib/rgeo/geographic/spherical_math.rb', line 76

def z
  @z
end

Class Method Details

.from_latlon(lat_, lon_) ⇒ Object



122
123
124
125
126
127
128
129
130
131
# File 'lib/rgeo/geographic/spherical_math.rb', line 122

def self.from_latlon(lat_, lon_)
  rpd_ = ImplHelper::Math::RADIANS_PER_DEGREE
  lat_rad_ = rpd_ * lat_
  lon_rad_ = rpd_ * lon_
  z_ = ::Math.sin(lat_rad_)
  r_ = ::Math.cos(lat_rad_)
  x_ = ::Math.cos(lon_rad_) * r_
  y_ = ::Math.sin(lon_rad_) * r_
  new(x_, y_, z_)
end

Instance Method Details

#%(rhs_) ⇒ Object



101
102
103
104
105
106
# File 'lib/rgeo/geographic/spherical_math.rb', line 101

def %(rhs_)
  rx_ = rhs_.x
  ry_ = rhs_.y
  rz_ = rhs_.z
  PointXYZ.new(@y*rz_-@z*ry_, @z*rx_-@x*rz_, @x*ry_-@y*rx_) rescue nil
end

#*(rhs_) ⇒ Object



93
94
95
96
97
98
# File 'lib/rgeo/geographic/spherical_math.rb', line 93

def *(rhs_)
  val_ = @x * rhs_.x + @y * rhs_.y + @z * rhs_.z
  val_ = 1.0 if val_ > 1.0
  val_ = -1.0 if val_ < -1.0
  val_
end

#dist_to_point(rhs_) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/rgeo/geographic/spherical_math.rb', line 109

def dist_to_point(rhs_)
  rx_ = rhs_.x
  ry_ = rhs_.y
  rz_ = rhs_.z
  x_ = @y*rz_-@z*ry_
  y_ = @z*rx_-@x*rz_
  z_ = @x*ry_-@y*rx_
  r_ = ::Math.sqrt(x_*x_ + y_*y_ + z_*z_)
  r_ = 1.0 if r_ > 1.0
  ::Math.asin(r_)
end

#eql?(rhs_) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)


79
80
81
# File 'lib/rgeo/geographic/spherical_math.rb', line 79

def eql?(rhs_)
  rhs_.kind_of?(PointXYZ) && @x == rhs_.x && @y == rhs_.y && @z == rhs_.z
end

#latlonObject



85
86
87
88
89
90
# File 'lib/rgeo/geographic/spherical_math.rb', line 85

def latlon
  lat_rad_ = ::Math.asin(@z)
  lon_rad_ = ::Math.atan2(@y, @x) rescue 0.0
  rpd_ = ImplHelper::Math::RADIANS_PER_DEGREE
  [lat_rad_ / rpd_, lon_rad_ / rpd_]
end

#to_sObject



69
70
71
# File 'lib/rgeo/geographic/spherical_math.rb', line 69

def to_s
  "(#{@x}, #{@y}, #{@z})"
end