cartesius 1.0.0 → 1.1.0

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
2
  SHA1:
3
- metadata.gz: 8ca7c08a027f0547ece43bf75d1d622aa7a59279
4
- data.tar.gz: 9b95391ad0010c8dd2cb1eb11a37933e2fa74b2f
3
+ metadata.gz: 69e7a9e2b6c6f4edb2bcc0cd73e5f909ee2eed07
4
+ data.tar.gz: 4eda3671a45184320a8485a0bd389df017bc8b8f
5
5
  SHA512:
6
- metadata.gz: 6b141b69ced00426c9c461e07bec394bacf3a625058c68ee101caa3f8886c21711342a920d2adfd29fc3fadc2094a108354ca004ad47a891a5830f306d4370d6
7
- data.tar.gz: b37537b3e28b9973c9d2981742cc52e6a2b181a1bc7342407af1e37d96fff7d343ed5199f4fce435c5d344909906a83d252541380e720a8cbb1d9c29bb5cb3f9
6
+ metadata.gz: 005e1721917eb39048995f4567a084c53ec9bdc66f2d95ca78ae2a827ae9bb19561747072ac257f697c46d2fc572e2a4175c897feedd929408a7d1fe438cbc8b
7
+ data.tar.gz: 01db7a237a5fa5edc13314dee6503120f9e232f65665e1cba2a3c9d830c1d9bbf68da95f367bc634e3af493d51b3e004eff202b9f4250665504e212643a8c8b0
@@ -0,0 +1,95 @@
1
+ module Cartesius
2
+ class Angle
3
+ NULL, RIGHT, FLAT, FULL = 0, 90, 180, 360
4
+ private_constant(:NULL)
5
+ private_constant(:RIGHT)
6
+ private_constant(:FLAT)
7
+ private_constant(:FULL)
8
+
9
+ def initialize(angle)
10
+ @angle = angle
11
+ end
12
+
13
+ private_class_method(:new)
14
+
15
+ def self.by_degrees(degrees)
16
+ new(degrees)
17
+ end
18
+
19
+ def self.by_radiants(radiants)
20
+ by_degrees(radiants * FLAT / Math::PI)
21
+ end
22
+
23
+ def self.by_lines(line1:, line2:)
24
+ raise ArgumentError.new('Lines must not be parallel!') if line1.parallel?(line2)
25
+ if line1.perpendicular?(line2)
26
+ [right, right]
27
+ else
28
+ acute = by_radiants(Math.atan(line1.slope - line2.slope / 1 + line1.slope * line2.slope).abs)
29
+ [acute, new(FLAT - acute.degrees)]
30
+ end
31
+ end
32
+
33
+ def self.null
34
+ by_degrees(NULL)
35
+ end
36
+
37
+ def self.right
38
+ by_degrees(RIGHT)
39
+ end
40
+
41
+ def self.flat
42
+ by_degrees(FLAT)
43
+ end
44
+
45
+ def self.full
46
+ by_degrees(FULL)
47
+ end
48
+
49
+ def degrees(precision = 3)
50
+ @angle.round(precision)
51
+ end
52
+
53
+ def radiants(precision = 3)
54
+ (@angle * Math::PI / FLAT).round(precision)
55
+ end
56
+
57
+ def null?
58
+ degrees == NULL
59
+ end
60
+
61
+ def acute?
62
+ degrees > NULL and degrees < RIGHT
63
+ end
64
+
65
+ def right?
66
+ degrees == RIGHT
67
+ end
68
+
69
+ def obtuse?
70
+ degrees > RIGHT and degrees < FLAT
71
+ end
72
+
73
+ def flat?
74
+ degrees == FLAT
75
+ end
76
+
77
+ def full?
78
+ degrees == FULL
79
+ end
80
+
81
+ def congruent?(angle)
82
+ angle.instance_of?(self.class) and
83
+ angle.degrees == degrees
84
+ end
85
+
86
+ alias_method(:eql?, :congruent?)
87
+
88
+ private
89
+
90
+ def hash
91
+ @angle.hash
92
+ end
93
+
94
+ end
95
+ end
@@ -37,7 +37,7 @@ module Cartesius
37
37
  [point3.x, point3.y, 1],
38
38
  [-(point1.x ** 2 + point1.y ** 2), -(point2.x ** 2 + point2.y ** 2), -(point3.x ** 2 + point3.y ** 2)]
39
39
  )
40
- self.new(x: alfa, y: beta, k: gamma)
40
+ new(x: alfa, y: beta, k: gamma)
41
41
  rescue
42
42
  raise ArgumentError.new('Invalid points!')
43
43
  end
@@ -59,17 +59,17 @@ module Cartesius
59
59
  end
60
60
 
61
61
  def congruent?(circumference)
62
- circumference.instance_of?(Circumference) and
63
- circumference.radius == self.radius
62
+ circumference.instance_of?(self.class) and
63
+ circumference.radius == radius
64
64
  end
65
65
 
66
66
  def == (circumference)
67
- circumference.instance_of?(Circumference) and
68
- circumference.center == self.center and circumference.radius == self.radius
67
+ circumference.instance_of?(self.class) and
68
+ circumference.center == center and circumference.radius == radius
69
69
  end
70
70
 
71
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)
72
+ new(x: -2 * center.x, y: -2 * center.y, k: center.x ** 2 + center.y ** 2 - radius.to_r ** 2)
73
73
  end
74
74
 
75
75
  private_class_method(:build_by)
@@ -151,17 +151,17 @@ module Cartesius
151
151
  end
152
152
 
153
153
  def congruent?(ellipse)
154
- ellipse.instance_of?(Ellipse) and
155
- ellipse.eccentricity == self.eccentricity
154
+ ellipse.instance_of?(self.class) and
155
+ ellipse.eccentricity == eccentricity
156
156
  end
157
157
 
158
158
  def == (ellipse)
159
- ellipse.instance_of?(Ellipse) and
160
- ellipse.focus1 == self.focus1 and ellipse.focus2 == self.focus2 and ellipse.distance == self.distance
159
+ ellipse.instance_of?(self.class) and
160
+ ellipse.focus1 == focus1 and ellipse.focus2 == focus2 and ellipse.distance == distance
161
161
  end
162
162
 
163
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)
164
+ 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)
165
165
  end
166
166
 
167
167
  private_class_method(:build_by)
@@ -181,17 +181,17 @@ module Cartesius
181
181
  end
182
182
 
183
183
  def congruent?(hyperbola)
184
- hyperbola.instance_of?(Hyperbola) and
185
- hyperbola.eccentricity == self.eccentricity
184
+ hyperbola.instance_of?(self.class) and
185
+ hyperbola.eccentricity == eccentricity
186
186
  end
187
187
 
188
188
  def == (hyperbola)
189
- hyperbola.instance_of?(Hyperbola) and
190
- hyperbola.focus1 == self.focus1 and hyperbola.focus2 == self.focus2 and hyperbola.distance == self.distance
189
+ hyperbola.instance_of?(self.class) and
190
+ hyperbola.focus1 == focus1 and hyperbola.focus2 == focus2 and hyperbola.distance == distance
191
191
  end
192
192
 
193
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)
194
+ 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
195
  end
196
196
 
197
197
  private_class_method(:build_by)
@@ -7,6 +7,10 @@ module Cartesius
7
7
  VERTICAL_SLOPE = Float::INFINITY
8
8
  HORIZONTAL_SLOPE = 0
9
9
 
10
+ private_constant(:VERTICAL_SLOPE)
11
+ private_constant(:HORIZONTAL_SLOPE)
12
+
13
+ # equation type: dx + ey + f = 0
10
14
  def initialize(x:, y:, k:)
11
15
  @x_coeff, @y_coeff, @k_coeff = x.to_r, y.to_r, k.to_r
12
16
  validation
@@ -17,7 +21,7 @@ module Cartesius
17
21
  end
18
22
 
19
23
  def self.horizontal(known_term:)
20
- new(x: 0, y: 1, k: -known_term.to_r)
24
+ create(slope: HORIZONTAL_SLOPE, known_term: known_term)
21
25
  end
22
26
 
23
27
  def self.vertical(known_term:)
@@ -29,18 +33,16 @@ module Cartesius
29
33
  raise ArgumentError.new('Points must be different!')
30
34
  end
31
35
 
32
- if point1.y == point2.y
33
- return horizontal(known_term: point1.y)
34
- end
35
-
36
36
  if point1.x == point2.x
37
37
  return vertical(known_term: point1.x)
38
+ else
39
+ m, q = Cramer.solution2(
40
+ [point1.x, 1],
41
+ [point2.x, 1],
42
+ [point1.y, point2.y]
43
+ )
44
+ create(slope: m, known_term: q)
38
45
  end
39
-
40
- slope = Rational(point2.y - point1.y, point2.x - point1.x)
41
- known_term = point1.y - slope * point1.x
42
-
43
- create(slope: slope, known_term: known_term)
44
46
  end
45
47
 
46
48
  def self.x_axis
@@ -52,19 +54,27 @@ module Cartesius
52
54
  end
53
55
 
54
56
  def self.ascending_bisector
55
- new(x: -1, y: 1, k: 0)
57
+ create(slope: 1, known_term: 0)
56
58
  end
57
59
 
58
60
  def self.descending_bisector
59
- new(x: 1, y: 1, k: 0)
61
+ create(slope: -1, known_term: 0)
60
62
  end
61
63
 
62
64
  def slope
63
- @y_coeff == 0 ? VERTICAL_SLOPE : Rational(-@x_coeff, @y_coeff)
65
+ if @y_coeff.zero?
66
+ VERTICAL_SLOPE
67
+ else
68
+ numberfy(-@x_coeff, @y_coeff)
69
+ end
64
70
  end
65
71
 
66
72
  def known_term
67
- @y_coeff == 0 ? Rational(-@k_coeff, @x_coeff) : Rational(-@k_coeff, @y_coeff)
73
+ if @y_coeff.zero?
74
+ numberfy(-@k_coeff, @x_coeff)
75
+ else
76
+ numberfy(-@k_coeff, @y_coeff)
77
+ end
68
78
  end
69
79
 
70
80
  def x_axis?
@@ -92,65 +102,68 @@ module Cartesius
92
102
  end
93
103
 
94
104
  def inclined?
95
- (not horizontal?) and (not vertical?)
105
+ ascending? or descending?
96
106
  end
97
107
 
98
108
  def ascending?
99
- slope != VERTICAL_SLOPE and slope > 0
109
+ slope != VERTICAL_SLOPE and slope > HORIZONTAL_SLOPE
100
110
  end
101
111
 
102
112
  def descending?
103
- slope < 0
113
+ slope < HORIZONTAL_SLOPE
104
114
  end
105
115
 
106
116
  def parallel?(line)
107
- slope == line.slope
117
+ line.slope == slope
108
118
  end
109
119
 
110
120
  def perpendicular?(line)
111
- if slope == 0
112
- return line.slope == VERTICAL_SLOPE
113
- end
114
- if slope == VERTICAL_SLOPE
115
- return line.slope == 0
121
+ if line.slope == HORIZONTAL_SLOPE
122
+ slope == VERTICAL_SLOPE
123
+ elsif line.slope == VERTICAL_SLOPE
124
+ slope == HORIZONTAL_SLOPE
125
+ else
126
+ line.slope * slope == -1
116
127
  end
117
- slope * line.slope == -1
118
128
  end
119
129
 
120
130
  def include?(point)
121
131
  if vertical?
122
- return known_term == point.x
132
+ point.x == known_term
133
+ else
134
+ point.y == slope * point.x + known_term
123
135
  end
124
- point.y == slope * point.x + known_term
125
136
  end
126
137
 
127
138
  def x_intercept
128
- @x_coeff.zero? ? nil : -Rational(@k_coeff, @x_coeff)
139
+ unless @x_coeff.zero?
140
+ numberfy(-@k_coeff, @x_coeff)
141
+ end
129
142
  end
130
143
 
131
144
  def y_intercept
132
- @y_coeff.zero? ? nil : -Rational(@k_coeff, @y_coeff)
145
+ unless @y_coeff.zero?
146
+ numberfy(-@k_coeff, @y_coeff)
147
+ end
133
148
  end
134
149
 
135
150
  def to_equation
136
- equationfy(
137
- 'x' => @x_coeff, 'y' => @y_coeff, '1' => @k_coeff
138
- )
151
+ equationfy('x' => @x_coeff, 'y' => @y_coeff, '1' => @k_coeff)
139
152
  end
140
153
 
141
154
  def congruent?(line)
142
- line.instance_of?(Line)
155
+ line.instance_of?(self.class)
143
156
  end
144
157
 
145
158
  def == (line)
146
- line.instance_of?(Line) and
147
- line.slope == self.slope and line.known_term == self.known_term
159
+ line.instance_of?(self.class) and
160
+ line.slope == slope and line.known_term == known_term
148
161
  end
149
162
 
150
163
  private
151
164
 
152
165
  def validation
153
- if (@x_coeff == 0 and @y_coeff == 0)
166
+ if @x_coeff.zero? and @y_coeff.zero?
154
167
  raise ArgumentError.new('Invalid coefficients!')
155
168
  end
156
169
  end
@@ -28,7 +28,7 @@ module Cartesius
28
28
  b = -2 * a * focus.x
29
29
  c = a * (focus.x ** 2) + focus.y - Rational(1, 4 * a)
30
30
 
31
- self.new(x2: a, x: b, k: c)
31
+ new(x2: a, x: b, k: c)
32
32
  end
33
33
 
34
34
  def self.by_points(point1:, point2:, point3:)
@@ -39,7 +39,7 @@ module Cartesius
39
39
  [point1.y, point2.y, point3.y]
40
40
  )
41
41
 
42
- self.new(x2: a, x: b, k: c)
42
+ new(x2: a, x: b, k: c)
43
43
  rescue
44
44
  raise ArgumentError.new('Invalid points!')
45
45
  end
@@ -71,13 +71,13 @@ module Cartesius
71
71
  end
72
72
 
73
73
  def congruent?(parabola)
74
- parabola.instance_of?(Parabola) and
75
- parabola.eccentricity == self.eccentricity
74
+ parabola.instance_of?(self.class) and
75
+ parabola.eccentricity == eccentricity
76
76
  end
77
77
 
78
78
  def == (parabola)
79
- parabola.instance_of?(Parabola) and
80
- parabola.focus == self.focus and parabola.directrix == self.directrix
79
+ parabola.instance_of?(self.class) and
80
+ parabola.focus == focus and parabola.directrix == directrix
81
81
  end
82
82
 
83
83
  private
@@ -1,7 +1,6 @@
1
1
  require('cartesius/numerificator')
2
2
 
3
3
  module Cartesius
4
-
5
4
  class Point
6
5
  include Numerificator
7
6
  attr_reader :x, :y
@@ -15,36 +14,36 @@ module Cartesius
15
14
  end
16
15
 
17
16
  def self.distance(point1, point2)
18
- Math.sqrt((point1.x - point2.x)** 2 + (point1.y - point2.y)** 2)
17
+ Math.sqrt((point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2)
19
18
  end
20
19
 
21
20
  def origin?
22
21
  self == Point.origin
23
22
  end
24
23
 
25
- def distance_from(point)
26
- Math.sqrt((@x - point.x)** 2 + (@y - point.y)** 2)
27
- end
28
-
29
24
  def to_coordinates
30
25
  "(#{stringfy(x)}; #{stringfy(y)})"
31
26
  end
32
27
 
33
28
  def to_equation
34
- equationfy(
35
- 'x^2' => 1, 'y^2' => 1, 'x' => -2 * @x, 'y' => -2 * @y, '1' => @x ** 2 + @y ** 2
36
- )
29
+ equationfy('x^2' => 1, 'y^2' => 1, 'x' => -2 * @x, 'y' => -2 * @y, '1' => @x ** 2 + @y ** 2)
37
30
  end
38
31
 
39
32
  def congruent?(point)
40
- point.instance_of?(Point)
33
+ point.instance_of?(self.class)
41
34
  end
42
35
 
43
36
  def == (point)
44
- point.instance_of?(Point) and
37
+ point.instance_of?(self.class) and
45
38
  point.x == @x and point.y == @y
46
39
  end
47
40
 
48
- end
41
+ alias_method(:eql?, :==)
49
42
 
43
+ private
44
+
45
+ def hash
46
+ @x.hash ^ @y.hash
47
+ end
48
+ end
50
49
  end
@@ -4,6 +4,7 @@ require('cartesius/line')
4
4
  module Cartesius
5
5
 
6
6
  class Segment
7
+ include Numerificator
7
8
  extend Forwardable
8
9
  attr_reader :extreme1, :extreme2
9
10
  def_delegators(:@line, :horizontal?, :vertical?, :inclined?, :ascending?, :descending?)
@@ -24,8 +25,8 @@ module Cartesius
24
25
 
25
26
  def mid
26
27
  Point.new(
27
- x: Rational(@extreme1.x + @extreme2.x, 2),
28
- y: Rational(@extreme1.y + @extreme2.y, 2)
28
+ x: numberfy(@extreme1.x + @extreme2.x, 2),
29
+ y: numberfy(@extreme1.y + @extreme2.y, 2)
29
30
  )
30
31
  end
31
32
 
@@ -34,17 +35,15 @@ module Cartesius
34
35
  end
35
36
 
36
37
  def congruent?(segment)
37
- segment.instance_of?(Segment) and
38
+ segment.instance_of?(self.class) and
38
39
  segment.length == self.length
39
40
  end
40
41
 
41
42
  def == (segment)
42
- unless segment.instance_of?(Segment)
43
- return false
44
- end
45
-
46
- (segment.extreme1 == self.extreme1 and segment.extreme2 == self.extreme2) or
47
- (segment.extreme1 == self.extreme2 and segment.extreme2 == self.extreme1)
43
+ segment.instance_of?(self.class) and (
44
+ (segment.extreme1 == extreme1 and segment.extreme2 == extreme2) or
45
+ (segment.extreme1 == extreme2 and segment.extreme2 == extreme1)
46
+ )
48
47
  end
49
48
 
50
49
  private
@@ -0,0 +1,106 @@
1
+ require('cartesius/validator')
2
+ require('cartesius/segment')
3
+ require('cartesius/angle')
4
+
5
+ module Cartesius
6
+
7
+ class Triangle
8
+
9
+ def initialize(a:, b:, c:)
10
+ validation(a, b, c)
11
+ @v_a = a
12
+ @v_b = b
13
+ @v_c = c
14
+ @s_a = Segment.new(extreme1: @v_b, extreme2: @v_c)
15
+ @s_b = Segment.new(extreme1: @v_a, extreme2: @v_c)
16
+ @s_c = Segment.new(extreme1: @v_a, extreme2: @v_b)
17
+ @a_a = Angle.by_radiants(carnot(@s_a, @s_b, @s_c))
18
+ @a_b = Angle.by_radiants(carnot(@s_b, @s_a, @s_c))
19
+ @a_c = Angle.by_radiants(carnot(@s_c, @s_a, @s_b))
20
+ end
21
+
22
+ def angles
23
+ {a: @a_a, b: @a_b, c: @a_c}
24
+ end
25
+
26
+ def sides
27
+ {a: @s_a, b: @s_b, c: @s_c}
28
+ end
29
+
30
+ def vertices
31
+ {a: @v_a, b: @v_b, c: @v_c}
32
+ end
33
+
34
+ def rectangle?
35
+ angles.values.any?(&:right?)
36
+ end
37
+
38
+ def obtuse?
39
+ angles.values.any?(&:obtuse?)
40
+ end
41
+
42
+ def acute?
43
+ not rectangle? and not obtuse?
44
+ end
45
+
46
+ def equilateral?(precision = 2)
47
+ sides_congruent(precision) == 1
48
+ end
49
+
50
+ def isosceles?(precision = 2)
51
+ equilateral? or sides_congruent(precision) == 2
52
+ end
53
+
54
+ def scalene?(precision = 2)
55
+ sides_congruent(precision) == 3
56
+ end
57
+
58
+ def perimeter
59
+ sides.values.inject(0) {|sum, side| sum + side.length}
60
+ end
61
+
62
+ def area(precision = 2)
63
+ Rational(sides[:a].length * sides[:b].length * Math.sin(angles[:c].radiants), 2).round(precision)
64
+ end
65
+
66
+ def == (triangle)
67
+ triangle.instance_of?(self.class) and
68
+ triangle.vertices.values.to_set == vertices.values.to_set
69
+ end
70
+
71
+ def congruent? (triangle)
72
+ triangle.instance_of?(self.class) and
73
+ sides_length(triangle) == sides_length(self)
74
+ end
75
+
76
+ def similar?(triangle)
77
+ triangle.instance_of?(self.class) and
78
+ triangle.angles.values.to_set == angles.values.to_set
79
+ end
80
+
81
+ private
82
+
83
+ def carnot(side1, side2, side3)
84
+ cosine = Rational(
85
+ side2.length ** 2 + side3.length ** 2 - side1.length ** 2,
86
+ 2 * side2.length * side3.length
87
+ )
88
+ Math.acos(cosine)
89
+ end
90
+
91
+ def validation(a, b, c)
92
+ Validator.same_points([a, b, c])
93
+ Validator.aligned_points([a, b, c])
94
+ end
95
+
96
+ def sides_length(triangle)
97
+ triangle.sides.values.collect(&:length).sort
98
+ end
99
+
100
+ def sides_congruent(precision)
101
+ sides_length(self).map {|side| side.round(precision)}.uniq.count
102
+ end
103
+
104
+ end
105
+
106
+ 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.0.0
4
+ version: 1.1.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-12-01 00:00:00.000000000 Z
11
+ date: 2018-01-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: The cartesian plan and its elements.
14
14
  email: mauroquaglia@libero.it
@@ -16,6 +16,7 @@ executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
+ - lib/cartesius/angle.rb
19
20
  - lib/cartesius/circumference.rb
20
21
  - lib/cartesius/ellipse.rb
21
22
  - lib/cartesius/hyperbola.rb
@@ -23,6 +24,7 @@ files:
23
24
  - lib/cartesius/parabola.rb
24
25
  - lib/cartesius/point.rb
25
26
  - lib/cartesius/segment.rb
27
+ - lib/cartesius/triangle.rb
26
28
  homepage: https://github.com/MauroQuaglia/cartesius
27
29
  licenses:
28
30
  - MIT
@@ -35,7 +37,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
35
37
  requirements:
36
38
  - - ">="
37
39
  - !ruby/object:Gem::Version
38
- version: 2.4.0
40
+ version: 2.1.0
39
41
  required_rubygems_version: !ruby/object:Gem::Requirement
40
42
  requirements:
41
43
  - - ">="
@@ -43,7 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
43
45
  version: '0'
44
46
  requirements: []
45
47
  rubyforge_project:
46
- rubygems_version: 2.6.10
48
+ rubygems_version: 2.6.14
47
49
  signing_key:
48
50
  specification_version: 4
49
51
  summary: The cartesian coordinate system.