flash_math 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +17 -0
  4. data/.rspec +4 -0
  5. data/.travis.yml +13 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +187 -0
  9. data/Rakefile +6 -0
  10. data/flash_math.gemspec +27 -0
  11. data/lib/flash_math.rb +3 -0
  12. data/lib/flash_math/modules/geometry.rb +10 -0
  13. data/lib/flash_math/modules/geometry/geometric_bounding_box.rb +16 -0
  14. data/lib/flash_math/modules/geometry/geometric_distance.rb +20 -0
  15. data/lib/flash_math/modules/geometry/geometric_line.rb +87 -0
  16. data/lib/flash_math/modules/geometry/geometric_point.rb +19 -0
  17. data/lib/flash_math/modules/geometry/geometric_point_in_polygon.rb +63 -0
  18. data/lib/flash_math/modules/geometry/geometric_polygon.rb +36 -0
  19. data/lib/flash_math/modules/geometry/geometric_segment.rb +128 -0
  20. data/lib/flash_math/modules/geometry/geometric_vector.rb +46 -0
  21. data/lib/flash_math/modules/statistics.rb +1 -0
  22. data/lib/flash_math/modules/statistics/statistical_spread.rb +129 -0
  23. data/lib/flash_math/version.rb +3 -0
  24. data/spec/lib/geometry/geometric_bounding_box_spec.rb +67 -0
  25. data/spec/lib/geometry/geometric_distance_spec.rb +55 -0
  26. data/spec/lib/geometry/geometric_line_spec.rb +287 -0
  27. data/spec/lib/geometry/geometric_point_spec.rb +53 -0
  28. data/spec/lib/geometry/geometric_polygon_spec.rb +148 -0
  29. data/spec/lib/geometry/geometric_segment_spec.rb +231 -0
  30. data/spec/lib/geometry/geometric_vector_spec.rb +110 -0
  31. data/spec/lib/statistics/statistics_spread_spec.rb +219 -0
  32. data/spec/spec_helper.rb +4 -0
  33. metadata +168 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ce3ea8e05a64b4e3c3d6b526609c6f0c83ac19ee
4
+ data.tar.gz: d45484f49006f327b0aed556f69264c46b72861e
5
+ SHA512:
6
+ metadata.gz: a1d77d3c127d7e1ce4fa407b0918e8e54f84ff45c3c4357b45e4b682b5aab3c3ab657e51212814806461fc3295281234b558372afe372137096c90f99ecf63a9
7
+ data.tar.gz: b88290c99fe047570a92e1b611aae66a3a3f8607b764a967ba813aeafe914379a779893374e6dd6f8c732961e9f1402e1b850578d936eb40803824b4ca932f05
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --order random
2
+ --colour
3
+ --backtrace
4
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ before_install:
2
+ - sudo apt-get install libxml2-dev
3
+ cache: bundler
4
+ language: ruby
5
+ notifications:
6
+ email:
7
+ recipients:
8
+ - j.gomez@drexed.com
9
+ on_failure: change
10
+ on_success: never
11
+ rvm:
12
+ - ruby-head
13
+ script: 'bundle exec rake'
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in flash_math.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Juan Gomez
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # Flash Math
2
+
3
+ [![Build Status](https://travis-ci.org/drexed/flash_math.svg?branch=master)](https://travis-ci.org/drexed/flash_math)
4
+ [![Coverage Status](https://coveralls.io/repos/drexed/flash_math/badge.png)](https://coveralls.io/r/drexed/flash_math)
5
+ [![Code Climate](https://codeclimate.com/github/drexed/flash_math.png)](https://codeclimate.com/github/drexed/flash_math)
6
+
7
+ Flash Validators is a collection of advance math modules.
8
+
9
+ Currently supported calculations: geometry and statistics.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'flash_math'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install flash_math
24
+
25
+ ## Usage
26
+
27
+ ### Geometry
28
+
29
+ ####Geometrical Point:####
30
+ Use the following methods to generate geometical point:
31
+ `GeometricPoint.new(x, y)` and `GeometricPoint.new_by_array(array)`
32
+
33
+ Use the following methods to generate geometical point data:
34
+ `advance_by(vector)` and `to_vector`
35
+
36
+ ```ruby
37
+ geo_point = GeometricPoint.new(1, 2)
38
+ geo_vector = GeometricVector.new(2, -1)
39
+
40
+ geo_point.x #=> 1
41
+ geo_point.2 #=> 2
42
+ geo_point.advance_by(geo_vector) #=> [3, 1]
43
+ ```
44
+
45
+ ####Geometrical Vector:####
46
+ Use the following methods to generate geometical vector:
47
+ `GeometricVector.new(x, y)` and `GeometricVector.new_by_array(array)`
48
+
49
+ Use the following methods to generate geometical vector data:
50
+ `modulus`, `collinear_with?(vector)`, `cross_product(vector)`, and `scalar_product(vector)`
51
+
52
+ ```ruby
53
+ geo_vector1 = GeometricVector.new(1, 2)
54
+ geo_vector2 = GeometricVector.new(2, 4)
55
+
56
+ geo_vector1.x #=> 1
57
+ geo_vector1.y #=> 2
58
+ geo_vector1.modulus #=> 2.23606797749979
59
+ geo_vector1.collinear_with?(geo_vector2) #=> true
60
+ geo_vector1.cross_product(geo_vector2) #=> 10
61
+ geo_vector1.scalar_product(geo_vector2) #=> 0
62
+ ```
63
+
64
+ ####Geometrical Distance:####
65
+ Use the following method to generate geometical distance:
66
+ `GeometricDistance.new(x, y)` and `GeometricDistance.new_by_arrays(array)`
67
+
68
+ Use the following methods to generate geometical distance data:
69
+ `distance`, `midpoint`, and `midpoint_distance`
70
+
71
+ ```ruby
72
+ geo_distance = GeometricalDistance.new_by_array([1, 1], [2, 4])
73
+
74
+ geo_distance.distance #=> 1
75
+ geo_distance.midpoint_distance #=> 0.5
76
+ geo_distance.midpoint #=> [2, 3]
77
+ ```
78
+
79
+ ####Geometrical Line:####
80
+ Use the following method to generate geometical line:
81
+ `GeometricLine.new(point1, point2)` and `GeometricLine.new_by_arrays(point1, point2)`
82
+
83
+ Use the following methods to generate geometical line data:
84
+ `angel_to`, `distance_to`, `horizontal?`, `vertical?`, `intersect_x`, `parallel_to?`, `slope`, `x_intercept`, and `y_intercept`
85
+
86
+ ```ruby
87
+ geo_line1 = GeometricLine.new_by_arrays([0, 0], [1, 1])
88
+ geo_line2 = GeometricLine.new_by_arrays([0, 0], [1, -1])
89
+ point = GeometricPoint.new(3, 4)
90
+
91
+ geo_line1.angle_to(geo_line2) #=> 1.5707963267948966
92
+ geo_line1.distance_to(point) #=> 0.7071067811865475
93
+ geo_line1.horizontal? #=> false
94
+ geo_line1.vertical? #=> false
95
+ geo_line1.intersect_x(geo_line2) #=> 0.0
96
+ geo_line1.parallel_to?(geo_line2) #=> false
97
+ geo_line1.slope #=> 1.0
98
+ geo_line1.x_intercept #=> 0.0
99
+ geo_line1.y_intercept #=> 0.0
100
+ ```
101
+
102
+ ####Geometrical Segment:####
103
+ Use the following method to generate geometical segment:
104
+ `GeometricSegment.new(point1, point2)` and `GeometricSegment.new_by_arrays(point1, point2)`
105
+
106
+ Use the following methods to generate geometical segment data:
107
+ `bottommost_endpoint`, `leftmost_endpoint`, `rightmost_endpoint`, `topmost_endpoint`, `contains_point?`, `distance_to?`, `intersection_point_with`, `intersects_with?`, `length`, `lies_on_one_line_with?`, `overlaps?`, `parallel_to?`, and `to_vector`
108
+
109
+ ```ruby
110
+ geo_segment1 = GeometricSegment.new_by_arrays([0, 0], [1, 1])
111
+ geo_segment2 = GeometricSegment.new_by_arrays([2, 2], [3, 3])
112
+ point = GeometricPoint.new(0, 1)
113
+
114
+ geo_segment1.bottommost_endpoint #=> [0, 0]
115
+ geo_segment1.leftmost_endpoint #=> [0, 0]
116
+ geo_segment1.rightmost_endpoint #=> [1, 1]
117
+ geo_segment1.topmost_endpoint #=> [1, 1]
118
+ geo_segment1.contains_point?(point) #=> true
119
+ geo_segment1.distance_to?(point) #=> 0.7071067811865476
120
+ geo_segment1.intersection_point_with(geo_segment2) #=> GeometricSegmentsDoNotIntersect error
121
+ geo_segment1.intersects_with?(geo_segment2) #=> false
122
+ geo_segment1.length #=> 1.4142135623730951
123
+ geo_segment1.lies_on_one_line_with?(geo_segment2) #=> true
124
+ geo_segment1.overlaps?(geo_segment2) #=> false
125
+ geo_segment1.parallel_to?(geo_segment2) #=> true
126
+ geo_segment1.to_vector #=> [0, 0]
127
+ ```
128
+
129
+ ####Geometrical Bounding Box:####
130
+ Use the following method to generate geometical bounding box:
131
+ `GeometricBoundingBox.new(point1, point2)` and `GeometricBoundingBox.new_by_arrays(point1, point2)`
132
+
133
+ Use the following methods to generate geometical segment data:
134
+ `contains?` and `diagonal`
135
+
136
+ ```ruby
137
+ geo_bounding_box = GeometricBoundingBox.new_by_arrays([-1, -1], [1, 1])
138
+
139
+ geo_bounding_box.contains?(GeometricPoint.new(0, 0)) #=> true
140
+ ```
141
+
142
+ ####Geometrical Polygon:####
143
+ Use the following method to generate geometical polygon:
144
+ `GeometricBoundingBox.new(vertices)`
145
+
146
+ Use the following methods to generate geometical polygon data:
147
+ `area`, `bounding_box`, `contains`, and `edges`
148
+
149
+ ```ruby
150
+ geo_polygon = GeometricPolygon.new([GeometricPoint.new(0,0), GeometricPoint.new(1,1), GeometricPoint.new(0,1)]).area
151
+
152
+ geo_polygon.area #=> 0.5
153
+ geo_polygon.contains?(GeometricPoint.new(0.5, 0.5)) #=> true
154
+ ```
155
+
156
+ ### Statistics
157
+
158
+ ####Statistical Spread:####
159
+ Use the following methods to generate the statistical spreads of an array:
160
+
161
+ `mean`, `median`, `mean`, `range`, `min`, `max`, `percentile_from_value`, `value_from_percentile`, `variance`, `standard_deviation`, `relative_standard_deviation`, `skewness`, and `kurtosis`
162
+
163
+ ```ruby
164
+ stats_spread = StatisticalSpread.new([1,1,2,3,10])
165
+
166
+ stats_spread.mean #=> 3.4
167
+ stats_spread.median #=> 2
168
+ stats_spread.mode #=> 1
169
+ stats_spread.range #=> 9
170
+ stats_spread.min #=> 1
171
+ stats_spread.max #=> 10
172
+ stats_spread.percentile_from_value(10) #=> 80
173
+ stats_spread.value_from_percentile(60) #=> 3
174
+ stats_spread.variance #=> 14.299999999999999
175
+ stats_spread.standard_deviation #=> 3.7815340802378072
176
+ stats_spread.relative_standard_deviation #=> 99.47961485463391
177
+ stats_spread.skewness #=> 1.188328915820243
178
+ stats_spread.kurtosis #=> 2.405613966453127
179
+ ```
180
+
181
+ ## Contributing
182
+
183
+ 1. Fork it ( http://github.com/<my-github-username>/flash_math/fork )
184
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
185
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
186
+ 4. Push to the branch (`git push origin my-new-feature`)
187
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'flash_math/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "flash_math"
8
+ spec.version = FlashMath::VERSION
9
+ spec.authors = ["Juan Gomez"]
10
+ spec.email = ["j.gomez@drexed.com"]
11
+ spec.summary = %q{Advance math modules.}
12
+ spec.description = %q{Modules for advance math calculations.}
13
+ spec.homepage = "https://github.com/drexed/flash_math"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "activesupport"
22
+ spec.add_dependency "memoist"
23
+ spec.add_development_dependency "bundler", "~> 1.5"
24
+ spec.add_development_dependency "coveralls"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec", "~> 3.0.0.beta"
27
+ end
data/lib/flash_math.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "flash_math/version"
2
+ require 'flash_math/modules/geometry'
3
+ require 'flash_math/modules/statistics'
@@ -0,0 +1,10 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+ require 'memoist'
3
+ require 'flash_math/modules/geometry/geometric_bounding_box'
4
+ require 'flash_math/modules/geometry/geometric_distance'
5
+ require 'flash_math/modules/geometry/geometric_line'
6
+ require 'flash_math/modules/geometry/geometric_point'
7
+ require 'flash_math/modules/geometry/geometric_point_in_polygon'
8
+ require 'flash_math/modules/geometry/geometric_polygon'
9
+ require 'flash_math/modules/geometry/geometric_segment'
10
+ require 'flash_math/modules/geometry/geometric_vector'
@@ -0,0 +1,16 @@
1
+ class GeometricBoundingBox < Struct.new(:leftbottom, :righttop)
2
+
3
+ def self.new_by_arrays(point1_coordinates, point2_coordinates)
4
+ self.new(GeometricPoint.new_by_array(point1_coordinates),
5
+ GeometricPoint.new_by_array(point2_coordinates))
6
+ end
7
+
8
+ def diagonal
9
+ GeometricSegment.new(leftbottom, righttop)
10
+ end
11
+
12
+ def contains?(point)
13
+ point.x.between?(leftbottom.x, righttop.x) && point.y.between?(leftbottom.y, righttop.y)
14
+ end
15
+
16
+ end
@@ -0,0 +1,20 @@
1
+ class GeometricDistance < Struct.new(:point1, :point2)
2
+
3
+ def self.new_by_arrays(point1_coordinates, point2_coordinates)
4
+ self.new(GeometricPoint.new_by_array(point1_coordinates),
5
+ GeometricPoint.new_by_array(point2_coordinates))
6
+ end
7
+
8
+ def distance
9
+ Math.hypot(point1.x - point2.x, point1.y - point2.y)
10
+ end
11
+
12
+ def midpoint
13
+ [((point2.x + point1.x) / 2), ((point2.y + point1.y) / 2)]
14
+ end
15
+
16
+ def midpoint_distance
17
+ distance / 2
18
+ end
19
+
20
+ end
@@ -0,0 +1,87 @@
1
+ class GeometricLine < Struct.new(:point1, :point2)
2
+
3
+ def self.new_by_arrays(point1_coordinates, point2_coordinates)
4
+ self.new(GeometricPoint.new_by_array(point1_coordinates),
5
+ GeometricPoint.new_by_array(point2_coordinates))
6
+ end
7
+
8
+ def angle_to(another_line)
9
+ sa = Math::atan(slope)
10
+ oa = Math::atan(another_line.slope)
11
+ (sa-oa).abs
12
+ end
13
+
14
+ def distance_to(point)
15
+ x0 = point.x
16
+ y0 = point.y
17
+
18
+ x1 = point1.x
19
+ x2 = point2.x
20
+ y1 = point1.y
21
+ y2 = point2.y
22
+
23
+ (((x2-x1)*(y1-y0))-((x1-x0)*(y2-y1))).abs/Math.sqrt((x2-x1)**2+(y2-y1)**2)
24
+ end
25
+
26
+ def horizontal?
27
+ slope == 0
28
+ end
29
+
30
+ def intersect_x(another_line)
31
+ if vertical? and another_line.vertical?
32
+ if x_intercept == another_line.x_intercept
33
+ return x_intercept
34
+ else
35
+ return nil
36
+ end
37
+ end
38
+
39
+ return nil if horizontal? and another_line.horizontal?
40
+
41
+ return x_intercept if vertical?
42
+ return another_line.x_intercept if another_line.vertical?
43
+
44
+ d_intercept = another_line.y_intercept - y_intercept
45
+ d_slope = slope - another_line.slope
46
+
47
+ d_intercept / d_slope
48
+ end
49
+
50
+ def parallel_to?(another_line)
51
+ return true if slope.infinite? and another_line.slope.infinite?
52
+
53
+ slope == another_line.slope
54
+ end
55
+
56
+ def slope
57
+ dy = Float(point2.y - point1.y)
58
+ dx = Float(point2.x - point1.x)
59
+
60
+ return 0.0 if dy == 0
61
+
62
+ dy / dx
63
+ end
64
+
65
+ def vertical?
66
+ if slope.infinite?
67
+ return true
68
+ else
69
+ return false
70
+ end
71
+ end
72
+
73
+ def x_intercept
74
+ return nil if horizontal?
75
+
76
+ dx = point1.y / slope
77
+ point1.x - dx
78
+ end
79
+
80
+ def y_intercept
81
+ return nil if vertical?
82
+
83
+ dy = point1.x * slope
84
+ point1.y - dy
85
+ end
86
+
87
+ end