Class: RGeo::Geographic::SphericalMath::PointXYZ
- Inherits:
-
Object
- Object
- RGeo::Geographic::SphericalMath::PointXYZ
- 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.
Constant Summary collapse
- P1 =
new(1, 0, 0)
- P2 =
new(0, 1, 0)
Instance Attribute Summary collapse
-
#x ⇒ Object
readonly
Returns the value of attribute x.
-
#y ⇒ Object
readonly
Returns the value of attribute y.
-
#z ⇒ Object
readonly
Returns the value of attribute z.
Class Method Summary collapse
Instance Method Summary collapse
- #%(rhs_) ⇒ Object
- #*(rhs_) ⇒ Object
-
#create_perpendicular ⇒ Object
Creates some point that is perpendicular to this point.
- #dist_to_point(rhs_) ⇒ Object
- #eql?(rhs_) ⇒ Boolean (also: #==)
-
#initialize(x_, y_, z_) ⇒ PointXYZ
constructor
:nodoc:.
- #latlon ⇒ Object
- #lonlat ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(x_, y_, z_) ⇒ PointXYZ
:nodoc:
24 25 26 27 28 29 30 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 24 def initialize(x_, y_, z_) r_ = ::Math.sqrt(x_ * x_ + y_ * y_ + z_ * z_) @x = (x_ / r_).to_f @y = (y_ / r_).to_f @z = (z_ / r_).to_f raise "Not a number" if @x.nan? || @y.nan? || @z.nan? end |
Instance Attribute Details
#x ⇒ Object (readonly)
Returns the value of attribute x.
36 37 38 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 36 def x @x end |
#y ⇒ Object (readonly)
Returns the value of attribute y.
37 38 39 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 37 def y @y end |
#z ⇒ Object (readonly)
Returns the value of attribute z.
38 39 40 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 38 def z @z end |
Class Method Details
.from_latlon(lat_, lon_) ⇒ Object
111 112 113 114 115 116 117 118 119 120 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 111 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 |
.weighted_combination(p1_, w1_, p2_, w2_) ⇒ Object
122 123 124 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 122 def self.weighted_combination(p1_, w1_, p2_, w2_) new(p1_.x * w1_ + p2_.x * w2_, p1_.y * w1_ + p2_.y * w2_, p1_.z * w1_ + p2_.z * w2_) end |
Instance Method Details
#%(rhs_) ⇒ Object
74 75 76 77 78 79 80 81 82 83 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 74 def %(rhs_) rx_ = rhs_.x ry_ = rhs_.y rz_ = rhs_.z begin PointXYZ.new(@y * rz_ - @z * ry_, @z * rx_ - @x * rz_, @x * ry_ - @y * rx_) rescue nil end end |
#*(rhs_) ⇒ Object
67 68 69 70 71 72 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 67 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 |
#create_perpendicular ⇒ Object
Creates some point that is perpendicular to this point
103 104 105 106 107 108 109 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 103 def create_perpendicular p1dot_ = self * P1 p2dot_ = self * P2 p1dot_ = -p1dot_ if p1dot_ < 0 p2dot_ = -p2dot_ if p2dot_ < 0 p1dot_ < p2dot_ ? (self % P1) : (self % P2) end |
#dist_to_point(rhs_) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 85 def dist_to_point(rhs_) rx_ = rhs_.x ry_ = rhs_.y rz_ = rhs_.z dot_ = @x * rx_ + @y * ry_ + @z * rz_ if dot_ > -0.8 && dot_ < 0.8 ::Math.acos(dot_) else x_ = @y * rz_ - @z * ry_ y_ = @z * rx_ - @x * rz_ z_ = @x * ry_ - @y * rx_ as_ = ::Math.asin(::Math.sqrt(x_ * x_ + y_ * y_ + z_ * z_)) dot_ > 0.0 ? as_ : ::Math::PI - as_ end end |
#eql?(rhs_) ⇒ Boolean Also known as: ==
40 41 42 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 40 def eql?(rhs_) rhs_.is_a?(PointXYZ) && @x == rhs_.x && @y == rhs_.y && @z == rhs_.z end |
#latlon ⇒ Object
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 45 def latlon lat_rad_ = ::Math.asin(@z) lon_rad_ = begin ::Math.atan2(@y, @x) rescue 0.0 end rpd_ = ImplHelper::Math::RADIANS_PER_DEGREE [lat_rad_ / rpd_, lon_rad_ / rpd_] end |
#lonlat ⇒ Object
56 57 58 59 60 61 62 63 64 65 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 56 def lonlat lat_rad_ = ::Math.asin(@z) lon_rad_ = begin ::Math.atan2(@y, @x) rescue 0.0 end rpd_ = ImplHelper::Math::RADIANS_PER_DEGREE [lon_rad_ / rpd_, lat_rad_ / rpd_] end |
#to_s ⇒ Object
32 33 34 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 32 def to_s "(#{@x}, #{@y}, #{@z})" end |