laptimer-geometry 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Geometry do
4
+ it "should calculate the distance using the Earth radius Nelson Piquet" do
5
+ point1 = {:x => -47.900648, :y => -15.772954}
6
+ point2 = {:x => -47.900365, :y => -15.772869}
7
+ point3 = {:x => -47.90025, :y => -15.772835}
8
+ Geometry.calculate_spherical_distance(point1, point2).should be_true
9
+ Geometry.calculate_spherical_distance(point1, point3).should be_true
10
+ end
11
+
12
+ it "should find the exact distance between 2 points on the earth" do
13
+ point1 = {:x => -47.900331, :y => -15.77284}
14
+ point2 = {:x => -47.897064, :y => -15.77171}
15
+ distance = Geometry.calculate_spherical_distance(point1, point2)
16
+ distance.should be_within(0.001).of(0.372) # in Km
17
+ end
18
+ end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require File.expand_path('../../src/geometry', __FILE__)
3
2
 
4
3
  describe Line do
5
4
  before do
@@ -112,14 +111,6 @@ describe Line do
112
111
  flag_line.intercept_line_segment?(segment1).should be_false
113
112
  end
114
113
 
115
- it "should calculate the distance using the Earth radius Nelson Piquet" do
116
- point1 = {:x => -47.900648, :y => -15.772954}
117
- point2 = {:x => -47.900365, :y => -15.772869}
118
- point3 = {:x => -47.90025, :y => -15.772835}
119
- Geometry.calculate_distance(point1, point2).should be_true
120
- Geometry.calculate_distance(point1, point3).should be_true
121
- end
122
-
123
114
  it "should find the crossing segment with some real coordinates - Aut. Nelson Piquet" do
124
115
  flag_line = Line.new({:x => -47.900333, :y => -15.772656, }, {:x => -47.900148, :y => -15.773056})
125
116
  segment1 = Line.new({:x => -47.900648, :y => -15.772954}, {:x =>-47.899923, :y => -15.772683})
@@ -1,129 +1,34 @@
1
1
  module Geometry
2
2
  include Math
3
3
  extend Math
4
+
5
+ # Earth radius near Equator Line
6
+ EARTH_RADIUS = 6378
4
7
 
5
- def distance(point1, point2)
6
- x1 = (point1[:x] > 0) ? point1[:x] : (point1[:x]*-1 )
7
- x2 = (point2[:x] > 0) ? point2[:x] : (point2[:x]*-1 )
8
- y1 = (point1[:y] > 0) ? point1[:y] : (point1[:y]*-1 )
9
- y2 = (point2[:y] > 0) ? point2[:y] : (point2[:y]*-1 )
10
- hypot x1 - x2, y1 - y2
8
+ def euclidean_distance(point1, point2)
9
+ hypot point1[:x] - point2[:x], point1[:y] - point2[:y]
11
10
  end
12
11
 
13
- def calculate_distance(point1, point2)
14
- x1 = point1[:x] * Math::PI / 180
15
- x2 = point2[:x] * Math::PI / 180
16
- y1 = point1[:y] * Math::PI / 180
17
- y2 = point2[:y] * Math::PI / 180
18
-
19
- s = sin(y2)*sin(y1)+(cos(y2)*cos(y1)*cos(x2 - x1))
20
- rad_distance = acos(s)
21
- degree_distance = rad_distance/(Math::PI/180)
22
- earth_radius = 6378
23
- distance_km = earth_radius*degree_distance
24
- distance_km
25
- end
26
-
27
- module_function :distance
28
- module_function :calculate_distance
29
- end
30
-
31
- class Line
32
- include Math
33
- def initialize(pointA, pointB)
34
- @a, @b, @c = nil, nil, nil
35
- @gradient = nil
36
- @linear = nil
37
- @pointA = pointA
38
- @pointB = pointB
39
- calculate_gradient
40
- calculate_linear
41
- end
42
-
43
- def pointA
44
- @pointA
45
- end
46
-
47
- def pointB
48
- @pointB
49
- end
50
-
51
- def gradient(ac = nil)
52
- if ac.nil?
53
- @gradient
54
- else
55
- @gradient = ac
56
- end
57
-
58
- @gradient
59
- end
60
-
61
- # m(x2-x1) - y2 + y1 = 0
62
- def include?(point)
63
- result = @gradient * (point[:x] - @pointA[:x]) - point[:y] + @pointA[:y]
64
- if(result == 0)
65
- true
66
- else
67
- false
68
- end
69
- end
12
+ def calculate_spherical_distance(point1, point2)
13
+ x1 = deg_2_rad(point1[:x])
14
+ x2 = deg_2_rad(point2[:x])
15
+ y1 = deg_2_rad(point1[:y])
16
+ y2 = deg_2_rad(point2[:y])
70
17
 
71
- def intercept?(line)
72
- (intercept_at(line).nil? == true) ? false : true
73
- end
74
18
 
75
- def intercept_at(line)
76
- if @gradient != line.gradient
77
- x = calculate_x_from_two_lines(self, line)
78
- y = (@gradient*x.to_f) + @linear
79
-
80
- new_point = { :x => sprintf('%.6f',x).to_f, :y => sprintf('%.6f',y).to_f}
81
- return new_point
82
- end
83
-
84
- return nil
85
- end
86
-
87
- def linear_touch
88
- @linear
89
- end
90
-
91
- def intercept_line_segment?(line)
92
-
93
- # verify the distance
94
- if intercept?(line)
95
- interception_point = intercept_at(line)
96
-
97
- distance_segment = Geometry.calculate_distance(line.pointA, line.pointB)
98
- distance_A_line_segment = Geometry.calculate_distance(line.pointA, interception_point)
99
- distance_B_line_segment = Geometry.calculate_distance(line.pointB, interception_point)
100
-
101
- if distance_A_line_segment > distance_segment
102
- return false
103
- elsif distance_B_line_segment > distance_segment
104
- return false
105
- else
106
- return true
107
- end
108
- end
109
-
110
- return false
111
- end
112
-
113
- private
114
- def calculate_gradient
115
- @gradient = (@pointB[:y] - @pointA[:y]) / (@pointB[:x] - @pointA[:x]).to_f
116
- end
19
+ dlon = x2 - x1
20
+ dlat = y2 - y1
21
+ a = (sin(dlat/2))**2 + cos(y1) * cos(y2) * (sin(dlon/2))**2
22
+ c = 2 * atan2( sqrt(a), sqrt(1-a) )
23
+ d = 6378 * c
24
+ end
117
25
 
118
- def calculate_linear
119
- @linear = nil
120
- if not @gradient.nil?
121
- @linear = @pointA[:y].to_f - (@gradient * @pointA[:x].to_f )
122
- end
123
- @linear
124
- end
26
+ def deg_2_rad(deg)
27
+ rad = deg * Math::PI/180;
28
+ rad
29
+ end
125
30
 
126
- def calculate_x_from_two_lines(line1, line2)
127
- (line2.linear_touch - line1.linear_touch) / (line1.gradient - line2.gradient)
128
- end
31
+ module_function :euclidean_distance
32
+ module_function :deg_2_rad
33
+ module_function :calculate_spherical_distance
129
34
  end
@@ -0,0 +1,98 @@
1
+ class Line
2
+ def initialize(pointA, pointB)
3
+ @a, @b, @c = nil, nil, nil
4
+ @gradient = nil
5
+ @linear = nil
6
+ @pointA = pointA
7
+ @pointB = pointB
8
+ calculate_gradient
9
+ calculate_linear
10
+ end
11
+
12
+ def pointA
13
+ @pointA
14
+ end
15
+
16
+ def pointB
17
+ @pointB
18
+ end
19
+
20
+ def gradient(ac = nil)
21
+ if ac.nil?
22
+ @gradient
23
+ else
24
+ @gradient = ac
25
+ end
26
+
27
+ @gradient
28
+ end
29
+
30
+ # m(x2-x1) - y2 + y1 = 0
31
+ def include?(point)
32
+ result = @gradient * (point[:x] - @pointA[:x]) - point[:y] + @pointA[:y]
33
+ if(result == 0)
34
+ true
35
+ else
36
+ false
37
+ end
38
+ end
39
+
40
+ def intercept?(line)
41
+ (intercept_at(line).nil? == true) ? false : true
42
+ end
43
+
44
+ def intercept_at(line)
45
+ if @gradient != line.gradient
46
+ x = calculate_x_from_two_lines(self, line)
47
+ y = (@gradient*x.to_f) + @linear
48
+
49
+ new_point = { :x => sprintf('%.6f',x).to_f, :y => sprintf('%.6f',y).to_f}
50
+ return new_point
51
+ end
52
+
53
+ return nil
54
+ end
55
+
56
+ def linear_touch
57
+ @linear
58
+ end
59
+
60
+ def intercept_line_segment?(line)
61
+
62
+ # verify the distance
63
+ if intercept?(line)
64
+ interception_point = intercept_at(line)
65
+
66
+ distance_segment = Geometry.calculate_spherical_distance(line.pointA, line.pointB)
67
+ distance_A_line_segment = Geometry.calculate_spherical_distance(line.pointA, interception_point)
68
+ distance_B_line_segment = Geometry.calculate_spherical_distance(line.pointB, interception_point)
69
+
70
+ if distance_A_line_segment > distance_segment
71
+ return false
72
+ elsif distance_B_line_segment > distance_segment
73
+ return false
74
+ else
75
+ return true
76
+ end
77
+ end
78
+
79
+ return false
80
+ end
81
+
82
+ private
83
+ def calculate_gradient
84
+ @gradient = (@pointB[:y] - @pointA[:y]) / (@pointB[:x] - @pointA[:x]).to_f
85
+ end
86
+
87
+ def calculate_linear
88
+ @linear = nil
89
+ if not @gradient.nil?
90
+ @linear = @pointA[:y].to_f - (@gradient * @pointA[:x].to_f )
91
+ end
92
+ @linear
93
+ end
94
+
95
+ def calculate_x_from_two_lines(line1, line2)
96
+ (line2.linear_touch - line1.linear_touch) / (line1.gradient - line2.gradient)
97
+ end
98
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: laptimer-geometry
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Eduardo Marques
@@ -15,10 +15,10 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-10-03 00:00:00 Z
18
+ date: 2011-10-14 00:00:00 Z
19
19
  dependencies: []
20
20
 
21
- description: " laptimer-geometry is a gem created to help the coordinates calculations used in a laptimer software.\n"
21
+ description: " laptimer-geometry is a gem created to help the coordinate calculations used in laptimer software.\n v0.0.2 \n - Added a new method to calculate distance between two geographic points\n - Improved the accuracy of the distance calculation\n"
22
22
  email: edhana@gmail.com
23
23
  executables: []
24
24
 
@@ -28,8 +28,8 @@ extra_rdoc_files: []
28
28
 
29
29
  files:
30
30
  - src/geometry.rb
31
- - src/lap_counter.rb
32
- - spec/lap_counter_spec.rb
31
+ - src/line.rb
32
+ - spec/geometry_spec.rb
33
33
  - spec/line_spec.rb
34
34
  homepage: http://github.com/edhana/laptimer-geometry
35
35
  licenses: []
@@ -65,5 +65,5 @@ signing_key:
65
65
  specification_version: 3
66
66
  summary: Implementation of basic 2D geometry algorithms, to help with a lap timer system written in Ruby
67
67
  test_files:
68
- - spec/lap_counter_spec.rb
68
+ - spec/geometry_spec.rb
69
69
  - spec/line_spec.rb
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
- require File.expand_path('../../src/lap_counter', __FILE__)
3
-
4
- describe LapCounter do
5
- it "should find a straight segment witch is valid" do
6
- true.should be_true
7
- end
8
- end
@@ -1,2 +0,0 @@
1
- class LapCounter
2
- end