Permalink
Browse files

better vector handling

  • Loading branch information...
kristianmandrup committed May 6, 2011
1 parent 12ef60c commit 4d9fdadcb6cfe51b24a54b7ddc3dc47053f2220a
View
@@ -10,6 +10,7 @@ module GeoMagic
require 'geo_magic/remote'
require 'geo_magic/calculate'
require 'geo_magic/distance'
+require 'geo_magic/direction'
require 'geo_magic/radius'
require 'geo_magic/vector'
require 'geo_magic/meta'
View
@@ -1,6 +1,6 @@
require 'geo_magic/calculate'
require 'geo_magic/distance/class_methods'
-require 'geo_magic/distance/vector'
+require 'geo_magic/vector/distance_vector'
require 'geo_magic/distance/formula'
require 'geo_magic/distance/point_distance'
require 'geo_magic/distance/points_distance'
@@ -43,7 +43,15 @@ def #{op} dist_unit
end
}
end
-
+
+ # from(@low_left, :NW)
+ def from point, direction
+ raise ArgumentError, "Invalid direction: #{direction}" if !valid_directions.include?(direction)
+ raise ArgumentError, "First argument must be a GeoMagic::Point, was: #{point}" if !point.kind_of?(GeoMagic::Point)
+ vector = GeoMagic::Vector.in_direction(direction, self)
+ point.move_vector(vector)
+ end
+
def number
distance.round_to(precision[unit])
end
@@ -1,124 +0,0 @@
-require 'sugar-high/kind_of'
-
-# This can be used to indicate a rectangle, with a latitude and logitude distance from the center in both directions to span out the rectangle.
-
-module GeoMagic
- class Distance
- class Vector
- attr_accessor :lat_distance, :long_distance, :lat_factor
-
- # should be Distance objects!
- def initialize lat_distance, long_distance, options = {}
- raise ArgumentError, "lat and long distance arguments must be instances of GeoMagic::Distance, was: #{lat_distance} #{long_distance}" if ![long_distance, lat_distance].only_kinds_of? GeoMagic::Distance
- @lat_distance = lat_distance
- @long_distance = long_distance
- @lat_factor = options[:lat_factor] || 1
- end
-
- def * arg
- multiply arg
- end
-
- def / arg
- multiply(1/arg)
- end
-
- def multiply arg
- vect_dist = new lat_distance.clone, long_distance.clone
- vect_dist.multiply! arg
- end
-
- def multiply! arg
- factors = case arg
- when Numeric
- [arg, arg]
- when Hash
- [factor(arg, lat_symbols), factor(arg, long_symbols)]
- else
- raise ArgumentError, "Argument must be a Fixnum or a Hash specifying factor to multiply latitude and/or longitude with, was #{arg.class}"
- end
- multiply_lat factors.first
- multiply_long factors.last
- self
- end
-
- def multiply_lat arg
- check_numeric! arg
- self.lat_distance *= arg
- end
-
- def multiply_long arg
- check_numeric! arg
- self.long_distance *= arg
- end
-
- def radius center
- GeoMagic::Radius.send :"create_rectangular", center, self
- end
-
- def to_s
- "distances: (lat: #{lat_distance}, long: #{long_distance})"
- end
-
- protected
-
- def check_numeric! arg
- raise ArgumentError, "Argument must be Numeric" if !arg.is_a? Numeric
- end
-
- include GeoMagic::GeoSymbols
-
- class << self
-
- include GeoMagic::GeoSymbols
-
- # should create distance vector from 2 points
- def create_from *args
- case args.size
- when 1
- extract_from_single args.first
- when 2
- new *args
- else
- raise ArgumentError, "Too many arguments! #{args}"
- end
- end
-
- protected
-
- def extract_from_single arg
- case arg
- when GeoMagic::Distance::Vector
- arg
- when GeoMagic::Distance
- new arg.clone, arg.clone
- else
- new *extract_from_hash(arg.clone)
- end
- end
-
- def extract_from_hash hash
- raise ArgumentError, "single argument must be a hash" if !hash.kind_of? Hash
- [lat_dist(hash), long_dist(hash)]
- end
-
- def lat_dist hash
- sym = lat_symbols.select {|s| hash[s].kind_of? GeoMagic::Distance }.first
- raise ArgumentError, "latitude could not be extracted from hash" if !sym
- hash[sym]
- end
-
- def long_dist hash
- sym = long_symbols.select {|s| hash[s].kind_of? GeoMagic::Distance }.first
- raise ArgumentError, "longitude could not be extracted from hash" if !sym
- hash[sym]
- end
- end
-
- def factor hash, symbols
- s = symbols.select {|s| hash[s].is_a? Numeric }
- s.empty? ? 1 : hash[s]
- end
- end
- end
-end
@@ -4,8 +4,8 @@ class RectangularRadius < Radius
def initialize center_point, vector_distance
super center_point
- vector_distance = GeoMagic::Distance::Vector.create_from vector_distance
- raise ArgumentError, "#{self.class} radius distance must be a Distance::Vector with lat and long distance" if !vector_distance.kind_of? GeoMagic::Distance::Vector
+ vector_distance = GeoMagic::DistanceVector.create_from vector_distance
+ raise ArgumentError, "#{self.class} radius distance must be a GeoMagic::DistanceVector with lat and long distance" if !vector_distance.kind_of? GeoMagic::DistanceVector
@vector_distance = vector_distance
end
View
@@ -1,85 +1,17 @@
module GeoMagic
- class Vector
- attr_accessor :p0, :p1
-
- def initialize p0, p1
- raise ArgumentError, "Vector must be initialized with a start end ending point, was: #{p0}, #{p1}" if ![p0, p1].are_points?
- @p0 = p0
- @p1 = p1
- end
-
- def self.create_at center, vector
- new center, center.move_vector(vector)
- end
-
- def length type = nil
- rad_dist = case type
- when nil
- GeoMagic::Distance.distance(p0, p1)
- when :latitude
- (p0.latitude - p1.latitude).abs
- when :longitude
- (p0.longitude - p1.longitude).abs
- else
- raise ArgumentError, "Bad argument for calculating lenght, valid args are: nil, :latitude or :longitude"
+ class Vector
+ # The vector from the origin O = (0,0) to the point A = (2,3) is simply written as (2,3).
+ def apply_to arg
+ def apply_to arg
+ raise ArgumentError, "Argument must be a GeoMagic::Point or a GeoMagic::PointVector" if !arg.any_kind_of?(GeoMagic::Vector, GeoMagic::PointVector)
+ case arg
+ when GeoMagic::Point
+ when GeoMagic::PointVector
+ end
end
- d = GeoMagic::Distance.new rad_dist, :radians
- d.lat_factor = p0.middle_point(p1).latitude_factor if type == :latitude
- d
- end
-
- def lat_distance
- length(:latitude).in_radians
end
-
- def long_distance
- length(:longitude).in_radians
- end
-
- def vector_distance
- GeoMagic::Distance::Vector.new length(:latitude), length(:longitude), :lat_factor => lat_factor
- end
-
- def lat_factor
- p0.middle_point(p1).latitude_factor
- end
-
- # distance between points p0 and p1 that define the vector
-
- def distance unit = :radians
- dist = ::GeoMagic::Distance.calculate p0, p1
- unit != :radians ? dist[unit] : dist
- end
-
- def distance_from center, unit = :meters
- point = center.move delta_latitude, delta_longitude
- dist = ::GeoMagic::Distance.calculate center, point
- unit != :radians ? dist[unit] : dist
- end
-
- def [] key
- case key
- when 0, :p0
- p0
- when 1, :p1
- p1
- else
- raise "Vector key must be either 0/1 or :p0/:p1"
- end
- end
-
- protected
-
- def connection_length
- Math.sqrt((delta_longitude + delta_latitude).abs)
- end
-
- def delta_longitude
- (p0.longitude - p1.longitude)**2
- end
-
- def delta_latitude
- (p0.latitude - p1.latitude)**2
- end
end
end
+
+require 'geo_magic/vector/point_vector'
+require 'geo_magic/vector/direction_vector'
@@ -0,0 +1,59 @@
+module GeoMagic
+ module Direction
+ class Vector < GeoMagic::Vector
+ attr_accessor :direction, :distance
+
+ def initialize direction, distance
+ raise ArgumentError, "Invalid direction: #{direction}" if !valid_directions.include?(direction)
+ raise ArgumentError, "First argument must be a GeoMagic::Distance, was: #{distance}" if !distance.kind_of?(GeoMagic::Distance)
+ @direction = direction
+ @distance = distance
+ end
+
+ def self.valid_directions
+ [:north, :south, :east, :west, :NW, :NE, :SW, :SE]
+ end
+
+ def to_point_vector
+ GeoMagic::PointVector.from_origin calc_point
+ end
+
+ def apply_to arg
+ raise ArgumentError, "Argument must be a GeoMagic::Point or a GeoMagic::PointVector" if !arg.any_kind_of?(GeoMagic::Vector, GeoMagic::PointVector)
+ case arg
+ when GeoMagic::Point
+ when GeoMagic::PointVector
+ end
+ end
+
+ protected
+
+ def calc_point
+ va = 45
+ c = distance
+ a = c * 0.7071067770164218 # Math.sin(45 * Math.PI / 180);
+ b = Math.sqrt((c * c) - (a * a));
+
+ lat, lng = case direction
+ when :north
+ [0, -distance]
+ when :south
+ [0, distance]
+ when :west
+ [-distance, 0]
+ when :east
+ [distance, 0]
+ when :NW
+ [a, b]
+ when :SW
+ [a, -b]
+ when :NE
+ [-a, b]
+ when :SE
+ [-a, -b]
+ end
+ GeoMagic::Point.new lat, lng
+ end
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit 4d9fdad

Please sign in to comment.