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
:nodoc:.
-
#y ⇒ Object
readonly
:nodoc:.
-
#z ⇒ Object
readonly
:nodoc:.
Class Method Summary collapse
Instance Method Summary collapse
- #%(other) ⇒ Object
- #*(other) ⇒ Object
-
#create_perpendicular ⇒ Object
Creates some point that is perpendicular to this point.
- #dist_to_point(rhs) ⇒ Object
- #eql?(other) ⇒ Boolean (also: #==)
-
#initialize(x, y, z) ⇒ PointXYZ
constructor
A new instance of PointXYZ.
- #latlon ⇒ Object
- #lonlat ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(x, y, z) ⇒ PointXYZ
Returns a new instance of PointXYZ.
28 29 30 31 32 33 34 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 28 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)
:nodoc:
26 27 28 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 26 def x @x end |
#y ⇒ Object (readonly)
:nodoc:
26 27 28 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 26 def y @y end |
#z ⇒ Object (readonly)
:nodoc:
26 27 28 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 26 def z @z end |
Class Method Details
.from_latlon(lat, lon) ⇒ Object
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 103 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(pt1, wt1, pt2, wt2) ⇒ Object
114 115 116 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 114 def self.weighted_combination(pt1, wt1, pt2, wt2) new(pt1.x * wt1 + pt2.x * wt2, pt1.y * wt1 + pt2.y * wt2, pt1.z * wt1 + pt2.z * wt2) end |
Instance Method Details
#%(other) ⇒ Object
66 67 68 69 70 71 72 73 74 75 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 66 def %(other) rx = other.x ry = other.y rz = other.z begin PointXYZ.new(@y * rz - @z * ry, @z * rx - @x * rz, @x * ry - @y * rx) rescue StandardError nil end end |
#*(other) ⇒ Object
59 60 61 62 63 64 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 59 def *(other) val = @x * other.x + @y * other.y + @z * other.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
95 96 97 98 99 100 101 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 95 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
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 77 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?(other) ⇒ Boolean Also known as: ==
40 41 42 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 40 def eql?(other) other.is_a?(PointXYZ) && @x == other.x && @y == other.y && @z == other.z end |
#latlon ⇒ Object
45 46 47 48 49 50 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 45 def latlon lat_rad = Math.asin(@z) lon_rad = Math.atan2(@y, @x) rpd = ImplHelper::Math::RADIANS_PER_DEGREE [lat_rad / rpd, lon_rad / rpd] end |
#lonlat ⇒ Object
52 53 54 55 56 57 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 52 def lonlat lat_rad = Math.asin(@z) lon_rad = Math.atan2(@y, @x) rpd = ImplHelper::Math::RADIANS_PER_DEGREE [lon_rad / rpd, lat_rad / rpd] end |
#to_s ⇒ Object
36 37 38 |
# File 'lib/rgeo/geographic/spherical_math.rb', line 36 def to_s "(#{@x}, #{@y}, #{@z})" end |