geo-triangle 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "rspec", "~> 2.3.0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.6.0"
12
+ gem "rcov", ">= 0"
13
+ end
@@ -0,0 +1,28 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.6.0)
7
+ bundler (~> 1.0.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rake (0.8.7)
11
+ rcov (0.9.9)
12
+ rspec (2.3.0)
13
+ rspec-core (~> 2.3.0)
14
+ rspec-expectations (~> 2.3.0)
15
+ rspec-mocks (~> 2.3.0)
16
+ rspec-core (2.3.1)
17
+ rspec-expectations (2.3.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.3.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ bundler (~> 1.0.0)
26
+ jeweler (~> 1.6.0)
27
+ rcov
28
+ rspec (~> 2.3.0)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 parrot-studio
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,71 @@
1
+ = geo-triangle
2
+
3
+ == Introduction
4
+
5
+ Author:: parrot_studio < parrot at users.sourceforge.jp >
6
+ License:: The MIT License
7
+
8
+ 三点の座標から中心(重心)を求める。
9
+
10
+ あくまで緯度経度を数値的に処理しているだけで、距離の補正等は考慮していない。
11
+ そのため、あまりに離れすぎた三点を指定すると、値が妥当でない場合があり得る。
12
+
13
+ == Install
14
+ gem install geo-triangle
15
+
16
+ == Usage
17
+ # require 'rubygems' # if ruby 1.8.x
18
+ require 'geo-triangle'
19
+
20
+ # 緯度(lat), 経度(lon)の組み合わせを3つ渡す
21
+ GeoTriangle.center(
22
+ [36.383304,139.073632], [36.391026,139.075107], [36.378536,139.046445]) #=> [36.384289, 139.065061]
23
+
24
+ # 順序が正しければ引数は適当でもいい
25
+ GeoTriangle.center(
26
+ 36.383304,139.073632,36.391026,139.075107,36.378536,139.046445)
27
+
28
+ # newしてから構築するやり方
29
+ gt1 = GeoTriangle.new
30
+ gt1.set_coordinate([36.383304,139.073632])
31
+ gt1.set_coordinate([36.391026,139.075107])
32
+ gt1.set_coordinate([36.378536,139.046445])
33
+ gt1.center #=> [36.384289, 139.065061]
34
+
35
+ # 4個以上は無視される
36
+ gt2 = GeoTriangle.new
37
+ gt2.set_coordinate([36.383304,139.073632])
38
+ gt2.set_coordinate([36.391026,139.075107])
39
+ gt2.set_coordinate([36.378536,139.046445])
40
+ gt2.set_coordinate([37.378536,136.046445]) # 4つ目以降は無視
41
+ gt2.center #=> [36.384289, 139.065061]
42
+
43
+ # 同じ座標はまとめられる
44
+ gt3 = GeoTriangle.new
45
+ gt3.set_coordinate([36.383304,139.073632])
46
+ gt3.set_coordinate([36.391026,139.075107])
47
+ gt3.set_coordinate([36.391026,139.075107]) # 上と同じ座標
48
+ # 座標が2つと見なされ、座標の数が足りないのでnilを返す
49
+ gt3.center #=> nil
50
+
51
+ == Extra Module
52
+ # require 'rubygems' # if 1.8.x
53
+ require 'geo-triangle'
54
+
55
+ # 重心ではなく外心を求めたい場合
56
+ cc = GeoTriangleExt::CircumCenter.create([0,4],[2,0],[5,6])
57
+ cc.center #=> [2.333333, 3.333333]
58
+
59
+ # 鈍角三角形の場合、外心は三角形の外になるため、実装はしたが使えない
60
+
61
+ == Release Note
62
+
63
+ === ver 0.0.1
64
+
65
+ * release for test
66
+
67
+ == Copyright
68
+
69
+ Copyright (c) 2011 parrot-studio. See LICENSE.txt for
70
+ further details.
71
+
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "geo-triangle"
18
+ gem.homepage = "http://github.com/parrot-studio/geo-triangle"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{calculate geo-triangle's gravity center}
21
+ gem.description = %Q{calculate center of 3 geo-coordinates(lat, lon)}
22
+ gem.email = "parrot@users.sourceforge.jp"
23
+ gem.authors = ["parrot-studio"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.rspec_opts = ["-c", "-r ./spec/spec_helper.rb"]
32
+ spec.pattern = FileList['spec/**/*_spec.rb']
33
+ end
34
+
35
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :default => :spec
41
+
42
+ require 'rake/rdoctask'
43
+ Rake::RDocTask.new do |rdoc|
44
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
45
+
46
+ rdoc.rdoc_dir = 'rdoc'
47
+ rdoc.title = "geo-triangle #{version}"
48
+ rdoc.rdoc_files.include('README*')
49
+ rdoc.rdoc_files.include('lib/**/*.rb')
50
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,60 @@
1
+ # coding: utf-8
2
+ require 'bigdecimal'
3
+ require 'gravity_center'
4
+ require 'geo_triangle_ext/linear_function'
5
+ require 'geo_triangle_ext/circum_center'
6
+
7
+ class GeoTriangle
8
+
9
+ class << self
10
+
11
+ def center(*val)
12
+ gt = self.new
13
+ v = [val].flatten
14
+ gt.set_coordinate(v[0], v[1])
15
+ gt.set_coordinate(v[2], v[3])
16
+ gt.set_coordinate(v[4], v[5])
17
+ gt.center
18
+ end
19
+
20
+ end
21
+
22
+ def exist?(lat, lon)
23
+ return false unless lat
24
+ return false unless lon
25
+ return false if lat.abs > 90.0
26
+ return false if lon.abs > 180.0
27
+ true
28
+ end
29
+
30
+ def set_coordinate(*val)
31
+ v = [val].flatten
32
+ lat = v[0]
33
+ lon = v[1]
34
+ coordinates << [lat, lon] if exist?(lat, lon)
35
+ self
36
+ end
37
+
38
+ def coordinates
39
+ @coordinates ||= []
40
+ @coordinates = @coordinates.uniq
41
+ @coordinates = @coordinates.take(3) if @coordinates.size > 3
42
+ @coordinates
43
+ end
44
+
45
+ def valid_coordinates?
46
+ return false unless coordinates.size == 3
47
+ return false unless coordinates.all?{|c| c.size == 2}
48
+ true
49
+ end
50
+
51
+ def center
52
+ return unless valid_coordinates?
53
+ gc = GravityCenter.create(*coordinates)
54
+ lat = gc.center_x.round(6).to_f
55
+ lon = gc.center_y.round(6).to_f
56
+ exist?(lat, lon) ? [lat, lon] : nil
57
+ end
58
+
59
+ end
60
+
@@ -0,0 +1,84 @@
1
+ # coding: utf-8
2
+ module GeoTriangleExt
3
+
4
+ class CircumCenter
5
+
6
+ class << self
7
+
8
+ def create(*co)
9
+ cc = self.new
10
+ co.take(3).each{|c| cc.coordinates << c}
11
+ cc
12
+ end
13
+
14
+ end
15
+
16
+ def set_coordinate(x, y)
17
+ coordinates << [x, y]
18
+ end
19
+
20
+ def coordinates
21
+ @coordinates ||= []
22
+ @coordinates = @coordinates.uniq
23
+ @coordinates = @coordinates.take(3) if @coordinates.size > 3
24
+ @coordinates
25
+ end
26
+
27
+ def valid_coordinates?
28
+ return false unless coordinates.size == 3
29
+ return false unless coordinates.all?{|c| c.size == 2}
30
+ true
31
+ end
32
+
33
+ def functions
34
+ @functions ||= create_functions
35
+ @functions
36
+ end
37
+
38
+ def valid_functions?
39
+ return false if functions.size < 2
40
+ return false if functions.combination(2).any?{|f1, f2|
41
+ f1.orthogonal_slope == f2.orthogonal_slope}
42
+ true
43
+ end
44
+
45
+ def center
46
+ return unless valid_functions?
47
+ @center_point ||= calc_center
48
+ @center_point
49
+ end
50
+
51
+ private
52
+
53
+ def create_functions
54
+ return [] unless valid_coordinates?
55
+ ret = []
56
+ coordinates.combination(2) do |a, b|
57
+ f = LinearFunction.create(*([a, b].flatten))
58
+ next unless f
59
+ ret << f if f.valid?
60
+ end
61
+ ret
62
+ end
63
+
64
+ def calc_center
65
+ return unless valid_functions?
66
+
67
+ l1 = functions.first
68
+ l2 = functions.last
69
+
70
+ a1 = l1.orthogonal_slope
71
+ b1 = l1.orthogonal_intercept
72
+ a2 = l2.orthogonal_slope
73
+ b2 = l2.orthogonal_intercept
74
+
75
+ x = (b2 - b1) / (a1 - a2)
76
+ y = (a1 * b2 - b1 * a2) / (a1 - a2)
77
+
78
+ [x, y]
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
@@ -0,0 +1,77 @@
1
+ # coding: utf-8
2
+ module GeoTriangleExt
3
+
4
+ class LinearFunction
5
+
6
+ attr_writer :ax, :ay, :bx, :by
7
+
8
+ class << self
9
+
10
+ def create(ax, ay, bx, by)
11
+ lf = self.new
12
+ lf.ax = ax
13
+ lf.ay = ay
14
+ lf.bx = bx
15
+ lf.by = by
16
+ lf
17
+ end
18
+
19
+ end
20
+
21
+ def ax
22
+ @bax ||= BigDecimal(@ax.to_s)
23
+ @bax
24
+
25
+ end
26
+
27
+ def ay
28
+ @bay ||= BigDecimal(@ay.to_s)
29
+ @bay
30
+ end
31
+
32
+ def bx
33
+ @bbx ||= BigDecimal(@bx.to_s)
34
+ @bbx
35
+ end
36
+
37
+ def by
38
+ @bby ||= BigDecimal(@by.to_s)
39
+ @bby
40
+ end
41
+
42
+ def valid?
43
+ return false if ax == bx
44
+ return false if ay == by
45
+ true
46
+ end
47
+
48
+ def middle_point
49
+ x = (ax + bx) / 2.0
50
+ y = (ay + by) / 2.0
51
+ [x, y]
52
+ end
53
+
54
+ def slope
55
+ return unless valid?
56
+ (ay - by) / (ax - bx)
57
+ end
58
+
59
+ def intercept
60
+ return unless valid?
61
+ (ax * by - ay * bx) / (ax - bx)
62
+ end
63
+
64
+ def orthogonal_slope
65
+ return unless valid?
66
+ (bx - ax) / (ay - by)
67
+ end
68
+
69
+ def orthogonal_intercept
70
+ return unless valid?
71
+ (ax*ax + ay*ay - bx*bx - by*by) / (2 * (ay - by))
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
@@ -0,0 +1,75 @@
1
+ # coding: utf-8
2
+ require 'bigdecimal'
3
+
4
+ class GravityCenter
5
+
6
+ attr_reader :x1, :y1, :x2, :y2, :x3, :y3
7
+
8
+ def self.create(*val)
9
+ gc = self.new
10
+ gc.instance_eval do
11
+ v = [val].flatten
12
+ @x1 = BigDecimal(v[0].to_s)
13
+ @y1 = BigDecimal(v[1].to_s)
14
+ @x2 = BigDecimal(v[2].to_s)
15
+ @y2 = BigDecimal(v[3].to_s)
16
+ @x3 = BigDecimal(v[4].to_s)
17
+ @y3 = BigDecimal(v[5].to_s)
18
+ end
19
+ gc
20
+ end
21
+
22
+ def sx1
23
+ @sx1 ||= x1 - x3
24
+ @sx1
25
+ end
26
+
27
+ def sy1
28
+ @sy1 ||= y1 - y3
29
+ @sy1
30
+ end
31
+
32
+ def sx2
33
+ @sx2 ||= x2 - x3
34
+ @sx2
35
+ end
36
+
37
+ def sy2
38
+ @sy2 ||= y2 - y3
39
+ @sy2
40
+ end
41
+
42
+ def center_sx
43
+ @center_sx ||= calc_center_sx
44
+ @center_sx
45
+ end
46
+
47
+ def center_x
48
+ center_sx + x3
49
+ end
50
+
51
+ def center_sy
52
+ @center_sy ||= calc_center_sy
53
+ @center_sy
54
+ end
55
+
56
+ def center_y
57
+ center_sy + y3
58
+ end
59
+
60
+ def center
61
+ [center_x, center_y]
62
+ end
63
+
64
+ private
65
+
66
+ def calc_center_sx
67
+ (sx1 + sx2) / 3
68
+ end
69
+
70
+ def calc_center_sy
71
+ (sy1 + sy2) / 3
72
+ end
73
+
74
+ end
75
+
@@ -0,0 +1,130 @@
1
+ # coding: utf-8
2
+ describe GeoTriangle do
3
+
4
+ describe "#exist?" do
5
+
6
+ before do
7
+ @gt = GeoTriangle.new
8
+ end
9
+
10
+ context "lat or lon is nil" do
11
+ it {@gt.exist?(40.2, nil).should be_false}
12
+ it {@gt.exist?(nil, 135.0).should be_false}
13
+ end
14
+
15
+ context "over value" do
16
+ it {@gt.exist?(90.1, 135.0).should be_false}
17
+ it {@gt.exist?(42.0, 180.1).should be_false}
18
+ end
19
+
20
+ context "valid lat and lon" do
21
+ it {@gt.exist?(36.383304, 139.073632).should be_true}
22
+ end
23
+
24
+ end
25
+
26
+ describe "#set_coordinate" do
27
+
28
+ before do
29
+ @gt = GeoTriangle.new
30
+ end
31
+
32
+ context "exist coordinate" do
33
+ before do
34
+ @gt.set_coordinate([36.383304, 139.073632])
35
+ @gt.set_coordinate(36.391026, 139.075107)
36
+ end
37
+ it {@gt.coordinates.should == [[36.383304, 139.073632], [36.391026, 139.075107]]}
38
+ end
39
+
40
+ context "not exist coordinate" do
41
+ before do
42
+ @gt.set_coordinate([136.383304, 139.073632])
43
+ @gt.set_coordinate(36.391026, 239.075107)
44
+ end
45
+ it {@gt.coordinates.should be_empty}
46
+ end
47
+
48
+ context "not coordinate pair" do
49
+ before do
50
+ @gt.set_coordinate(36.383304)
51
+ end
52
+ it {@gt.coordinates.should be_empty}
53
+ end
54
+
55
+ end
56
+
57
+ describe "#valid_coordinates?" do
58
+
59
+ before do
60
+ @gt = GeoTriangle.new
61
+ end
62
+
63
+ context "coordinates size not enough" do
64
+ before do
65
+ @gt.set_coordinate([36.383304, 139.073632])
66
+ @gt.set_coordinate(36.391026, 139.075107)
67
+ end
68
+ it {@gt.coordinates.size.should == 2}
69
+ it {@gt.valid_coordinates?.should be_false}
70
+ end
71
+
72
+ context "invalid coordinate format" do
73
+ before do
74
+ @gt.set_coordinate([36.383304, 139.073632])
75
+ @gt.set_coordinate(36.391026, 139.075107)
76
+ @gt.coordinates << [135.0]
77
+ end
78
+ it {@gt.coordinates.size.should == 3}
79
+ it {@gt.valid_coordinates?.should be_false}
80
+ end
81
+
82
+ context "valid coordinates" do
83
+ before do
84
+ @gt.set_coordinate([36.383304,139.073632])
85
+ @gt.set_coordinate([36.391026,139.075107])
86
+ @gt.set_coordinate([36.378536,139.046445])
87
+ @gt.set_coordinate([37.378536,138.046445])
88
+ end
89
+ it {@gt.coordinates.size.should == 3}
90
+ it {@gt.valid_coordinates?.should be_true}
91
+ end
92
+
93
+ end
94
+
95
+ describe "#center" do
96
+
97
+ before do
98
+ @gt = GeoTriangle.new
99
+ end
100
+
101
+ context "valid coordinates center" do
102
+ before do
103
+ @gt.set_coordinate([36.383304,139.073632])
104
+ @gt.set_coordinate([36.391026,139.075107])
105
+ @gt.set_coordinate([36.378536,139.046445])
106
+ end
107
+ it {@gt.center.should == [36.384289, 139.065061]}
108
+ end
109
+
110
+ context "invalid coordinates" do
111
+ before do
112
+ @gt.set_coordinate([36.383304,139.073632])
113
+ @gt.set_coordinate([36.391026,139.075107])
114
+ @gt.set_coordinate([36.391026,139.075107])
115
+ end
116
+ it {@gt.coordinates.size.should == 2}
117
+ it {@gt.valid_coordinates?.should be_false}
118
+ it {@gt.center.should be_nil}
119
+ end
120
+
121
+ end
122
+
123
+ describe ".center" do
124
+ subject {GeoTriangle.center(
125
+ [36.383304,139.073632], [36.391026,139.075107], [36.378536,139.046445])}
126
+ it {should == [36.384289, 139.065061]}
127
+ end
128
+
129
+ end
130
+
@@ -0,0 +1,178 @@
1
+ # coding: utf-8
2
+ describe GeoTriangleExt::CircumCenter do
3
+
4
+ describe "#set_coordinate" do
5
+ before do
6
+ @cc = GeoTriangleExt::CircumCenter.new
7
+ @cc.set_coordinate(1, 2)
8
+ end
9
+ it {@cc.coordinates.should == [[1,2]]}
10
+ end
11
+
12
+ describe "#coordinates" do
13
+
14
+ context "default" do
15
+ it {GeoTriangleExt::CircumCenter.new.coordinates.should be_empty}
16
+ end
17
+
18
+ context "has only 3 coordinates" do
19
+ before do
20
+ @cc = GeoTriangleExt::CircumCenter.new
21
+ @cc.set_coordinate(1, 2)
22
+ @cc.set_coordinate(3, 4)
23
+ @cc.set_coordinate(5, 6)
24
+ @cc.set_coordinate(7, 8)
25
+ end
26
+ it {@cc.coordinates.size.should == 3}
27
+ it {@cc.coordinates.should == [[1,2],[3,4],[5,6]]}
28
+ end
29
+
30
+ end
31
+
32
+ describe "#valid_coordinates?" do
33
+
34
+ context "coordinates size not enough" do
35
+ before do
36
+ @cc = GeoTriangleExt::CircumCenter.new
37
+ @cc.set_coordinate(1, 2)
38
+ @cc.set_coordinate(3, 4)
39
+ end
40
+ it {@cc.coordinates.size.should == 2}
41
+ it {@cc.valid_coordinates?.should be_false}
42
+ end
43
+
44
+ context "invalid coordinate format" do
45
+ before do
46
+ @cc = GeoTriangleExt::CircumCenter.new
47
+ @cc.set_coordinate(1, 2)
48
+ @cc.set_coordinate(3, 4)
49
+ @cc.coordinates << 5
50
+ end
51
+ it {@cc.coordinates.size.should == 3}
52
+ it {@cc.valid_coordinates?.should be_false}
53
+ end
54
+
55
+ context "valid coordinates" do
56
+ before do
57
+ @cc = GeoTriangleExt::CircumCenter.new
58
+ @cc.set_coordinate(1, 2)
59
+ @cc.set_coordinate(3, 4)
60
+ @cc.set_coordinate(5, 6)
61
+ @cc.set_coordinate(7, 8)
62
+ end
63
+ it {@cc.coordinates.size.should == 3}
64
+ it {@cc.valid_coordinates?.should be_true}
65
+ end
66
+
67
+ end
68
+
69
+ describe ".create" do
70
+
71
+ context "create object" do
72
+ subject {GeoTriangleExt::CircumCenter.create([1,2], [3,4], [5,6])}
73
+ it {should be_instance_of(GeoTriangleExt::CircumCenter)}
74
+ its(:coordinates) {should == [[1,2],[3,4],[5,6]]}
75
+ end
76
+
77
+ context "take 3 coordinates if given over 3" do
78
+ subject {GeoTriangleExt::CircumCenter.create([1,2], [3,4], [5,6],[7,8])}
79
+ it {should be_instance_of(GeoTriangleExt::CircumCenter)}
80
+ its(:coordinates) {should == [[1,2],[3,4],[5,6]]}
81
+ end
82
+
83
+ end
84
+
85
+ describe "#functions" do
86
+
87
+ context "3 functions from triangle coordinates" do
88
+ before do
89
+ @cc = GeoTriangleExt::CircumCenter.create([0,4],[2,0],[5,6])
90
+ end
91
+ it {@cc.functions.size.should == 3}
92
+ end
93
+
94
+ context "not created if not valid coordinates" do
95
+ before do
96
+ @cc = GeoTriangleExt::CircumCenter.new
97
+ @cc.set_coordinate(1, 2)
98
+ @cc.set_coordinate(3, 4)
99
+ end
100
+ it {@cc.functions.should be_empty}
101
+ end
102
+
103
+ context "2 functions if 2 coordinates x or y is same" do
104
+ before do
105
+ @cc = GeoTriangleExt::CircumCenter.create([0,4],[2,0],[5,4])
106
+ end
107
+ it {@cc.functions.size.should == 2}
108
+ end
109
+
110
+ context "1 functions if right triangle" do
111
+ before do
112
+ @cc = GeoTriangleExt::CircumCenter.create([0,4],[2,0],[0,0])
113
+ end
114
+ it {@cc.functions.size.should == 1}
115
+ end
116
+
117
+ end
118
+
119
+ describe "#valid_functions?" do
120
+
121
+ context "valid triangle coordinates" do
122
+ before do
123
+ @cc = GeoTriangleExt::CircumCenter.create([0,4],[2,0],[5,6])
124
+ end
125
+ it {@cc.functions.size.should == 3}
126
+ it {@cc.valid_functions?.should be_true}
127
+ end
128
+
129
+ context "2 functions is valid" do
130
+ before do
131
+ @cc = GeoTriangleExt::CircumCenter.create([0,4],[2,0],[5,4])
132
+ end
133
+ it {@cc.functions.size.should == 2}
134
+ it {@cc.valid_functions?.should be_true}
135
+ end
136
+
137
+ context "1 functions is not valid" do
138
+ before do
139
+ @cc = GeoTriangleExt::CircumCenter.create([0,4],[2,0],[0,0])
140
+ end
141
+ it {@cc.functions.size.should == 1}
142
+ it {@cc.valid_functions?.should be_false}
143
+ end
144
+
145
+ context "3 coordinates on same line" do
146
+ before do
147
+ @cc = GeoTriangleExt::CircumCenter.create([0,4],[2,0],[4,-4])
148
+ end
149
+ it {@cc.functions.size.should == 3}
150
+ it {@cc.valid_functions?.should be_false}
151
+ end
152
+
153
+ end
154
+
155
+ describe "#center" do
156
+
157
+ context "triangle coordinates" do
158
+ before do
159
+ cc = GeoTriangleExt::CircumCenter.create([0,4],[2,0],[5,6])
160
+ @x, @y = cc.center
161
+ end
162
+ it {@x.round(5).to_f.should == 3.25}
163
+ it {@y.round(5).to_f.should == 3.125}
164
+ end
165
+
166
+ context "2 coordinates x or y is same" do
167
+ before do
168
+ cc = GeoTriangleExt::CircumCenter.create([0,4],[2,0],[5,4])
169
+ @x, @y = cc.center
170
+ end
171
+ it {@x.round(5).to_f.should == 2.5}
172
+ it {@y.round(5).to_f.should == 2.75}
173
+ end
174
+
175
+ end
176
+
177
+ end
178
+
@@ -0,0 +1,97 @@
1
+ # coding: utf-8
2
+ describe GeoTriangleExt::LinearFunction do
3
+
4
+ describe "#valid?" do
5
+
6
+ context "ax == bx" do
7
+ before do
8
+ @lf = GeoTriangleExt::LinearFunction.new
9
+ @lf.ax = 1
10
+ @lf.ay = 2
11
+ @lf.bx = 1
12
+ @lf.by = 5
13
+ end
14
+ it {@lf.valid?.should be_false}
15
+ end
16
+
17
+ context "bx == by" do
18
+ before do
19
+ @lf = GeoTriangleExt::LinearFunction.new
20
+ @lf.ax = 1
21
+ @lf.ay = 2
22
+ @lf.bx = 7
23
+ @lf.by = 2
24
+ end
25
+ it {@lf.valid?.should be_false}
26
+ end
27
+
28
+ context "unrelated" do
29
+ before do
30
+ @lf = GeoTriangleExt::LinearFunction.new
31
+ @lf.ax = 1
32
+ @lf.ay = 2
33
+ @lf.bx = 7
34
+ @lf.by = 0
35
+ end
36
+ it {@lf.valid?.should be_true}
37
+ end
38
+
39
+ end
40
+
41
+ describe ".create" do
42
+ subject{GeoTriangleExt::LinearFunction.create(1, 2, 7, 0)}
43
+ it {should be_instance_of(GeoTriangleExt::LinearFunction)}
44
+ its(:ax) {should == 1.0}
45
+ its(:ay) {should == 2.0}
46
+ its(:bx) {should == 7.0}
47
+ its(:by) {should == 0.0}
48
+ end
49
+
50
+ describe "#middle_point" do
51
+
52
+ context "positive number only" do
53
+ before do
54
+ @lf = GeoTriangleExt::LinearFunction.create(1, 2, 7, 1)
55
+ end
56
+ it {@lf.middle_point.should == [4.0, 1.5]}
57
+ end
58
+
59
+ context "include negative number" do
60
+ before do
61
+ @lf = GeoTriangleExt::LinearFunction.create(1, 2, -7, -1)
62
+ end
63
+ it {@lf.middle_point.should == [-3.0, 0.5]}
64
+ end
65
+
66
+ end
67
+
68
+ describe "#slope" do
69
+ before do
70
+ @lf = GeoTriangleExt::LinearFunction.create(0, 4, 2, 0)
71
+ end
72
+ it {@lf.slope.should == -2.0}
73
+ end
74
+
75
+ describe "#intercept" do
76
+ before do
77
+ @lf = GeoTriangleExt::LinearFunction.create(0, 4, 2, 0)
78
+ end
79
+ it {@lf.intercept.should == 4.0}
80
+ end
81
+
82
+ describe "#orthogonal_slope" do
83
+ before do
84
+ @lf = GeoTriangleExt::LinearFunction.create(0, 4, 2, 0)
85
+ end
86
+ it {@lf.orthogonal_slope.should == 0.5}
87
+ end
88
+
89
+ describe "#orthogonal_intercept" do
90
+ before do
91
+ @lf = GeoTriangleExt::LinearFunction.create(0, 4, 2, 0)
92
+ end
93
+ it {@lf.orthogonal_intercept.should == 1.5}
94
+ end
95
+
96
+ end
97
+
@@ -0,0 +1,60 @@
1
+ # coding: utf-8
2
+ describe GravityCenter do
3
+
4
+ describe ".create" do
5
+
6
+ context "3 coordinates set" do
7
+ subject {GravityCenter.create([1,2],[3,4],[5,6])}
8
+ it {should be_instance_of(GravityCenter)}
9
+ its(:x1) {should == 1.0}
10
+ its(:y1) {should == 2.0}
11
+ its(:x2) {should == 3.0}
12
+ its(:y2) {should == 4.0}
13
+ its(:x3) {should == 5.0}
14
+ its(:y3) {should == 6.0}
15
+ end
16
+
17
+ context "6 numbers set" do
18
+ subject {GravityCenter.create(10,20,30,40,50,60)}
19
+ it {should be_instance_of(GravityCenter)}
20
+ its(:x1) {should == 10.0}
21
+ its(:y1) {should == 20.0}
22
+ its(:x2) {should == 30.0}
23
+ its(:y2) {should == 40.0}
24
+ its(:x3) {should == 50.0}
25
+ its(:y3) {should == 60.0}
26
+ end
27
+
28
+ end
29
+
30
+ describe "#sx1, #sx2, #sy1, #sy2 is shifted coordinates for (x3,y3) to (0,0)" do
31
+ subject {GravityCenter.create([0,4],[2,0],[5,6])}
32
+ its(:sx1) {should == -5.0}
33
+ its(:sy1) {should == -2.0}
34
+ its(:sx2) {should == -3.0}
35
+ its(:sy2) {should == -6.0}
36
+ end
37
+
38
+ describe "#center_sx, #center_sy is gravity center of shifted triangle" do
39
+ subject {GravityCenter.create([0,4],[2,0],[5,6])}
40
+ it {subject.center_sx.round(6).to_f.should == -2.666667}
41
+ it {subject.center_sy.round(6).to_f.should == -2.666667}
42
+ end
43
+
44
+ describe "#center_x, #center_y is gravity center of original triangle" do
45
+ subject {GravityCenter.create([0,4],[2,0],[5,6])}
46
+ it {subject.center_x.round(6).to_f.should == 2.333333}
47
+ it {subject.center_y.round(6).to_f.should == 3.333333}
48
+ end
49
+
50
+ describe "#center is gravity center coordinate of triangle" do
51
+ before do
52
+ gc = GravityCenter.create([0,4],[2,0],[5,6])
53
+ @x, @y = gc.center
54
+ end
55
+ it {@x.round(6).to_f.should == 2.333333}
56
+ it {@y.round(6).to_f.should == 3.333333}
57
+ end
58
+
59
+ end
60
+
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'geo-triangle'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geo-triangle
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - parrot-studio
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-19 00:00:00 +09:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 2.3.0
24
+ type: :development
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 1.0.0
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: jeweler
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.6.0
46
+ type: :development
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: rcov
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: *id004
60
+ description: calculate center of 3 geo-coordinates(lat, lon)
61
+ email: parrot@users.sourceforge.jp
62
+ executables: []
63
+
64
+ extensions: []
65
+
66
+ extra_rdoc_files:
67
+ - LICENSE.txt
68
+ - README.rdoc
69
+ files:
70
+ - .document
71
+ - .rspec
72
+ - Gemfile
73
+ - Gemfile.lock
74
+ - LICENSE.txt
75
+ - README.rdoc
76
+ - Rakefile
77
+ - VERSION
78
+ - lib/geo-triangle.rb
79
+ - lib/geo_triangle_ext/circum_center.rb
80
+ - lib/geo_triangle_ext/linear_function.rb
81
+ - lib/gravity_center.rb
82
+ - spec/geo-triangle_spec.rb
83
+ - spec/geo_triangle_ext/circum_center_spec.rb
84
+ - spec/geo_triangle_ext/linear_function_spec.rb
85
+ - spec/gravity_center_spec.rb
86
+ - spec/spec_helper.rb
87
+ has_rdoc: true
88
+ homepage: http://github.com/parrot-studio/geo-triangle
89
+ licenses:
90
+ - MIT
91
+ post_install_message:
92
+ rdoc_options: []
93
+
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 449437378648933997
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: "0"
111
+ requirements: []
112
+
113
+ rubyforge_project:
114
+ rubygems_version: 1.6.2
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: calculate geo-triangle's gravity center
118
+ test_files: []
119
+