cartesius 0.0.1 → 1.0.0

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
2
  SHA1:
3
- metadata.gz: 95fd724a37b3fd9e2e072f649cd34ffcd6ade1bd
4
- data.tar.gz: 304ab894b81c52b1d02c63076be66879a20319f7
3
+ metadata.gz: 8ca7c08a027f0547ece43bf75d1d622aa7a59279
4
+ data.tar.gz: 9b95391ad0010c8dd2cb1eb11a37933e2fa74b2f
5
5
  SHA512:
6
- metadata.gz: 5f3b5b319332a590bcd796952e58328cbafa0b6857fea724bc796cbdc72520c715a167d063bf3510a5db5617cb52c49e55b75938c42c69c484a47a82a817471e
7
- data.tar.gz: 3abcc3dc0cdc72e7878dbb1c55cf7c4d887f1fe464e228083e993e0d11f4952ee9769c9afaf34cfc69212e51f848f56c32bc08b808cf1f2c259b941006bdc50d
6
+ metadata.gz: 6b141b69ced00426c9c461e07bec394bacf3a625058c68ee101caa3f8886c21711342a920d2adfd29fc3fadc2094a108354ca004ad47a891a5830f306d4370d6
7
+ data.tar.gz: b37537b3e28b9973c9d2981742cc52e6a2b181a1bc7342407af1e37d96fff7d343ed5199f4fce435c5d344909906a83d252541380e720a8cbb1d9c29bb5cb3f9
@@ -11,57 +11,56 @@ module Cartesius
11
11
  # Conic
12
12
  # Conic equation type: x^2 + y^2 + dx + ey + f = 0
13
13
  def initialize(x:, y:, k:)
14
- @x2_coeff, @y2_coeff, @x_coeff, @y_coeff, @k_coeff = 1, 1, x.to_r, y.to_r, k.to_r
14
+ @x2_coeff, @y2_coeff, @x_coeff, @y_coeff, @k_coeff = normalize(1, 1, x, y, k)
15
15
  validation
16
16
  end
17
17
 
18
- def self.by_definition(focus:, radius:)
19
- alfa = -2 * focus.x
20
- beta = -2 * focus.y
21
- gamma = focus.x ** 2 + focus.y ** 2 - radius.to_r ** 2
18
+ def self.by_definition(center:, radius:)
19
+ if radius <= 0
20
+ raise ArgumentError.new('Radius must be positive!')
21
+ end
22
22
 
23
- self.new(x: alfa, y: beta, k: gamma)
23
+ build_by(center, radius)
24
24
  end
25
25
 
26
- def self.by_canonical(focus:, radius:)
27
- by_definition(focus: focus, radius: radius)
26
+ def self.by_diameter(diameter:)
27
+ center = diameter.mid
28
+ radius = Rational(diameter.length, 2)
29
+
30
+ build_by(center, radius)
28
31
  end
29
32
 
30
33
  def self.by_points(point1:, point2:, point3:)
31
- if point1 == point2 or point1 == point3 or point2 == point3
32
- raise ArgumentError.new('Points must be distinct!')
33
- end
34
-
35
- line = Line.by_points(point1: point1, point2: point2)
36
- if line.include?(point3)
37
- raise ArgumentError.new('Points must not be aligned!')
38
- end
39
-
40
34
  alfa, beta, gamma = Cramer.solution3(
41
35
  [point1.x, point1.y, 1],
42
36
  [point2.x, point2.y, 1],
43
37
  [point3.x, point3.y, 1],
44
38
  [-(point1.x ** 2 + point1.y ** 2), -(point2.x ** 2 + point2.y ** 2), -(point3.x ** 2 + point3.y ** 2)]
45
39
  )
46
-
47
40
  self.new(x: alfa, y: beta, k: gamma)
41
+ rescue
42
+ raise ArgumentError.new('Invalid points!')
48
43
  end
49
44
 
50
-
51
- def self.unitary
52
- new(x: 0, y: 0, k: -1)
45
+ def self.goniometric
46
+ build_by(Point.origin, 1)
53
47
  end
54
48
 
55
- def center
56
- Point.new(x: centrum[:xc], y: centrum[:yc])
49
+ def goniometric?
50
+ self == Circumference.goniometric
57
51
  end
58
52
 
59
53
  def radius
60
54
  Math.sqrt(a2)
61
55
  end
62
56
 
63
- def unitary?
64
- self == Circumference.unitary
57
+ def eccentricity
58
+ 0
59
+ end
60
+
61
+ def congruent?(circumference)
62
+ circumference.instance_of?(Circumference) and
63
+ circumference.radius == self.radius
65
64
  end
66
65
 
67
66
  def == (circumference)
@@ -69,19 +68,11 @@ module Cartesius
69
68
  circumference.center == self.center and circumference.radius == self.radius
70
69
  end
71
70
 
72
- def congruent?(circumference)
73
- unless circumference.instance_of?(self.class)
74
- return false
75
- end
76
-
77
- circumference.radius == self.radius
71
+ def self.build_by(center, radius)
72
+ self.new(x: -2 * center.x, y: -2 * center.y, k: center.x ** 2 + center.y ** 2 - radius.to_r ** 2)
78
73
  end
79
74
 
80
- def to_equation
81
- equationfy(
82
- 'x^2' => @x2_coeff, 'y^2' => @y2_coeff, 'x' => @x_coeff, 'y' => @y_coeff, '1' => @k_coeff
83
- )
84
- end
75
+ private_class_method(:build_by)
85
76
 
86
77
  private
87
78
 
@@ -11,8 +11,7 @@ module Cartesius
11
11
  # Conic
12
12
  # Conic equation type: ax^2 + by^2 + dx + ey + f = 0
13
13
  def initialize(x2:, y2:, x:, y:, k:)
14
- x2, y2, x, y, k = normalize(x2, y2, x, y, k)
15
- @x2_coeff, @y2_coeff, @x_coeff, @y_coeff, @k_coeff = x2.to_r, y2.to_r, x.to_r, y.to_r, k.to_r
14
+ @x2_coeff, @y2_coeff, @x_coeff, @y_coeff, @k_coeff = normalize(x2, y2, x, y, k)
16
15
  validation
17
16
  end
18
17
 
@@ -21,42 +20,61 @@ module Cartesius
21
20
  raise ArgumentError.new('Focus points must be different!')
22
21
  end
23
22
 
24
- unless focus1.aligned_horizontally_with?(focus2) or focus1.aligned_vertically_with?(focus2)
25
- raise ArgumentError.new('Focus must be aligned to axis!')
23
+ focal_axis = Segment.new(extreme1: focus1, extreme2: focus2)
24
+ if focal_axis.inclined?
25
+ raise ArgumentError.new('Focal axis must not be inclined!')
26
26
  end
27
27
 
28
- focal_distance = Point.distance(focus1, focus2)
29
- if distance <= focal_distance
28
+ if distance <= focal_axis.length
30
29
  raise ArgumentError.new('Sum of distances must be greater than focal distance!')
31
30
  end
32
31
 
33
- center = Segment.new(extreme1: focus1, extreme2: focus2).mid
34
- c2 = Rational(focal_distance, 2) ** 2
35
- if focus1.aligned_horizontally_with?(focus2)
32
+ c2 = Rational(focal_axis.length, 2) ** 2
33
+ if focal_axis.horizontal?
36
34
  a2 = Rational(distance, 2) ** 2
37
35
  b2 = a2 - c2
38
- end
39
- if focus1.aligned_vertically_with?(focus2)
36
+ else
40
37
  b2 = Rational(distance, 2) ** 2
41
38
  a2 = b2 - c2
42
39
  end
43
40
 
44
- self.new(x2: b2, y2: a2, x: -2 * b2 * center.x, y: -2 * a2 * center.y, k: b2 * center.x ** 2 + a2 * center.y ** 2 - a2 * b2)
41
+ center = focal_axis.mid
42
+
43
+ build_by(a2, b2, center)
45
44
  end
46
45
 
47
- def self.by_canonical(center:, x_semi_axis:, y_semi_axis:)
48
- if x_semi_axis <= 0 or y_semi_axis <= 0
49
- raise ArgumentError.new('Semi axis length must be positive!')
46
+ def self.by_axes(major_axis:, minor_axis:)
47
+ if major_axis == minor_axis
48
+ raise ArgumentError.new('Axes must be different!')
50
49
  end
51
50
 
52
- if x_semi_axis == y_semi_axis
53
- raise ArgumentError.new('Semi axis length must be different!')
51
+ if major_axis.inclined? or minor_axis.inclined?
52
+ raise ArgumentError.new('Axes must not be inclined!')
54
53
  end
55
54
 
56
- b2 = y_semi_axis ** 2
57
- a2 = x_semi_axis ** 2
55
+ if major_axis.horizontal? and minor_axis.horizontal?
56
+ raise ArgumentError.new('Axes can not be both horizontal!')
57
+ end
58
58
 
59
- self.new(x2: b2, y2: a2, x: -2 * b2 * center.x, y: -2 * a2 * center.y, k: b2 * center.x ** 2 + a2 * center.y ** 2 - a2 * b2)
59
+ if major_axis.vertical? and minor_axis.vertical?
60
+ raise ArgumentError.new('Axes can not be both vertical!')
61
+ end
62
+
63
+ if major_axis.mid != minor_axis.mid
64
+ raise ArgumentError.new('Axes must be the same mid point!')
65
+ end
66
+
67
+ if major_axis.horizontal?
68
+ a2 = Rational(major_axis.length, 2) ** 2
69
+ b2 = Rational(minor_axis.length, 2) ** 2
70
+ else
71
+ a2 = Rational(minor_axis.length, 2) ** 2
72
+ b2 = Rational(major_axis.length, 2) ** 2
73
+ end
74
+
75
+ center = major_axis.mid
76
+
77
+ build_by(a2, b2, center)
60
78
  end
61
79
 
62
80
  def self.by_points(center:, point1:, point2:)
@@ -74,74 +92,62 @@ module Cartesius
74
92
  [1, 1]
75
93
  )
76
94
  rescue
77
- raise ArgumentError.new('No Ellipse for these points!')
95
+ raise ArgumentError.new('Center and points are not valid!')
78
96
  end
79
97
 
80
98
  a2 = Rational(1, alfa)
81
99
  b2 = Rational(1, beta)
82
100
 
83
- self.new(x2: b2, y2: a2, x: -2 * b2 * center.x, y: -2 * a2 * center.y, k: b2 * center.x ** 2 + a2 * center.y ** 2 - a2 * b2)
101
+ build_by(a2, b2, center)
84
102
  end
85
103
 
86
104
  def focus1
87
- if a2 > b2
88
- Point.new(x: center.x + Math.sqrt(a2 - b2), y: center.y)
89
- else
90
- Point.new(x: center.x, y: center.y + Math.sqrt(b2 - a2))
91
- end
105
+ discriminating(
106
+ lambda {Point.new(x: center.x + cx, y: center.y)},
107
+ lambda {Point.new(x: center.x, y: center.y + cy)}
108
+ )
92
109
  end
93
110
 
94
111
  def focus2
95
- if a2 > b2
96
- Point.new(x: center.x - Math.sqrt(a2 - b2), y: center.y)
97
- else
98
- Point.new(x: center.x, y: center.y - Math.sqrt(b2 - a2))
99
- end
100
- end
101
-
102
- def focal_distance
103
- Point.distance(focus1, focus2)
104
- end
105
-
106
- def center
107
- Point.new(x: centrum[:xc], y: centrum[:yc])
108
- end
109
-
110
- def sum_of_distances
111
- if a2 > b2
112
- 2 * Math.sqrt(a2)
113
- else
114
- 2 * Math.sqrt(b2)
115
- end
112
+ discriminating(
113
+ lambda {Point.new(x: center.x - cx, y: center.y)},
114
+ lambda {Point.new(x: center.x, y: center.y - cy)}
115
+ )
116
116
  end
117
117
 
118
- def x_semi_axis_length
119
- Math.sqrt(a2)
118
+ def distance
119
+ discriminating(lambda {2 * a}, lambda {2 * b})
120
120
  end
121
121
 
122
- def y_semi_axis_length
123
- Math.sqrt(b2)
122
+ def focal_axis
123
+ Segment.new(extreme1: focus1, extreme2: focus2)
124
124
  end
125
125
 
126
- def major_semi_axis
127
- [x_semi_axis_length, y_semi_axis_length].max
126
+ def major_axis
127
+ discriminating(
128
+ lambda {Segment.new(extreme1: Point.new(x: center.x - a, y: center.y), extreme2: Point.new(x: center.x + a, y: center.y))},
129
+ lambda {Segment.new(extreme1: Point.new(x: center.x, y: center.y - b), extreme2: Point.new(x: center.x, y: center.y + b))},
130
+ )
128
131
  end
129
132
 
130
- def minor_semi_axis
131
- [x_semi_axis_length, y_semi_axis_length].min
133
+ def minor_axis
134
+ discriminating(
135
+ lambda {Segment.new(extreme1: Point.new(x: center.x, y: center.y - b), extreme2: Point.new(x: center.x, y: center.y + b))},
136
+ lambda {Segment.new(extreme1: Point.new(x: center.x - a, y: center.y), extreme2: Point.new(x: center.x + a, y: center.y))}
137
+ )
132
138
  end
133
139
 
134
140
  def vertices
135
141
  [
136
- Point.new(x: center.x + x_semi_axis_length, y: center.y),
137
- Point.new(x: center.x, y: center.y - y_semi_axis_length),
138
- Point.new(x: center.x - x_semi_axis_length, y: center.y),
139
- Point.new(x: center.x, y: center.y + y_semi_axis_length)
142
+ Point.new(x: center.x + a, y: center.y),
143
+ Point.new(x: center.x, y: center.y - b),
144
+ Point.new(x: center.x - a, y: center.y),
145
+ Point.new(x: center.x, y: center.y + b)
140
146
  ]
141
147
  end
142
148
 
143
149
  def eccentricity
144
- Rational(focal_distance, 2 * major_semi_axis)
150
+ Rational(focal_axis.length, major_axis.length)
145
151
  end
146
152
 
147
153
  def congruent?(ellipse)
@@ -151,15 +157,15 @@ module Cartesius
151
157
 
152
158
  def == (ellipse)
153
159
  ellipse.instance_of?(Ellipse) and
154
- ellipse.focus1 == self.focus1 and ellipse.focus2 == self.focus2 and ellipse.sum_of_distances == self.sum_of_distances
160
+ ellipse.focus1 == self.focus1 and ellipse.focus2 == self.focus2 and ellipse.distance == self.distance
155
161
  end
156
162
 
157
- def to_equation
158
- equationfy(
159
- 'x^2' => @x2_coeff, 'y^2' => @y2_coeff, 'x' => @x_coeff, 'y' => @y_coeff, '1' => @k_coeff
160
- )
163
+ def self.build_by(a2, b2, center)
164
+ self.new(x2: b2, y2: a2, x: -2 * b2 * center.x, y: -2 * a2 * center.y, k: b2 * center.x ** 2 + a2 * center.y ** 2 - a2 * b2)
161
165
  end
162
166
 
167
+ private_class_method(:build_by)
168
+
163
169
  private
164
170
 
165
171
  def validation
@@ -168,6 +174,30 @@ module Cartesius
168
174
  end
169
175
  end
170
176
 
177
+ def discriminating(horizontal_focus_type, vertical_focus_type)
178
+ if a2 > b2
179
+ horizontal_focus_type.call
180
+ else
181
+ vertical_focus_type.call
182
+ end
183
+ end
184
+
185
+ def a
186
+ Math.sqrt(a2)
187
+ end
188
+
189
+ def b
190
+ Math.sqrt(b2)
191
+ end
192
+
193
+ def cx
194
+ Math.sqrt(a2 - b2)
195
+ end
196
+
197
+ def cy
198
+ Math.sqrt(b2 - a2)
199
+ end
200
+
171
201
  end
172
202
 
173
203
  end
@@ -8,11 +8,15 @@ module Cartesius
8
8
  class Hyperbola
9
9
  include Determinator, Numerificator
10
10
 
11
- # Conic
11
+ RIGHT_POSITION = 1
12
+ UP_POSITION = -1
13
+
14
+ private_constant(:UP_POSITION)
15
+ private_constant(:RIGHT_POSITION)
16
+
12
17
  # Conic equation type: ax^2 + by^2 + dx + ey + f = 0
13
18
  def initialize(x2:, y2:, x:, y:, k:)
14
- x2, y2, x, y, k = normalize(x2, y2, x, y, k)
15
- @x2_coeff, @y2_coeff, @x_coeff, @y_coeff, @k_coeff = x2.to_r, y2.to_r, x.to_r, y.to_r, k.to_r
19
+ @x2_coeff, @y2_coeff, @x_coeff, @y_coeff, @k_coeff = normalize(x2, y2, x, y, k)
16
20
  validation
17
21
  end
18
22
 
@@ -21,51 +25,65 @@ module Cartesius
21
25
  raise ArgumentError.new('Focus points must be different!')
22
26
  end
23
27
 
24
- unless focus1.aligned_horizontally_with?(focus2) or focus1.aligned_vertically_with?(focus2)
25
- raise ArgumentError.new('Focus must be aligned to axis!')
28
+ focal_axis = Segment.new(extreme1: focus1, extreme2: focus2)
29
+ if focal_axis.inclined?
30
+ raise ArgumentError.new('Focal axis must not be inclined!')
26
31
  end
27
32
 
28
- focal_distance = Point.distance(focus1, focus2)
29
- if distance >= focal_distance
30
- raise ArgumentError.new('Difference of distances must be less than focal distance!')
33
+ if distance >= focal_axis.length
34
+ raise ArgumentError.new('Difference between distances must be less than focal distance!')
31
35
  end
32
36
 
33
- center = Segment.new(extreme1: focus1, extreme2: focus2).mid
34
- c2 = Rational(focal_distance, 2) ** 2
35
- if focus1.aligned_horizontally_with?(focus2)
36
- a2 = Rational(distance, 2) ** 2
37
+ c2 = Rational(focal_axis.length, 2)**2
38
+ if focal_axis.horizontal?
39
+ a2 = Rational(distance, 2)**2
37
40
  b2 = c2 - a2
38
- position = 1
39
- end
40
- if focus1.aligned_vertically_with?(focus2)
41
- b2 = Rational(distance, 2) ** 2
41
+ position = RIGHT_POSITION
42
+ else
43
+ b2 = Rational(distance, 2)**2
42
44
  a2 = c2 - b2
43
- position = -1
45
+ position = UP_POSITION
44
46
  end
45
47
 
46
- self.new(x2: b2, y2: -a2, x: -2 * b2 * center.x, y: 2 * a2 * center.y, k: b2 * center.x ** 2 - a2 * center.y ** 2 + -position * a2 * b2)
48
+ center = focal_axis.mid
49
+
50
+ build_by(a2, b2, center, position)
47
51
  end
48
52
 
49
- def self.by_canonical(center:, transverse_axis:, not_transverse_axis:, position:)
50
- if transverse_axis <= 0 or not_transverse_axis <= 0
51
- raise ArgumentError.new('Axis length must be positive!')
53
+ def self.by_axes(transverse_axis:, not_transverse_axis:)
54
+ if transverse_axis == not_transverse_axis
55
+ raise ArgumentError.new('Axes must be different!')
52
56
  end
53
57
 
54
- unless [-1, 1].include?(position)
55
- raise ArgumentError.new('Position must be up or right!')
58
+ if transverse_axis.inclined? or not_transverse_axis.inclined?
59
+ raise ArgumentError.new('Axes must not be inclined!')
56
60
  end
57
61
 
58
- if position == -1
59
- a2 = not_transverse_axis ** 2
60
- b2 = transverse_axis ** 2
62
+ if transverse_axis.horizontal? and not_transverse_axis.horizontal?
63
+ raise ArgumentError.new('Axes can not be both horizontal!')
61
64
  end
62
65
 
63
- if position == 1
64
- a2 = transverse_axis ** 2
65
- b2 = not_transverse_axis ** 2
66
+ if transverse_axis.vertical? and not_transverse_axis.vertical?
67
+ raise ArgumentError.new('Axes can not be both vertical!')
66
68
  end
67
69
 
68
- self.new(x2: b2, y2: -a2, x: -2 * b2 * center.x, y: 2 * a2 * center.y, k: b2 * center.x ** 2 - a2 * center.y ** 2 + -position * a2 * b2)
70
+ if transverse_axis.mid != not_transverse_axis.mid
71
+ raise ArgumentError.new('Axes must be the same mid point!')
72
+ end
73
+
74
+ if transverse_axis.horizontal?
75
+ a2 = Rational(transverse_axis.length, 2)**2
76
+ b2 = Rational(not_transverse_axis.length, 2)**2
77
+ position = RIGHT_POSITION
78
+ else
79
+ a2 = Rational(not_transverse_axis.length, 2)**2
80
+ b2 = Rational(transverse_axis.length, 2)**2
81
+ position = UP_POSITION
82
+ end
83
+
84
+ center = transverse_axis.mid
85
+
86
+ build_by(a2, b2, center, position)
69
87
  end
70
88
 
71
89
  def self.by_points(center:, vertex:, point:)
@@ -73,16 +91,15 @@ module Cartesius
73
91
  raise ArgumentError.new('Points must be different!')
74
92
  end
75
93
 
76
- unless vertex.aligned_horizontally_with?(center) or vertex.aligned_vertically_with?(center)
94
+ semi_axis = Segment.new(extreme1: center, extreme2: vertex)
95
+ if semi_axis.inclined?
77
96
  raise ArgumentError.new('Vertex must be aligned with center!')
78
97
  end
79
98
 
80
- if vertex.aligned_horizontally_with?(center)
81
- position = 1
82
- end
83
-
84
- if vertex.aligned_vertically_with?(center)
85
- position = -1
99
+ if semi_axis.horizontal?
100
+ position = RIGHT_POSITION
101
+ else
102
+ position = UP_POSITION
86
103
  end
87
104
 
88
105
  shifted1 = Point.new(x: vertex.x - center.x, y: vertex.y - center.y)
@@ -90,53 +107,77 @@ module Cartesius
90
107
 
91
108
  begin
92
109
  alfa, beta = Cramer.solution2(
93
- [shifted1.x ** 2, shifted1.y ** 2],
94
- [shifted2.x ** 2, shifted2.y ** 2],
95
- [1, 1]
110
+ [shifted1.x**2, -shifted1.y**2],
111
+ [shifted2.x**2, -shifted2.y**2],
112
+ [position, position]
96
113
  )
97
114
  rescue
98
- raise ArgumentError.new('No Hyperbola for these points!')
115
+ raise ArgumentError.new('Center, vertex and point are not valid!')
99
116
  end
100
117
 
101
118
  a2 = Rational(1, alfa)
102
119
  b2 = Rational(1, beta)
103
120
 
104
- self.new(x2: b2, y2: -a2, x: -2 * b2 * center.x, y: 2 * a2 * center.y, k: b2 * center.x ** 2 - a2 * center.y ** 2 + -position * a2 * b2)
121
+ build_by(a2, b2, center, position)
105
122
  end
106
123
 
107
124
  def focus1
108
- if position == 1
109
- return Point.new(x: center.x + Math.sqrt(a2 + b2), y: center.y)
110
- end
111
- if position == -1
112
- return Point.new(x: center.x, y: center.y + Math.sqrt(a2 + b2))
113
- end
125
+ discriminating(
126
+ lambda {Point.new(x: center.x + c, y: center.y)},
127
+ lambda {Point.new(x: center.x, y: center.y + c)}
128
+ )
114
129
  end
115
130
 
116
131
  def focus2
117
- if position == 1
118
- return Point.new(x: center.x - Math.sqrt(a2 + b2), y: center.y)
119
- end
120
- if position == -1
121
- return Point.new(x: center.x, y: center.y - Math.sqrt(a2 + b2))
122
- end
132
+ discriminating(
133
+ lambda {Point.new(x: center.x - c, y: center.y)},
134
+ lambda {Point.new(x: center.x, y: center.y - c)}
135
+ )
123
136
  end
124
137
 
125
- def focal_distance
126
- Point.distance(focus1, focus2)
138
+ def distance
139
+ discriminating(lambda {2 * a}, lambda {2 * b})
127
140
  end
128
141
 
129
- def center
130
- Point.new(x: centrum[:xc], y: centrum[:yc])
142
+ def focal_axis
143
+ Segment.new(extreme1: focus1, extreme2: focus2)
131
144
  end
132
145
 
133
- def difference_of_distances
134
- if position == 1
135
- return 2 * Math.sqrt(a2)
136
- end
137
- if position == -1
138
- return 2 * Math.sqrt(b2)
139
- end
146
+ def transverse_axis
147
+ discriminating(
148
+ lambda {Segment.new(extreme1: Point.new(x: center.x - a, y: center.y), extreme2: Point.new(x: center.x + a, y: center.y))},
149
+ lambda {Segment.new(extreme1: Point.new(x: center.x, y: center.y - b), extreme2: Point.new(x: center.x, y: center.y + b))},
150
+ )
151
+ end
152
+
153
+ def not_transverse_axis
154
+ discriminating(
155
+ lambda {Segment.new(extreme1: Point.new(x: center.x, y: center.y - b), extreme2: Point.new(x: center.x, y: center.y + b))},
156
+ lambda {Segment.new(extreme1: Point.new(x: center.x - a, y: center.y), extreme2: Point.new(x: center.x + a, y: center.y))}
157
+ )
158
+ end
159
+
160
+ def vertices
161
+ discriminating(
162
+ lambda {[Point.new(x: center.x - a, y: center.y), Point.new(x: center.x + a, y: center.y)]},
163
+ lambda {[Point.new(x: center.x, y: center.y - b), Point.new(x: center.x, y: center.y + b)]}
164
+ )
165
+ end
166
+
167
+ def eccentricity
168
+ Rational(focal_axis.length, transverse_axis.length)
169
+ end
170
+
171
+ def ascending_asymptote
172
+ Line.create(slope: Rational(b, a), known_term: center.y - center.x * Rational(b, a))
173
+ end
174
+
175
+ def descending_asymptote
176
+ Line.create(slope: -Rational(b, a), known_term: center.y + center.x * Rational(b, a))
177
+ end
178
+
179
+ def equilateral?
180
+ a2 == b2
140
181
  end
141
182
 
142
183
  def congruent?(hyperbola)
@@ -146,21 +187,41 @@ module Cartesius
146
187
 
147
188
  def == (hyperbola)
148
189
  hyperbola.instance_of?(Hyperbola) and
149
- hyperbola.focus1 == self.focus1 and hyperbola.focus2 == self.focus2 and hyperbola.difference_of_distances == self.difference_of_distances
190
+ hyperbola.focus1 == self.focus1 and hyperbola.focus2 == self.focus2 and hyperbola.distance == self.distance
150
191
  end
151
192
 
193
+ def self.build_by(a2, b2, center, position)
194
+ self.new(x2: b2, y2: -a2, x: -2 * b2 * center.x, y: 2 * a2 * center.y, k: b2 * center.x ** 2 - a2 * center.y ** 2 + -position * a2 * b2)
195
+ end
196
+
197
+ private_class_method(:build_by)
198
+
152
199
  private
153
200
 
154
201
  def validation
155
-
156
202
  if signum(@x2_coeff * @y2_coeff) >= 0 or determinator == @k_coeff
157
203
  raise ArgumentError.new('Invalid coefficients!')
158
204
  end
205
+ end
206
+
207
+ def discriminating(horizontal_focus_type, vertical_focus_type)
208
+ if signum(determinator - @k_coeff) == 1
209
+ horizontal_focus_type.call
210
+ else
211
+ vertical_focus_type.call
212
+ end
213
+ end
214
+
215
+ def a
216
+ Math.sqrt(a2)
217
+ end
159
218
 
219
+ def b
220
+ Math.sqrt(b2)
160
221
  end
161
222
 
162
- def position
163
- signum(determinator - @k_coeff)
223
+ def c
224
+ Math.sqrt(a2 + b2)
164
225
  end
165
226
 
166
227
  end
@@ -29,11 +29,11 @@ module Cartesius
29
29
  raise ArgumentError.new('Points must be different!')
30
30
  end
31
31
 
32
- if point1.aligned_horizontally_with?(point2)
32
+ if point1.y == point2.y
33
33
  return horizontal(known_term: point1.y)
34
34
  end
35
35
 
36
- if point1.aligned_vertically_with?(point2)
36
+ if point1.x == point2.x
37
37
  return vertical(known_term: point1.x)
38
38
  end
39
39
 
@@ -143,7 +143,7 @@ module Cartesius
143
143
  end
144
144
 
145
145
  def == (line)
146
- congruent?(line) and
146
+ line.instance_of?(Line) and
147
147
  line.slope == self.slope and line.known_term == self.known_term
148
148
  end
149
149
 
@@ -15,14 +15,6 @@ module Cartesius
15
15
  validation
16
16
  end
17
17
 
18
- def self.unitary_convex
19
- new(x2: 1, x: 0, k: 0)
20
- end
21
-
22
- def self.unitary_concave
23
- new(x2: -1, x: 0, k: 0)
24
- end
25
-
26
18
  def self.by_definition(directrix:, focus:)
27
19
  if directrix.include?(focus)
28
20
  raise ArgumentError.new('Focus belongs to directrix!')
@@ -36,27 +28,10 @@ module Cartesius
36
28
  b = -2 * a * focus.x
37
29
  c = a * (focus.x ** 2) + focus.y - Rational(1, 4 * a)
38
30
 
39
- self.new(x2: -a, x: -b, k: -c)
40
- end
41
-
42
- def self.by_canonical(focus:, gap:)
43
- if gap.zero?
44
- raise ArgumentError.new('Gap must not be zero!')
45
- end
46
-
47
- a = gap
48
- b = -2 * a * focus.x
49
- c = (focus.x ** 2) + focus.y - Rational(1, 4 * a)
50
-
51
- self.new(x2: -a, x: -b, k: -c)
31
+ self.new(x2: a, x: b, k: c)
52
32
  end
53
33
 
54
34
  def self.by_points(point1:, point2:, point3:)
55
-
56
- if point1 == point2 or point1 == point3 or point2 == point3
57
- raise ArgumentError.new('Points must be distinct!')
58
- end
59
-
60
35
  a, b, c = Cramer.solution3(
61
36
  [point1.x ** 2, point1.x, 1],
62
37
  [point2.x ** 2, point2.x, 1],
@@ -64,7 +39,9 @@ module Cartesius
64
39
  [point1.y, point2.y, point3.y]
65
40
  )
66
41
 
67
- self.new(x2: -a, x: -b, k: -c)
42
+ self.new(x2: a, x: b, k: c)
43
+ rescue
44
+ raise ArgumentError.new('Invalid points!')
68
45
  end
69
46
 
70
47
  def directrix
@@ -83,23 +60,24 @@ module Cartesius
83
60
  Line.vertical(known_term: Rational(-@x_coeff, 2* @x2_coeff))
84
61
  end
85
62
 
86
- def unitary_convex?
87
- self == Parabola.unitary_convex
63
+ def eccentricity
64
+ @x2_coeff.abs
88
65
  end
89
66
 
90
- def unitary_concave?
91
- self == Parabola.unitary_concave
67
+ def to_equation
68
+ equationfy(
69
+ 'x^2' => @x2_coeff, 'x' => @x_coeff, 'y' => -1, '1' => @k_coeff
70
+ )
92
71
  end
93
72
 
94
- def == (parabola)
73
+ def congruent?(parabola)
95
74
  parabola.instance_of?(Parabola) and
96
- parabola.focus == self.focus and parabola.directrix == self.directrix
75
+ parabola.eccentricity == self.eccentricity
97
76
  end
98
77
 
99
- def to_equation
100
- equationfy(
101
- 'x^2' => @x2_coeff, 'x' => @x_coeff, 'y' => @y_coeff, '1' => @k_coeff
102
- )
78
+ def == (parabola)
79
+ parabola.instance_of?(Parabola) and
80
+ parabola.focus == self.focus and parabola.directrix == self.directrix
103
81
  end
104
82
 
105
83
  private
@@ -15,27 +15,15 @@ module Cartesius
15
15
  end
16
16
 
17
17
  def self.distance(point1, point2)
18
- Math.sqrt(
19
- (point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2
20
- )
18
+ Math.sqrt((point1.x - point2.x)** 2 + (point1.y - point2.y)** 2)
21
19
  end
22
20
 
23
21
  def origin?
24
22
  self == Point.origin
25
23
  end
26
24
 
27
- def aligned_horizontally_with?(point)
28
- @y == point.y
29
- end
30
-
31
- def aligned_vertically_with?(point)
32
- @x == point.x
33
- end
34
-
35
25
  def distance_from(point)
36
- Math.sqrt(
37
- (@x - point.x) ** 2 + (@y - point.y) ** 2
38
- )
26
+ Math.sqrt((@x - point.x)** 2 + (@y - point.y)** 2)
39
27
  end
40
28
 
41
29
  def to_coordinates
@@ -53,7 +41,7 @@ module Cartesius
53
41
  end
54
42
 
55
43
  def == (point)
56
- congruent?(point) and
44
+ point.instance_of?(Point) and
57
45
  point.x == @x and point.y == @y
58
46
  end
59
47
 
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: 0.0.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mauro Quaglia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-07 00:00:00.000000000 Z
11
+ date: 2017-12-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: The cartesian plan and its elements.
14
14
  email: mauroquaglia@libero.it
@@ -35,7 +35,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
35
35
  requirements:
36
36
  - - ">="
37
37
  - !ruby/object:Gem::Version
38
- version: '0'
38
+ version: 2.4.0
39
39
  required_rubygems_version: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - ">="
@@ -43,7 +43,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
43
43
  version: '0'
44
44
  requirements: []
45
45
  rubyforge_project:
46
- rubygems_version: 2.6.13
46
+ rubygems_version: 2.6.10
47
47
  signing_key:
48
48
  specification_version: 4
49
49
  summary: The cartesian coordinate system.