cartesius 1.1.0 → 1.1.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.
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.