geometry_3d 0.0.0 → 0.1.1

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: 2ce961e96e2afd1aa40e1ed69b026f01fe6431f3
4
- data.tar.gz: f7694694f3a44e170e00fb11176d259501dd9cab
3
+ metadata.gz: b6be9663a382709ce88d58a88343d355c8c11889
4
+ data.tar.gz: 434c0d1cad5c1474523ecdf2e3d025d06cf25a6a
5
5
  SHA512:
6
- metadata.gz: fd0c38048554b2716e5b8308703e3a894d913cb38e4746b13533ed552f4cc3deb5a68b91ea26ab1ef23afbccdd7f5bdef5d7421888e0118cdca076397d805f56
7
- data.tar.gz: 0859769cf7a415e81fa902df66271f584ed86ae1d4c0a3ddb9f092ac010d4a19f66a7cf16d520a5df7867077ad680acbe6c2445d95421975ba5b9c027d18389d
6
+ metadata.gz: f45cfb2296046a337a1628970c8e7b371791b593d1399088f5a7897c7a9468914d61cce976b455fa74866702de54d45a56669e03dcc49dffab943879c7ec4bf4
7
+ data.tar.gz: 728cd85b9e419cde91e666a1ba269ef355207eef0fe158a318629b9059f3facebf0917df4af8b52103415c563654421a0a9df6ecfac64eade17c560279051d10
data/bin/geometry_3d ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env ruby
2
+ require 'geometry_3d'
data/lib/geometry_3d.rb CHANGED
@@ -1,5 +1,7 @@
1
- class Geometry
2
- def self.hi
3
- puts "djani"
4
- end
5
- end
1
+ require_relative './geometry_3d/point.rb'
2
+ require_relative './geometry_3d/vector'
3
+ require_relative './geometry_3d/line'
4
+ require_relative './geometry_3d/plane'
5
+ require_relative './geometry_3d/triangle'
6
+ require_relative './geometry_3d/circle'
7
+ require_relative './geometry_3d/equation.rb'
@@ -0,0 +1,39 @@
1
+ class Circle
2
+ attr_accessor :point
3
+ attr_accessor :radius
4
+ attr_accessor :vector
5
+
6
+ def initialize(point, vector, radius)
7
+ @point = point
8
+ @radius = radius
9
+ @vector = vector
10
+ end
11
+
12
+ # Find the area of a circle.
13
+ #
14
+ # Example:
15
+ # >> Circle.new(Point.new(1, 2, 3), Vector.new(1, 1, 1), 3)
16
+ # => 28.274333882308138
17
+ #
18
+ # Arguments:
19
+ # no
20
+
21
+ def area
22
+ Math::PI * radius ** 2
23
+ end
24
+
25
+ # Find the perimeter of a circle.
26
+ #
27
+ # Example:
28
+ # >> Circle.new(Point.new(1, 2, 3), Vector.new(1, 1, 1), 3)
29
+ # => 18.84955592153876
30
+ #
31
+ # Arguments:
32
+ # no
33
+
34
+ def perimeter
35
+ 2 * Math::PI * radius
36
+ end
37
+
38
+ end
39
+
@@ -0,0 +1,17 @@
1
+ class LinearEquation
2
+ attr_accessor :a
3
+ attr_accessor :b
4
+ attr_accessor :c
5
+
6
+ def initialize(a, b, c)
7
+ @a = a
8
+ @b = b
9
+ @c = c
10
+ end
11
+
12
+ def solve_system(equation)
13
+ y = (equation.a * c - a * equation.c) / (a * equation.b - equation.a * b).to_f
14
+ x = (- c - b * y) / a.to_f
15
+ [x, y]
16
+ end
17
+ end
@@ -0,0 +1,49 @@
1
+ class Line
2
+ attr_accessor :vector
3
+ attr_accessor :point
4
+
5
+ def initialize(point, vector)
6
+ @point = point
7
+ @vector = vector
8
+ end
9
+
10
+ # Construct a line with two points.
11
+ #
12
+ # Example:
13
+ # >> Line.construct_with_two_points(Point.new(1, 2, 3), Point.new(3, 2, 1))
14
+ # => Line.new(Point.new(1, 2, 3), Vector.new(2, 0, -2))
15
+ #
16
+ # Arguments:
17
+ # first_point: (Point)
18
+ # second_point: (Point)
19
+
20
+ def self.construct_with_two_points(first_point, second_point)
21
+ v = Vector.construct_with_two_points(first_point, second_point)
22
+ Line.new(first_point, v)
23
+ end
24
+
25
+ # Find intersecting point of two lines.
26
+ #
27
+ # Example:
28
+ # >> Line.new(Point.new(1,-2,3), Vector.new(5,2,-1)).find_intersecting_point(Line.new(Point.new(-4,-4,1), Vector.new(-1,3,-1)))
29
+ # => Point.new(-4, -4, 4)
30
+ #
31
+ # Arguments:
32
+ # line: (Line)
33
+
34
+ def find_intersecting_point(line)
35
+ eq1 = LinearEquation.new(vector.x, -line.vector.x, point.x - line.point.x)
36
+ eq2 = LinearEquation.new(vector.y, -line.vector.y, point.y - line.point.y)
37
+ find_point (eq1.solve_system(eq2)[0])
38
+ end
39
+
40
+ def ==(line)
41
+ point == line.point and vector == line.vector
42
+ end
43
+
44
+ private
45
+ def find_point(parameter)
46
+ Point.new(*point.to_a.zip(vector.to_a).map { |a, b| a + b * parameter})
47
+ end
48
+
49
+ end
@@ -0,0 +1,109 @@
1
+ class Plane
2
+ attr_accessor :a
3
+ attr_accessor :b
4
+ attr_accessor :c
5
+ attr_accessor :d
6
+
7
+ def initialize(a, b, c, d)
8
+ @a = a
9
+ @b = b
10
+ @c = c
11
+ @d = d
12
+ end
13
+
14
+ # Construct a plane passing through three points.
15
+ #
16
+ # Example:
17
+ # >> Plane.new(Point.new(1, 2, 3), Point.new(4, 6, 9), Point.new(12, 11, 9))
18
+ # => Plane.new(30, -48, 17, 15)
19
+ #
20
+ # Arguments:
21
+ # point1: (Point)
22
+ # point2: (Point)
23
+ # point3: (Point)
24
+
25
+ def self.construct_with_three_points(point1, point2, point3)
26
+ vector1 = Vector.construct_with_two_points(point1, point3)
27
+ vector2 = Vector.construct_with_two_points(point1, point2)
28
+ construct_with_two_vectors_and_point(vector1, vector2, point1)
29
+ end
30
+
31
+
32
+
33
+ # Construct plane with normal vector and passing through a point.
34
+ #
35
+ # Example:
36
+ # >> Plane.construct_with_normal_vector_and_point(Vector.new(-2, 3, 1), Point.new(1, 1, 1))
37
+ # => Plane.new(-2, 3, 1, -2)
38
+ #
39
+ # Arguments:
40
+ # vector: (Vector)
41
+ # point: (Point)
42
+
43
+ def self.construct_with_normal_vector_and_point(vector, point)
44
+ Plane.new(*vector.to_a, find_d(vector.to_a, point))
45
+ end
46
+
47
+ # Construct a plane parallel to two vectors and passing through a point.
48
+ #
49
+ # Example:
50
+ # >> Plane.construct_with_two_vectors_and_point(Vector.new(1, 2, 3), Vector.new(-2, 1, 2), Point.new(1, 1, 1))
51
+ # => Plane.new(30, -48, 17, 15)
52
+ #
53
+ # Arguments:
54
+ # vector1: (Vector)
55
+ # vector2: (Vector)
56
+ # point: (Point)
57
+
58
+ def self.construct_with_two_vectors_and_point(vector1, vector2, point)
59
+ vector = vector1.cross_product(vector2)
60
+ construct_with_normal_vector_and_point(vector, point)
61
+ end
62
+
63
+ # Construct a plane parallel other plane and passing through a point.
64
+ #
65
+ # Example:
66
+ # >> Plane.construct_with_plane_and_point(Plane.new(2, -3, 4, 5), Point.new(1, 1, 1))
67
+ # => Plane.new(2, -3, 4, -3)
68
+ #
69
+ # Arguments:
70
+ # vector1: (Vector)
71
+ # vector2: (Vector)
72
+ # point: (Point)
73
+
74
+ def self.construct_with_plane_and_point(plane, point)
75
+ Plane.new(*plane.to_a.take(3), find_d(plane.to_a.take(3), point))
76
+ end
77
+
78
+ def to_a
79
+ [a, b, c, d]
80
+ end
81
+
82
+ # Find normal vector of the plane
83
+ #
84
+ # Example:
85
+ # >> Plane.new(2, -5, 1.5, 3)
86
+ # => Vector.new(-2, -5, 1.5)
87
+ #
88
+ # Arguments:
89
+ # no
90
+
91
+ def find_normal_vector()
92
+ Vector.construct_with_plane(self)
93
+ end
94
+
95
+
96
+
97
+ def ==(plane)
98
+ #a == plane.a and b == plane.b and c == plane.c and d == plane.d
99
+ to_a.zip(plane.to_a).map { |a, b| a == b}.reduce(:&)
100
+ end
101
+
102
+
103
+ private
104
+ def self.find_d(array, point)
105
+ - array.zip(point.to_a).map { |a, b| a * b }.reduce(:+)
106
+ end
107
+
108
+
109
+ end
@@ -0,0 +1,92 @@
1
+ class Point
2
+ attr_accessor :x
3
+ attr_accessor :y
4
+ attr_accessor :z
5
+
6
+ def initialize(x, y, z)
7
+ @x = x
8
+ @y = y
9
+ @z = z
10
+ end
11
+
12
+ # Translate a point with a vector
13
+ #
14
+ # Example:
15
+ # >> Point.new(2, -1, 3).translate(Vector.new(1, 2, 3))
16
+ # => Point.new(3, 1, 6)
17
+ #
18
+ # Arguments:
19
+ # vector: (Vector)
20
+
21
+ def translate(vector)
22
+ Point.new(*to_a.zip(vector.to_a).map { |a, b| a + b})
23
+ end
24
+
25
+ # Check if a point is on a plane
26
+ #
27
+ # Example:
28
+ # >> Point.new(1, 1, 1).is_on_plane?(Plane.new(1, 2, 3, -6))
29
+ # => true
30
+ #
31
+ # Arguments:
32
+ # plane: (Plane)
33
+
34
+ def is_on_plane?(plane)
35
+ (plane.a * x + plane.b * y + plane.c * z + plane.d) == 0
36
+ end
37
+
38
+ # Check if a point is on a line
39
+ #
40
+ # Example:
41
+ # >> Point.new(1, 1, 4).is_on_line?(Line.new(Point.new(2, -1, 3), Vector.new(-1, 2, 1)))
42
+ # => true
43
+ #
44
+ # Arguments:
45
+ # line: (Line)
46
+
47
+ def is_on_line?(line)
48
+ to_a.zip(line.point.to_a, line.vector.to_a).map { |a, b, c| (a - b) / c }.uniq.length == 1
49
+ end
50
+
51
+ # Find the distance between two points
52
+ #
53
+ # Example:
54
+ # >> Point.new(-7, -4, 3).distance_to(Point.new(17, 6, 2.5))
55
+ # => 26.004807247891687
56
+ #
57
+ # Arguments:
58
+ # point: (Point)
59
+
60
+ def distance_to(point)
61
+ to_a.zip(point.to_a).map{|a, b| (b - a) ** 2}.reduce(:+) ** 0.5
62
+ end
63
+
64
+ # Find the midpoint between two points
65
+ #
66
+ # Example:
67
+ # >> Point.new(-7, -4, 3).get_midpoint(Point.new(17, 6, 2.5))
68
+ # => Point.new(5, 1, 2.75)
69
+ #
70
+ # Arguments:
71
+ # point: (Point)
72
+
73
+ def get_midpoint(point)
74
+ Point.new(*to_a.zip(point.to_a).map { |a, b| (a + b) / 2.0 })
75
+ end
76
+
77
+ def to_a
78
+ [x, y, z]
79
+ end
80
+
81
+
82
+ def ==(point)
83
+ @x == point.x and @y == point.y and @z == point.z
84
+ end
85
+
86
+ def round
87
+ Point.new(*to_a.map{|x| x.round(4)})
88
+ end
89
+
90
+
91
+ end
92
+
@@ -0,0 +1,115 @@
1
+ class Triangle
2
+ attr_accessor :point_a
3
+ attr_accessor :point_b
4
+ attr_accessor :point_c
5
+
6
+ def initialize(point_a, point_b, point_c)
7
+ @point_a = point_a
8
+ @point_b = point_b
9
+ @point_c = point_c
10
+ end
11
+
12
+ # Find the plane in which the triangle lies.
13
+ #
14
+ # Example:
15
+ # >> Triangle.new(Point.new(1, 2, 3), Point.new(4, 6, 9), Point.new(12, 11, 9)).get_plane
16
+ # => Plane.new(30, -48, 17, 15)
17
+ #
18
+ # Arguments:
19
+ # no
20
+
21
+ def get_plane
22
+ Plane.construct_with_three_points(point_a, point_b, point_c)
23
+ end
24
+
25
+ # Find the line in which the AB side of the triangle lies.
26
+ #
27
+ # Example:
28
+ # >> Triangle.new(Point.new(1, 2, 3), Point.new(4, 6, 9), Point.new(12, 11, 9)).get_line_ab
29
+ # => Line.new(Point.new(1, 2, 3), Vector.new(3, 4, 6))
30
+ #
31
+ # Arguments:
32
+ # no
33
+
34
+ def get_line_ab
35
+ Line.construct_with_two_points(point_a, point_b)
36
+ end
37
+
38
+ # Find the line in which the BC side of the triangle lies.
39
+ #
40
+ # Example:
41
+ # >> Triangle.new(Point.new(1, 2, 3), Point.new(4, 6, 9), Point.new(12, 11, 9)).get_line_bc
42
+ # => Line.new(Point.new(4, 6, 9), Vector.new(8, 5, 0))
43
+ #
44
+ # Arguments:
45
+ # no
46
+
47
+ def get_line_bc
48
+ Line.construct_with_two_points(point_b, point_c)
49
+ end
50
+
51
+ # Find the line in which the AC side of the triangle lies.
52
+ #
53
+ # Example:
54
+ # >> Triangle.new(Point.new(1, 2, 3), Point.new(4, 6, 9), Point.new(12, 11, 9)).get_line_ac
55
+ # => Line.new(Point.new(1, 2, 3), Vector.new(11, 9, 6))
56
+ #
57
+ # Arguments:
58
+ # no
59
+
60
+ def get_line_ac
61
+ Line.construct_with_two_points(point_a, point_c)
62
+ end
63
+
64
+ # Find the median of the triangle from the point A
65
+ #
66
+ # Example:
67
+ # >> Triangle.new(Point.new(1, 2, 3), Point.new(4, 6, 9), Point.new(12, 11, 9)).get_median_a
68
+ # => Line.new(Point.new(1, 2, 3), Vector.new(7, 6.5, 6))
69
+ #
70
+ # Arguments:
71
+ # no
72
+
73
+ def get_median_a
74
+ Line.construct_with_two_points(point_a, point_b.get_midpoint(point_c))
75
+ end
76
+
77
+ # Find the median of the triangle from the point B.
78
+ #
79
+ # Example:
80
+ # >> Triangle.new(Point.new(1, 2, 3), Point.new(4, 6, 9), Point.new(12, 11, 9)).get_median_b
81
+ # => Line.new(Point.new(4, 6, 9), Vector.new(2.5, 0.5, -3))
82
+ #
83
+ # Arguments:
84
+ # no
85
+ #Line.new(Point.new(4, 6, 9), Vector.new(2, 0, -3)).find_intersecting_point(Line.new(Point.new(12, 11, 9), Vector.new(-10, -7, -3)))
86
+ def get_median_b
87
+ Line.construct_with_two_points(point_b, point_a.get_midpoint(point_c))
88
+ end
89
+
90
+ # Find the median of the triangle from the point C.
91
+ #
92
+ # Example:
93
+ # >> Triangle.new(Point.new(1, 2, 3), Point.new(4, 6, 9), Point.new(12, 11, 9)).get_median_c
94
+ # => Line.new(Point.new(12, 11, 9), Vector.new(-9.5, -7, -3))
95
+ #
96
+ # Arguments:
97
+ # no
98
+
99
+ def get_median_c
100
+ Line.construct_with_two_points(point_c, point_a.get_midpoint(point_b))
101
+ end
102
+
103
+ # Find the centroid of the triangle.
104
+ #
105
+ # Example:
106
+ # >> Triangle.new(Point.new(1, 2, 3), Point.new(4, 6, 9), Point.new(12, 11, 9)).get_centroid
107
+ # => Point.new(5.666666666, 6.333333333, 7)
108
+ #
109
+ # Arguments:
110
+ # no
111
+
112
+ def get_centroid
113
+ get_median_a.find_intersecting_point(get_median_b)
114
+ end
115
+ end
@@ -0,0 +1,76 @@
1
+ class Vector
2
+ attr_accessor :x
3
+ attr_accessor :y
4
+ attr_accessor :z
5
+
6
+ def initialize(x, y, z)
7
+ @x = x
8
+ @y = y
9
+ @z = z
10
+ end
11
+
12
+ # Construct a vector with two points.
13
+ #
14
+ # Example:
15
+ # >> Vector.construct_with_two_points(Point.new(1, 2, 3), Point.new(3, 2, 1))
16
+ # => Vector.new(2, 0, -2)
17
+ #
18
+ # Arguments:
19
+ # first_point: (Point)
20
+ # second_point: (Point)
21
+
22
+ def self.construct_with_two_points(first_point, second_point)
23
+ Vector.new(*second_point.to_a.zip(first_point.to_a).map { |a, b| a - b} )
24
+ end
25
+
26
+ # Construct a vector as normal vector to a plane.
27
+ #
28
+ # Example:
29
+ # >> Vector.construct_with_plane(Plane.new(-2, 5, 2.5, 7))
30
+ # => Vector.new(-2, 5, 2.5)
31
+ #
32
+ # Arguments:
33
+ # first_point: (Point)
34
+ # second_point: (Point)
35
+
36
+ def self.construct_with_plane(plane)
37
+ Vector.new(*plane.to_a.take(3))
38
+ end
39
+
40
+ # Finds the sum vector of two vectors.
41
+ #
42
+ # Example:
43
+ # >> Vector.new(1, 2, 3) + (Vector.new(-2, 1, 2))
44
+ # => Vector.new(-1, 3, 5)
45
+ #
46
+ # Arguments:
47
+ # vector: (Vector)
48
+
49
+ def +(vector)
50
+ Vector.new(*to_a.zip(vector.to_a).map { |a, b| a + b } )
51
+ end
52
+
53
+ # Finds a vector perpendicular to both vectors.
54
+ #
55
+ # Example:
56
+ # >> Vector.new(1, 2, 3).cross_product(Vector.new(-2, 1, 2))
57
+ # => Vector.new(1, -8, 5)
58
+ #
59
+ # Arguments:
60
+ # vector: (Vector)
61
+
62
+ def cross_product(vector)
63
+ coordinate_x = y * vector.z - z * vector.y
64
+ coordinate_y = z * vector.x - x * vector.z
65
+ coordinate_z = x * vector.y - y * vector.x
66
+ Vector.new(coordinate_x, coordinate_y, coordinate_z)
67
+ end
68
+
69
+ def to_a()
70
+ [x, y, z]
71
+ end
72
+
73
+ def ==(vector)
74
+ x == vector.x and y == vector.y and z == vector.z
75
+ end
76
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geometry_3d
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guldjan Kupen
@@ -12,11 +12,20 @@ date: 2015-01-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A gem implementing basic 3D algorithms in Ruby.
14
14
  email: guldjan.kupen@gmail.com
15
- executables: []
15
+ executables:
16
+ - geometry_3d
16
17
  extensions: []
17
18
  extra_rdoc_files: []
18
19
  files:
20
+ - bin/geometry_3d
19
21
  - lib/geometry_3d.rb
22
+ - lib/geometry_3d/circle.rb
23
+ - lib/geometry_3d/equation.rb
24
+ - lib/geometry_3d/line.rb
25
+ - lib/geometry_3d/plane.rb
26
+ - lib/geometry_3d/point.rb
27
+ - lib/geometry_3d/triangle.rb
28
+ - lib/geometry_3d/vector.rb
20
29
  homepage: http://rubygems.org/gems/geometry_3d
21
30
  licenses:
22
31
  - MIT