cartesius 1.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 69e7a9e2b6c6f4edb2bcc0cd73e5f909ee2eed07
4
- data.tar.gz: 4eda3671a45184320a8485a0bd389df017bc8b8f
2
+ SHA256:
3
+ metadata.gz: 1a2864a5e8f19fdf96b0dc7f1bcd71b773b7407de108a7619a7739321eaaccab
4
+ data.tar.gz: 96a0970a6fb936d2851ad2438765bf87e9fc0b6f9e53a955e522100556bc423b
5
5
  SHA512:
6
- metadata.gz: 005e1721917eb39048995f4567a084c53ec9bdc66f2d95ca78ae2a827ae9bb19561747072ac257f697c46d2fc572e2a4175c897feedd929408a7d1fe438cbc8b
7
- data.tar.gz: 01db7a237a5fa5edc13314dee6503120f9e232f65665e1cba2a3c9d830c1d9bbf68da95f367bc634e3af493d51b3e004eff202b9f4250665504e212643a8c8b0
6
+ metadata.gz: 4730b97e60e48b29feb4f33cee385876227a3f7929be22b9c5d4caa5cf1d1cb39147b73ba8655c54f141e048a9c3048b7c1e324474218644e391dea0d38c0c24
7
+ data.tar.gz: 3d2bda2e42c5bb140c57c5aaf1313839ec72ead6e10ae5777f2ed04f3e51a074d38adef229aada5b5e505943af1d1480e22e36d4fcd530bd067170dd8c0f0d8b
@@ -1,3 +1,6 @@
1
+ require('cartesius/neighbourhoods')
2
+ require('cartesius/tolerance')
3
+
1
4
  module Cartesius
2
5
  class Angle
3
6
  NULL, RIGHT, FLAT, FULL = 0, 90, 180, 360
@@ -7,6 +10,7 @@ module Cartesius
7
10
  private_constant(:FULL)
8
11
 
9
12
  def initialize(angle)
13
+ validation(angle)
10
14
  @angle = angle
11
15
  end
12
16
 
@@ -46,8 +50,8 @@ module Cartesius
46
50
  by_degrees(FULL)
47
51
  end
48
52
 
49
- def degrees(precision = 3)
50
- @angle.round(precision)
53
+ def degrees
54
+ @angle
51
55
  end
52
56
 
53
57
  def radiants(precision = 3)
@@ -55,38 +59,44 @@ module Cartesius
55
59
  end
56
60
 
57
61
  def null?
58
- degrees == NULL
62
+ OpenNeighbourhood.new(NULL, Tolerance::TOLERANCE).include?(degrees)
59
63
  end
60
64
 
61
65
  def acute?
62
- degrees > NULL and degrees < RIGHT
66
+ CloseNeighbourhood.new(45, 45 - Tolerance::TOLERANCE).include?(degrees)
63
67
  end
64
68
 
65
69
  def right?
66
- degrees == RIGHT
70
+ OpenNeighbourhood.new(RIGHT, Tolerance::TOLERANCE).include?(degrees)
67
71
  end
68
72
 
69
73
  def obtuse?
70
- degrees > RIGHT and degrees < FLAT
74
+ CloseNeighbourhood.new(135, 45 - Tolerance::TOLERANCE).include?(degrees)
71
75
  end
72
76
 
73
77
  def flat?
74
- degrees == FLAT
78
+ OpenNeighbourhood.new(FLAT, Tolerance::TOLERANCE).include?(degrees)
75
79
  end
76
80
 
77
81
  def full?
78
- degrees == FULL
82
+ OpenNeighbourhood.new(FULL, Tolerance::TOLERANCE).include?(degrees)
79
83
  end
80
84
 
81
- def congruent?(angle)
82
- angle.instance_of?(self.class) and
83
- angle.degrees == degrees
85
+ def congruent?(other)
86
+ other.instance_of?(self.class) &&
87
+ OpenNeighbourhood.new(NULL, Tolerance::TOLERANCE).include?((other.degrees - degrees).abs)
84
88
  end
85
89
 
86
90
  alias_method(:eql?, :congruent?)
87
91
 
88
92
  private
89
93
 
94
+ def validation(angle)
95
+ if angle < NULL || angle > FULL
96
+ raise ArgumentError.new('Invalid angle!')
97
+ end
98
+ end
99
+
90
100
  def hash
91
101
  @angle.hash
92
102
  end
@@ -59,13 +59,13 @@ module Cartesius
59
59
  end
60
60
 
61
61
  def congruent?(circumference)
62
- circumference.instance_of?(self.class) and
62
+ circumference.instance_of?(self.class) &&
63
63
  circumference.radius == radius
64
64
  end
65
65
 
66
66
  def == (circumference)
67
- circumference.instance_of?(self.class) and
68
- circumference.center == center and circumference.radius == radius
67
+ circumference.instance_of?(self.class) &&
68
+ circumference.center == center && circumference.radius == radius
69
69
  end
70
70
 
71
71
  def self.build_by(center, radius)
@@ -0,0 +1,67 @@
1
+ require('matrix')
2
+
3
+ class Cramer
4
+
5
+ def self.solution1(row1, known_term)
6
+ matrix = Matrix.rows([row1])
7
+
8
+ determinant = matrix.determinant
9
+ if determinant.zero?
10
+ raise ArgumentError.new('The determinant is zero!')
11
+ end
12
+
13
+ x1 = Rational(
14
+ Matrix.columns([known_term]).determinant,
15
+ determinant
16
+ )
17
+
18
+ [x1]
19
+ end
20
+
21
+ def self.solution2(row1, row2, known_term)
22
+ matrix = Matrix.rows([row1, row2])
23
+
24
+ determinant = matrix.determinant
25
+ if determinant.zero?
26
+ raise ArgumentError.new('The determinant is zero!')
27
+ end
28
+
29
+ x1 = Rational(
30
+ Matrix.columns([known_term, matrix.column(1)]).determinant,
31
+ determinant
32
+ )
33
+
34
+ x2 = Rational(
35
+ Matrix.columns([matrix.column(0), known_term]).determinant,
36
+ determinant
37
+ )
38
+
39
+ [x1, x2]
40
+ end
41
+
42
+ def self.solution3(row1, row2, row3, known_term)
43
+ matrix = Matrix.rows([row1, row2, row3])
44
+
45
+ determinant = matrix.determinant
46
+ if determinant.zero?
47
+ raise ArgumentError.new('The determinant is zero!')
48
+ end
49
+
50
+ x1 = Rational(
51
+ Matrix.columns([known_term, matrix.column(1), matrix.column(2)]).determinant,
52
+ determinant
53
+ )
54
+
55
+ x2 = Rational(
56
+ Matrix.columns([matrix.column(0), known_term, matrix.column(2)]).determinant,
57
+ determinant
58
+ )
59
+
60
+ x3 = Rational(
61
+ Matrix.columns([matrix.column(0), matrix.column(1), known_term]).determinant,
62
+ determinant
63
+ )
64
+
65
+ [x1, x2, x3]
66
+ end
67
+ end
@@ -0,0 +1,30 @@
1
+ module Determinator
2
+
3
+ def center
4
+ Cartesius::Point.new(
5
+ x: Rational(-@x_coeff, (2 * @x2_coeff)),
6
+ y: Rational(-@y_coeff, (2 * @y2_coeff))
7
+ )
8
+ end
9
+
10
+ def to_equation
11
+ equationfy(
12
+ 'x^2' => @x2_coeff, 'y^2' => @y2_coeff, 'x' => @x_coeff, 'y' => @y_coeff, '1' => @k_coeff
13
+ )
14
+ end
15
+
16
+ private
17
+
18
+ def a2
19
+ Rational((determinator - @k_coeff).abs, (@x2_coeff).abs)
20
+ end
21
+
22
+ def b2
23
+ Rational((determinator - @k_coeff).abs, (@y2_coeff).abs)
24
+ end
25
+
26
+ def determinator
27
+ (@x2_coeff * (center.x**2)) + (@y2_coeff * (center.y**2))
28
+ end
29
+
30
+ end
@@ -48,15 +48,15 @@ module Cartesius
48
48
  raise ArgumentError.new('Axes must be different!')
49
49
  end
50
50
 
51
- if major_axis.inclined? or minor_axis.inclined?
51
+ if major_axis.inclined? || minor_axis.inclined?
52
52
  raise ArgumentError.new('Axes must not be inclined!')
53
53
  end
54
54
 
55
- if major_axis.horizontal? and minor_axis.horizontal?
55
+ if major_axis.horizontal? && minor_axis.horizontal?
56
56
  raise ArgumentError.new('Axes can not be both horizontal!')
57
57
  end
58
58
 
59
- if major_axis.vertical? and minor_axis.vertical?
59
+ if major_axis.vertical? && minor_axis.vertical?
60
60
  raise ArgumentError.new('Axes can not be both vertical!')
61
61
  end
62
62
 
@@ -78,7 +78,7 @@ module Cartesius
78
78
  end
79
79
 
80
80
  def self.by_points(center:, point1:, point2:)
81
- if center == point1 or center == point2 or point1 == point2
81
+ if center == point1 || center == point2 || point1 == point2
82
82
  raise ArgumentError.new('Points must be different!')
83
83
  end
84
84
 
@@ -151,13 +151,13 @@ module Cartesius
151
151
  end
152
152
 
153
153
  def congruent?(ellipse)
154
- ellipse.instance_of?(self.class) and
154
+ ellipse.instance_of?(self.class) &&
155
155
  ellipse.eccentricity == eccentricity
156
156
  end
157
157
 
158
158
  def == (ellipse)
159
- ellipse.instance_of?(self.class) and
160
- ellipse.focus1 == focus1 and ellipse.focus2 == focus2 and ellipse.distance == distance
159
+ ellipse.instance_of?(self.class) &&
160
+ ellipse.focus1 == focus1 && ellipse.focus2 == focus2 && ellipse.distance == distance
161
161
  end
162
162
 
163
163
  def self.build_by(a2, b2, center)
@@ -169,7 +169,7 @@ module Cartesius
169
169
  private
170
170
 
171
171
  def validation
172
- if @x2_coeff <= 0 or @y2_coeff <= 0 or @x2_coeff == @y2_coeff or determinator <= @k_coeff
172
+ if @x2_coeff <= 0 || @y2_coeff <= 0 || @x2_coeff == @y2_coeff || determinator <= @k_coeff
173
173
  raise ArgumentError.new('Invalid coefficients!')
174
174
  end
175
175
  end
@@ -55,15 +55,15 @@ module Cartesius
55
55
  raise ArgumentError.new('Axes must be different!')
56
56
  end
57
57
 
58
- if transverse_axis.inclined? or not_transverse_axis.inclined?
58
+ if transverse_axis.inclined? || not_transverse_axis.inclined?
59
59
  raise ArgumentError.new('Axes must not be inclined!')
60
60
  end
61
61
 
62
- if transverse_axis.horizontal? and not_transverse_axis.horizontal?
62
+ if transverse_axis.horizontal? && not_transverse_axis.horizontal?
63
63
  raise ArgumentError.new('Axes can not be both horizontal!')
64
64
  end
65
65
 
66
- if transverse_axis.vertical? and not_transverse_axis.vertical?
66
+ if transverse_axis.vertical? && not_transverse_axis.vertical?
67
67
  raise ArgumentError.new('Axes can not be both vertical!')
68
68
  end
69
69
 
@@ -87,7 +87,7 @@ module Cartesius
87
87
  end
88
88
 
89
89
  def self.by_points(center:, vertex:, point:)
90
- if center == vertex or center == point or vertex == point
90
+ if center == vertex || center == point || vertex == point
91
91
  raise ArgumentError.new('Points must be different!')
92
92
  end
93
93
 
@@ -181,13 +181,13 @@ module Cartesius
181
181
  end
182
182
 
183
183
  def congruent?(hyperbola)
184
- hyperbola.instance_of?(self.class) and
184
+ hyperbola.instance_of?(self.class) &&
185
185
  hyperbola.eccentricity == eccentricity
186
186
  end
187
187
 
188
188
  def == (hyperbola)
189
- hyperbola.instance_of?(self.class) and
190
- hyperbola.focus1 == focus1 and hyperbola.focus2 == focus2 and hyperbola.distance == distance
189
+ hyperbola.instance_of?(self.class) &&
190
+ hyperbola.focus1 == focus1 && hyperbola.focus2 == focus2 && hyperbola.distance == distance
191
191
  end
192
192
 
193
193
  def self.build_by(a2, b2, center, position)
@@ -199,7 +199,7 @@ module Cartesius
199
199
  private
200
200
 
201
201
  def validation
202
- if signum(@x2_coeff * @y2_coeff) >= 0 or determinator == @k_coeff
202
+ if signum(@x2_coeff * @y2_coeff) >= 0 || determinator == @k_coeff
203
203
  raise ArgumentError.new('Invalid coefficients!')
204
204
  end
205
205
  end
@@ -102,11 +102,11 @@ module Cartesius
102
102
  end
103
103
 
104
104
  def inclined?
105
- ascending? or descending?
105
+ ascending? || descending?
106
106
  end
107
107
 
108
108
  def ascending?
109
- slope != VERTICAL_SLOPE and slope > HORIZONTAL_SLOPE
109
+ slope != VERTICAL_SLOPE && slope > HORIZONTAL_SLOPE
110
110
  end
111
111
 
112
112
  def descending?
@@ -156,14 +156,14 @@ module Cartesius
156
156
  end
157
157
 
158
158
  def == (line)
159
- line.instance_of?(self.class) and
160
- line.slope == slope and line.known_term == known_term
159
+ line.instance_of?(self.class) &&
160
+ line.slope == slope && line.known_term == known_term
161
161
  end
162
162
 
163
163
  private
164
164
 
165
165
  def validation
166
- if @x_coeff.zero? and @y_coeff.zero?
166
+ if @x_coeff.zero? && @y_coeff.zero?
167
167
  raise ArgumentError.new('Invalid coefficients!')
168
168
  end
169
169
  end
@@ -0,0 +1,31 @@
1
+ class OpenNeighbourhood
2
+ def initialize(center, width)
3
+ @center = center
4
+ @width = width
5
+ end
6
+
7
+ def include?(value)
8
+ (value > @center - @width) && (value < @center + @width)
9
+ end
10
+ end
11
+
12
+ class CloseNeighbourhood
13
+ def initialize(center, width)
14
+ @center = center
15
+ @width = width
16
+ end
17
+
18
+ def include?(value)
19
+ (value >= @center - @width) && (value <= @center + @width)
20
+ end
21
+ end
22
+
23
+ class InfinityNeighbourhood
24
+ def initialize(width)
25
+ @width = width
26
+ end
27
+
28
+ def include?(value)
29
+ (value < -@width) && (value > @width)
30
+ end
31
+ end
@@ -0,0 +1,66 @@
1
+ module Numerificator
2
+
3
+ private
4
+
5
+ def equationfy(coefficients)
6
+ coefficients.delete_if {|_, value| value.zero?}
7
+
8
+ if coefficients.first.last < 0
9
+ coefficients.each {|k, v| coefficients[k] = -v}
10
+ end
11
+
12
+ equation = []
13
+ coefficients.each do |key, value|
14
+ if key == '1'
15
+ equation << [monomial(value)]
16
+ else
17
+ equation << [monomial(value, key)]
18
+ end
19
+ end
20
+ equation << ['=', '0']
21
+
22
+ equation.join(' ')
23
+ end
24
+
25
+ def stringfy(number)
26
+ if number.denominator == 1
27
+ return number.numerator.to_s
28
+ end
29
+ number.to_s
30
+ end
31
+
32
+ # TODO: test
33
+ def numberfy(numerator, denominator)
34
+ if denominator == 1
35
+ numerator
36
+ elsif denominator == -1
37
+ -numerator
38
+ else
39
+ Rational(numerator, denominator)
40
+ end
41
+ end
42
+
43
+ def monomial(number_part, letter_part = nil)
44
+ number_string = if number_part.denominator == 1
45
+ number_part.numerator.abs.to_s
46
+ else
47
+ "(#{number_part.abs})"
48
+ end
49
+ "#{signum_symbol(number_part)}#{number_string}#{letter_part}"
50
+ end
51
+
52
+ def signum(number)
53
+ number < 0 ? -1 : 1
54
+ end
55
+
56
+ def signum_symbol(number)
57
+ number >= 0 ? '+' : '-'
58
+ end
59
+
60
+ def normalize(*coefficients)
61
+ sign = signum(coefficients.first.to_r)
62
+ coefficients.map! {|coefficient| sign * coefficient.to_r}
63
+ end
64
+
65
+
66
+ end
@@ -71,13 +71,13 @@ module Cartesius
71
71
  end
72
72
 
73
73
  def congruent?(parabola)
74
- parabola.instance_of?(self.class) and
74
+ parabola.instance_of?(self.class) &&
75
75
  parabola.eccentricity == eccentricity
76
76
  end
77
77
 
78
78
  def == (parabola)
79
- parabola.instance_of?(self.class) and
80
- parabola.focus == focus and parabola.directrix == directrix
79
+ parabola.instance_of?(self.class) &&
80
+ parabola.focus == focus && parabola.directrix == directrix
81
81
  end
82
82
 
83
83
  private
@@ -1,3 +1,4 @@
1
+ require('cartesius/neighbourhoods')
1
2
  require('cartesius/numerificator')
2
3
 
3
4
  module Cartesius
@@ -34,8 +35,8 @@ module Cartesius
34
35
  end
35
36
 
36
37
  def == (point)
37
- point.instance_of?(self.class) and
38
- point.x == @x and point.y == @y
38
+ point.instance_of?(self.class) &&
39
+ point.x == @x && point.y == @y
39
40
  end
40
41
 
41
42
  alias_method(:eql?, :==)
@@ -35,17 +35,19 @@ module Cartesius
35
35
  end
36
36
 
37
37
  def congruent?(segment)
38
- segment.instance_of?(self.class) and
38
+ segment.instance_of?(self.class) &&
39
39
  segment.length == self.length
40
40
  end
41
41
 
42
42
  def == (segment)
43
- segment.instance_of?(self.class) and (
44
- (segment.extreme1 == extreme1 and segment.extreme2 == extreme2) or
45
- (segment.extreme1 == extreme2 and segment.extreme2 == extreme1)
43
+ segment.instance_of?(self.class) && (
44
+ (segment.extreme1 == extreme1 && segment.extreme2 == extreme2) ||
45
+ (segment.extreme1 == extreme2 && segment.extreme2 == extreme1)
46
46
  )
47
47
  end
48
48
 
49
+ alias_method(:eql?, :congruent?)
50
+
49
51
  private
50
52
 
51
53
  def validation
@@ -54,6 +56,10 @@ module Cartesius
54
56
  end
55
57
  end
56
58
 
59
+ def hash
60
+ length.hash
61
+ end
62
+
57
63
  end
58
64
 
59
65
  end
@@ -0,0 +1,3 @@
1
+ module Tolerance
2
+ TOLERANCE = Rational(1, 100)
3
+ end
@@ -40,19 +40,19 @@ module Cartesius
40
40
  end
41
41
 
42
42
  def acute?
43
- not rectangle? and not obtuse?
43
+ !rectangle? && !obtuse?
44
44
  end
45
45
 
46
- def equilateral?(precision = 2)
47
- sides_congruent(precision) == 1
46
+ def equilateral?
47
+ sides_congruent == 1
48
48
  end
49
49
 
50
- def isosceles?(precision = 2)
51
- equilateral? or sides_congruent(precision) == 2
50
+ def isosceles?
51
+ equilateral? || sides_congruent == 2
52
52
  end
53
53
 
54
- def scalene?(precision = 2)
55
- sides_congruent(precision) == 3
54
+ def scalene?
55
+ sides_congruent == 3
56
56
  end
57
57
 
58
58
  def perimeter
@@ -64,17 +64,17 @@ module Cartesius
64
64
  end
65
65
 
66
66
  def == (triangle)
67
- triangle.instance_of?(self.class) and
67
+ triangle.instance_of?(self.class) &&
68
68
  triangle.vertices.values.to_set == vertices.values.to_set
69
69
  end
70
70
 
71
71
  def congruent? (triangle)
72
- triangle.instance_of?(self.class) and
72
+ triangle.instance_of?(self.class) &&
73
73
  sides_length(triangle) == sides_length(self)
74
74
  end
75
75
 
76
76
  def similar?(triangle)
77
- triangle.instance_of?(self.class) and
77
+ triangle.instance_of?(self.class) &&
78
78
  triangle.angles.values.to_set == angles.values.to_set
79
79
  end
80
80
 
@@ -94,11 +94,11 @@ module Cartesius
94
94
  end
95
95
 
96
96
  def sides_length(triangle)
97
- triangle.sides.values.collect(&:length).sort
97
+ triangle.sides.values.collect(&:length)
98
98
  end
99
99
 
100
- def sides_congruent(precision)
101
- sides_length(self).map {|side| side.round(precision)}.uniq.count
100
+ def sides_congruent
101
+ sides_length(self).map {|s| s.round(3)}.to_set.count
102
102
  end
103
103
 
104
104
  end
@@ -0,0 +1,23 @@
1
+ require('cartesius/line')
2
+
3
+ module Cartesius
4
+
5
+ class Validator
6
+ def self.same_points(points)
7
+ if points.count != points.to_set.count
8
+ raise ArgumentError.new('Points must be distinct!')
9
+ end
10
+ end
11
+
12
+ # TODO: cambiare nome... ne bastano 3 allineati, ma se sono 4 per eccezione ne bastano tre allineati.
13
+ def self.aligned_points(points)
14
+ if points.count >= 3
15
+ line = Line.by_points(point1: points.shift, point2: points.pop)
16
+ points.each do |point|
17
+ raise ArgumentError.new('Points must not be aligned!') if line.include?(point)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cartesius
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mauro Quaglia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-05 00:00:00.000000000 Z
11
+ date: 2019-10-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: The cartesian plan and its elements.
14
14
  email: mauroquaglia@libero.it
@@ -18,13 +18,19 @@ extra_rdoc_files: []
18
18
  files:
19
19
  - lib/cartesius/angle.rb
20
20
  - lib/cartesius/circumference.rb
21
+ - lib/cartesius/cramer.rb
22
+ - lib/cartesius/determinator.rb
21
23
  - lib/cartesius/ellipse.rb
22
24
  - lib/cartesius/hyperbola.rb
23
25
  - lib/cartesius/line.rb
26
+ - lib/cartesius/neighbourhoods.rb
27
+ - lib/cartesius/numerificator.rb
24
28
  - lib/cartesius/parabola.rb
25
29
  - lib/cartesius/point.rb
26
30
  - lib/cartesius/segment.rb
31
+ - lib/cartesius/tolerance.rb
27
32
  - lib/cartesius/triangle.rb
33
+ - lib/cartesius/validator.rb
28
34
  homepage: https://github.com/MauroQuaglia/cartesius
29
35
  licenses:
30
36
  - MIT
@@ -37,15 +43,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
37
43
  requirements:
38
44
  - - ">="
39
45
  - !ruby/object:Gem::Version
40
- version: 2.1.0
46
+ version: '0'
41
47
  required_rubygems_version: !ruby/object:Gem::Requirement
42
48
  requirements:
43
49
  - - ">="
44
50
  - !ruby/object:Gem::Version
45
51
  version: '0'
46
52
  requirements: []
47
- rubyforge_project:
48
- rubygems_version: 2.6.14
53
+ rubygems_version: 3.0.4
49
54
  signing_key:
50
55
  specification_version: 4
51
56
  summary: The cartesian coordinate system.