gmath3D 0.1.1 → 0.2.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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
data/gmath3D.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{gmath3D}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Toshiyasu Shimizu"]
12
- s.date = %q{2011-09-24}
12
+ s.date = %q{2011-10-09}
13
13
  s.description = %q{This library defines 3D geometric elements(point, line, plane etc..). It can get two(or more) elements relation, like distance between two elements.}
14
14
  s.email = %q{toshi0328@gmail.com}
15
15
  s.extra_rdoc_files = [
data/lib/box.rb CHANGED
@@ -1,11 +1,19 @@
1
1
  require 'gmath3D'
2
2
 
3
3
  module GMath3D
4
+ #
5
+ # Box represents an axitially aligned box on 3D space.
6
+ #
4
7
  class Box < Geom
5
8
  public
6
9
  attr_accessor :min_point
7
10
  attr_accessor :max_point
8
11
 
12
+ # [Input]
13
+ # _point1_ and _point2_ should be Vector3.
14
+ # Each points are opposing corners.
15
+ # [Output]
16
+ # return new instance of Box.
9
17
  def initialize(point1 = Vector3.new(0,0,0), point2 = Vector3.new(1,1,1))
10
18
  Util.check_arg_type(Vector3, point1)
11
19
  Util.check_arg_type(Vector3, point2)
@@ -20,21 +28,36 @@ public
20
28
  @max_point.z = [ point1.z, point2.z ].max
21
29
  end
22
30
 
31
+ def to_s
32
+ "Box[min#{min_point.to_element_s}, max#{max_point.to_element_s}]"
33
+ end
34
+
23
35
  def ==(rhs)
24
36
  equals_inner(rhs)
25
37
  end
38
+
39
+ # [Input]
40
+ # _rhs_ shold be Vector3 or Box or Array of them.
41
+ # [Output]
42
+ # return added result as Box.
26
43
  def +(rhs)
27
44
  add(rhs)
28
45
  end
29
46
 
47
+ # [Output]
48
+ # return cente point of Box as Vector3.
30
49
  def center
31
50
  return (@min_point + @max_point) * 0.5
32
51
  end
33
52
 
53
+ # [Output]
54
+ # return x length, y lenght and z length as [Numeric, Numeric, Numeric]
34
55
  def length
35
56
  return max_point.x - min_point.x, max_point.y - min_point.y, max_point.z - min_point.z
36
57
  end
37
58
 
59
+ # [Output]
60
+ # return volume of Box as Numeric.
38
61
  def volume
39
62
  width, height, depth = self.length
40
63
  return width*height*depth
data/lib/finite_line.rb CHANGED
@@ -1,11 +1,18 @@
1
1
  require 'gmath3D'
2
2
 
3
3
  module GMath3D
4
+ #
5
+ # FiniteLine represents a finite line on 3D space.
6
+ #
4
7
  class FiniteLine < Geom
5
8
  public
6
9
  attr_accessor :start_point
7
10
  attr_accessor :end_point
8
11
 
12
+ # [Input]
13
+ # _start_point_arg_ and _end_point_arg_ should be Vector3.
14
+ # [Output]
15
+ # return new instance as FiniteLine
9
16
  def initialize(start_point_arg = Vector3.new(0.0,0.0,0.0), end_point_arg = Vector3.new(1.0,0.0,0.0))
10
17
  Util.check_arg_type(Vector3, start_point_arg)
11
18
  Util.check_arg_type(Vector3, end_point_arg)
@@ -14,10 +21,20 @@ public
14
21
  @end_point = end_point_arg
15
22
  end
16
23
 
24
+ def to_s
25
+ "FiniteLine[from#{start_point.to_element_s}, to#{end_point.to_element_s}]"
26
+ end
27
+
28
+ # [Output]
29
+ # return direction as vector from start_point to end_point as Vector3
17
30
  def direction
18
31
  @end_point - @start_point
19
32
  end
20
33
 
34
+ # [Input]
35
+ # _parameter_ should be Numeric.
36
+ # [Output]
37
+ # return a point on line at input parameter position as Vector3
21
38
  def point(parameter)
22
39
  if(parameter < 0.0 or 1.0 < parameter)
23
40
  return nil
@@ -26,10 +43,22 @@ public
26
43
  end
27
44
  end
28
45
 
46
+ # [Output]
47
+ # return length as Numeric
29
48
  def length
30
49
  @start_point.distance(@end_point)
31
50
  end
32
51
 
52
+ # This function returns closest distance between FiniteLine and anothor element.
53
+ # [Input]
54
+ # _target_ should be Vector3 or Line or FiniteLine
55
+ #
56
+ # [Output]
57
+ # [in case _target_ is Vector3]
58
+ # return "distance, closest point on myself, parameter on myself" as [Numeric, Vector3, Numeric]
59
+ # [in case _target_ is Line or FiniteLine]
60
+ # return "distance, point on myself, point on target, parameter on myself, parameter on tatget"
61
+ # as [Numeric, Vector3, Vector3, Numeric, Numeric]
33
62
  def distance(target)
34
63
  # with Point
35
64
  if(target.kind_of?(Vector3))
@@ -58,7 +87,6 @@ public
58
87
  closest_point = points_ary[distance_ary.index(distance)]
59
88
  return distance, closest_point
60
89
  end
61
-
62
90
  private
63
91
  def distance_to_point(target)
64
92
  # get distance using infinite line
@@ -81,7 +109,7 @@ private
81
109
  end
82
110
  return distance, closest_point, parameter
83
111
  end
84
-
112
+
85
113
  def distance_to_line(target_infinite_line)
86
114
  self_infinite_line = Line.new(self.start_point, self.direction)
87
115
  distance, point1, point2, parameter1, parameter2 = self_infinite_line.distance(target_infinite_line)
@@ -99,7 +127,7 @@ private
99
127
  return distance_to_end_point, self.end_point, closest_point_to_end_point, 1.0, parameter_to_end_point
100
128
  end
101
129
  end
102
-
130
+
103
131
  def distance_to_finite_line(target_finite_line)
104
132
  line1 = Line.new(self.start_point, self.direction)
105
133
  line2 = Line.new(target_finite_line.start_point, target_finite_line.direction)
data/lib/line.rb CHANGED
@@ -1,11 +1,18 @@
1
1
  require 'gmath3D'
2
2
 
3
3
  module GMath3D
4
+ #
5
+ # Line represents a infinite line on 3D space.
6
+ #
4
7
  class Line < Geom
5
8
  public
6
9
  attr_accessor :base_point
7
10
  attr_accessor :direction
8
-
11
+
12
+ # [Input]
13
+ # _point_ and _direction_ should be Vector3.
14
+ # [Output]
15
+ # return new instance of Line.
9
16
  def initialize(point = Vector3.new(0.0,0.0,0.0), direction = Vector3.new(1.0,0.0,0.0))
10
17
  Util.check_arg_type(Vector3, point)
11
18
  Util.check_arg_type(Vector3, direction)
@@ -13,12 +20,30 @@ module GMath3D
13
20
  @base_point = point
14
21
  @direction = direction
15
22
  end
16
-
23
+
24
+ def to_s
25
+ "Line[point#{@base_point.to_element_s}, vector#{@direction.to_element_s}"
26
+ end
27
+
28
+ # [Input]
29
+ # _parameter_ should be Numeric.
30
+ # [Output]
31
+ # return a point on line at input parameter position as Vector3
17
32
  def point(parameter)
18
- Util.check_arg_type(::Numeric, parameter)
33
+ Util.check_arg_type(::Numeric, parameter)
19
34
  @base_point + @direction*parameter
20
35
  end
21
-
36
+
37
+ # This function returns closest distance between Line and anothor element.
38
+ # [Input]
39
+ # _target_ should be Vector3 or Line.
40
+ #
41
+ # [Output]
42
+ # [in case _target_ is Vector3]
43
+ # return "distance, closest point on myself, parameter on myself" as [Numeric, Vector3, Numeric]
44
+ # [in case _target_ is Line]
45
+ # return "distance, point on myself, point on target, parameter on myself, parameter on tatget"
46
+ # as [Numeric, Vector3, Vector3, Numeric, Numeric]
22
47
  def distance(target)
23
48
  # with Point
24
49
  if(target.kind_of?(Vector3))
@@ -29,7 +54,7 @@ module GMath3D
29
54
  end
30
55
  Util.raise_argurment_error(target)
31
56
  end
32
-
57
+
33
58
  private
34
59
  def distance_to_point(target_point)
35
60
  point_on_line1 = self.base_point
@@ -42,7 +67,7 @@ module GMath3D
42
67
  vecPQ = vecAQ - vecAP
43
68
  return vecPQ.length, cross_point, parameter
44
69
  end
45
-
70
+
46
71
  def distance_to_line(target_line)
47
72
  if(self.direction.parallel?(target_line.direction)) then
48
73
  distanceInfo = self.distance(target_line.base_point)
@@ -52,23 +77,23 @@ module GMath3D
52
77
  line1_point2 = self.base_point + self.direction
53
78
  line2_point1 = target_line.base_point
54
79
  line2_point2 = target_line.base_point + target_line.direction
55
-
80
+
56
81
  vec_da = line1_point2 - line1_point1
57
82
  vec_db = line2_point2 - line2_point1
58
83
  vec_ab = line2_point1 - line1_point1
59
-
60
- abs_vec_db = vec_db.length*vec_db.length
61
- abs_vec_da = vec_da.length*vec_da.length
62
-
84
+
85
+ abs_vec_db = vec_db.length*vec_db.length
86
+ abs_vec_da = vec_da.length*vec_da.length
87
+
63
88
  delta = (abs_vec_da*abs_vec_db - vec_da.dot( vec_db )*vec_da.dot( vec_db ))
64
-
89
+
65
90
  if( delta < self.tolerance )
66
91
  # TODO ASSERT(false)
67
92
  return nil
68
93
  end
69
94
  parameter1 = (abs_vec_db*vec_ab.dot(vec_da) - vec_da.dot( vec_db )*vec_ab.dot( vec_db ) ) / delta
70
95
  parameter2 = (vec_da.dot( vec_db )*vec_ab.dot( vec_da ) - abs_vec_da*vec_ab.dot( vec_db ))/ delta
71
-
96
+
72
97
  line1_closest_point = line1_point1 + vec_da*parameter1
73
98
  line2_closest_point = line2_point1 + vec_db*parameter2
74
99
  distance = line1_closest_point.distance( line2_closest_point )
data/lib/plane.rb CHANGED
@@ -1,19 +1,45 @@
1
1
  require 'gmath3D'
2
2
 
3
3
  module GMath3D
4
+ #
5
+ # Plane represents a infinite plane on 3D space.
6
+ #
4
7
  class Plane < Geom
5
8
  public
6
9
  attr_accessor:base_point
7
10
  attr_accessor:normal
8
11
 
9
- def initialize(base_point_arg = Vector3.new(), normal_arg = Vector3.new(0,0,1))
10
- Util.check_arg_type(::Vector3, normal_arg)
11
- Util.check_arg_type(::Vector3, base_point_arg)
12
+ # [Input]
13
+ # _base_point_ and _normal_ should be Vector3.
14
+ # [Output]
15
+ # returns new instance of Plane.
16
+ def initialize(base_point = Vector3.new(), normal = Vector3.new(0,0,1))
17
+ Util.check_arg_type(::Vector3, normal)
18
+ Util.check_arg_type(::Vector3, base_point)
12
19
  super()
13
- @base_point = base_point_arg
14
- @normal = normal_arg.normalize()
20
+ @base_point = base_point
21
+ @normal = normal.normalize()
15
22
  end
16
23
 
24
+ def to_s
25
+ "Plane[point#{@base_point.to_element_s}, normal#{@normal.to_element_s}]"
26
+ end
27
+
28
+ # This function returns closest distance between Line and anothor element.
29
+ # [Input]
30
+ # _target_ should be Vector3 or Line or FiniteLine or Plane.
31
+ #
32
+ # [Output]
33
+ # [in case _target_ is Vector3]
34
+ # return "distance, closest point on myself" as [Numeric, Vector3].
35
+ # [in case _target_ is Line]
36
+ # return "distance, intersect point, parameter on tatget" as [Numeric, Vector3, Numeric].
37
+ # [in case _target_ is FiniteLine]
38
+ # return "distance, point on plane, point on target, parameter on target"
39
+ # as [Numeric, Vector3, Vector3, Numeric].
40
+ # [in case _target_ is Plane]
41
+ # return "distance, intersect line" as [Numeric, Vector3].
42
+
17
43
  def distance(target)
18
44
  # with Point
19
45
  if(target.kind_of?(Vector3))
@@ -31,6 +57,10 @@ public
31
57
  Util.raise_argurment_error(target)
32
58
  end
33
59
 
60
+ # [Input]
61
+ # _target_point_ should be Vector3.
62
+ # [Output]
63
+ # retrun projected point on plane as Vector3.
34
64
  def project( target_point )
35
65
  Util.check_arg_type(::Vector3, target_point)
36
66
  distance, closest_point = self.distance( target_point )
data/lib/rectangle.rb CHANGED
@@ -3,12 +3,20 @@ require 'matrix'
3
3
  require 'gmath3D'
4
4
 
5
5
  module GMath3D
6
+ #
7
+ # Rectangle represents a four edged finite plane on 3D space.
8
+ #
6
9
  class Rectangle < Geom
7
10
  public
8
11
  attr_accessor:base_point
9
12
  attr_accessor:u_vector
10
13
  attr_accessor:v_vector
11
14
 
15
+ # [Input]
16
+ # _base_point_ , _u_vector_, _v_vector_ should be Vector3.
17
+ # _u_vector_ and _v_vector_ should be orthogonalized.
18
+ # [Output]
19
+ # return new instance of Rectangle.
12
20
  def initialize(base_point_arg = Vector3.new(), u_vector_arg = Vector3.new(1,0,0), v_vector_arg = Vector3.new(0,1,0))
13
21
  Util.check_arg_type(::Vector3, base_point_arg)
14
22
  Util.check_arg_type(::Vector3, u_vector_arg)
@@ -19,12 +27,22 @@ public
19
27
  self.v_vector = v_vector_arg
20
28
  end
21
29
 
30
+ def to_s
31
+ "Rectangle[base#{@base_point.to_element_s}, u#{@u_vector.to_element_s}, v#{@v_vector.to_element_s}"
32
+ end
33
+
34
+ # [Input]
35
+ # _u_, _v_ should be Numeric.
36
+ # [Output]
37
+ # return point on rectangle as Vector3.
22
38
  def point(u, v)
23
39
  Util.check_arg_type(::Numeric, u)
24
40
  Util.check_arg_type(::Numeric, v)
25
41
  return base_point + u_vector*u + v_vector*v
26
42
  end
27
43
 
44
+ # [Output]
45
+ # return edges of rectangle as Array of FiniteLine.
28
46
  def edges
29
47
  edge_ary = Array.new(4)
30
48
  edge_ary[0] = FiniteLine.new( base_point, base_point+u_vector)
@@ -34,22 +52,34 @@ public
34
52
  return edge_ary
35
53
  end
36
54
 
55
+ # [Output]
56
+ # return normal of rectangle as Vector3.
37
57
  def normal
38
58
  return (u_vector.cross(v_vector)).normalize()
39
59
  end
40
60
 
61
+ # [Output]
62
+ # return point of opposite to base_point as Vector3.
41
63
  def opposite_point
42
64
  return base_point + u_vector + v_vector
43
65
  end
44
66
 
67
+ # [Output]
68
+ # return center point as Vector3.
45
69
  def center_point
46
70
  return base_point + u_vector*0.5 + v_vector*0.5
47
71
  end
48
72
 
73
+ # [Output]
74
+ # return rectangle area as Numeric.
49
75
  def area
50
76
  return (u_vector.cross(v_vector)).length
51
77
  end
52
78
 
79
+ # [Input]
80
+ # _check_point_ shold be Vector3.
81
+ # [Output]
82
+ # return u, v parametes on check_point as [Numeric, Numeric].
53
83
  def uv_parameter(check_point)
54
84
  Util.check_arg_type(::Vector3, check_point)
55
85
  mat = Matrix[[u_vector.x, u_vector.y, u_vector.z],
@@ -60,6 +90,10 @@ public
60
90
  return ans[0,0], ans[1,0]
61
91
  end
62
92
 
93
+ # [Input]
94
+ # _target_ shold be Vector3.
95
+ # [Output]
96
+ # return "distance, point on rectangle" as [Numeric, Vector3].
63
97
  def distance(target)
64
98
  # with Point
65
99
  if(target.kind_of?(Vector3))
data/lib/triangle.rb CHANGED
@@ -1,24 +1,41 @@
1
1
  require 'gmath3D'
2
2
 
3
3
  module GMath3D
4
+ #
5
+ # Triangle represents a three edged finite plane on 3D space.
6
+ #
4
7
  class Triangle < Geom
5
8
  public
6
9
  attr_accessor:vertices
7
10
 
8
- def initialize(vertex_arg1 = Vector3.new(), vertex_arg2 = Vector3.new(1,0,0), vertex_arg3 = Vector3.new(0,1,0))
9
- Util.check_arg_type(::Vector3, vertex_arg1)
10
- Util.check_arg_type(::Vector3, vertex_arg2)
11
- Util.check_arg_type(::Vector3, vertex_arg3)
11
+ # [Input]
12
+ # _vertex1_, _vertex2_, _vertex3_ should be Vector3.
13
+ # [Output]
14
+ # return new instance of Triangle.
15
+ def initialize(vertex1 = Vector3.new(), vertex2 = Vector3.new(1,0,0), vertex3 = Vector3.new(0,1,0))
16
+ Util.check_arg_type(::Vector3, vertex1)
17
+ Util.check_arg_type(::Vector3, vertex2)
18
+ Util.check_arg_type(::Vector3, vertex3)
12
19
  super()
13
- @vertices = Array.new([vertex_arg1, vertex_arg2, vertex_arg3])
20
+ @vertices = Array.new([vertex1, vertex2, vertex3])
14
21
  end
15
22
 
23
+ def to_s
24
+ "Triangle[#{@vertices[0].to_element_s}, #{@vertices[1].to_element_s}, #{@vertices[2].to_element_s}]"
25
+ end
26
+
27
+ # [Input]
28
+ # _parameter_ should be three element Array of Numeric.
29
+ # [Output]
30
+ # return point on triangle at parameter position as Vector3.
16
31
  def point( parameter )
17
32
  Util.check_arg_type(::Array, parameter )
18
33
  # TODO Argument check
19
34
  return self.vertices[0]*parameter[0] + self.vertices[1]*parameter[1] + self.vertices[2]*parameter[2]
20
35
  end
21
36
 
37
+ # [Output]
38
+ # return edges as three element Array of Vector3.
22
39
  def edges
23
40
  return_edges = Array.new(3)
24
41
  return_edges[0] = FiniteLine.new(self.vertices[0], self.vertices[1])
@@ -27,6 +44,8 @@ public
27
44
  return return_edges
28
45
  end
29
46
 
47
+ # [Output]
48
+ # return area as Numeric.
30
49
  def area
31
50
  vec1 = vertices[1] - vertices[0]
32
51
  vec2 = vertices[2] - vertices[0]
@@ -34,16 +53,24 @@ public
34
53
  return outer_product.length / 2.0
35
54
  end
36
55
 
56
+ # [Output]
57
+ # return center point as Vector3.
37
58
  def center
38
59
  return vertices.avg
39
60
  end
40
61
 
62
+ # [Output]
63
+ # return normal vector as Vector3.
41
64
  def normal
42
65
  vec1 = self.vertices[1] - self.vertices[0]
43
66
  vec2 = self.vertices[2] - self.vertices[0]
44
67
  return (vec1.cross(vec2).normalize)
45
68
  end
46
69
 
70
+ # [Input]
71
+ # _check_point_ should be Vector3.
72
+ # [Output]
73
+ # return barycentric_coordinate on check_point as three element Array of Numeric.
47
74
  def barycentric_coordinate( check_point )
48
75
  Util.check_arg_type(::Vector3, check_point)
49
76
 
@@ -95,6 +122,10 @@ public
95
122
  return b;
96
123
  end
97
124
 
125
+ # [Input]
126
+ # _target_ shold be Vector3.
127
+ # [Output]
128
+ # return "distance, point on triangle" as [Numeric, Vector3].
98
129
  def distance(target)
99
130
  # with Point
100
131
  if(target.kind_of?(Vector3))
@@ -106,7 +137,11 @@ public
106
137
  Util.raise_argurment_error(target)
107
138
  end
108
139
 
109
- def contains( check_point )
140
+ # [Input]
141
+ # _check_point_ shold be Vector3.
142
+ # [Output]
143
+ # return true if triangle contains _check_point_.
144
+ def contains?( check_point )
110
145
  Util.check_arg_type(Vector3, check_point )
111
146
  plane = Plane.new( vertices[0], self.normal)
112
147
  distance, projected_point = plane.distance(check_point)
@@ -117,11 +152,12 @@ public
117
152
  end
118
153
  return true
119
154
  end
155
+
120
156
  private
121
157
  def distance_to_point(target_point)
122
158
  plane = Plane.new( vertices[0], self.normal)
123
159
  distance, projected_point = plane.distance(target_point)
124
- if( self.contains(projected_point))
160
+ if( self.contains?(projected_point))
125
161
  return distance, projected_point
126
162
  end
127
163
  #check distance to FiniteLines
data/lib/vector3.rb CHANGED
@@ -1,38 +1,90 @@
1
1
  require 'gmath3D'
2
2
 
3
3
  module GMath3D
4
+ #
5
+ # Vector3 represents a point or a vector on 3D space.
6
+ #
4
7
  class Vector3 < Geom
5
8
  public
6
9
  attr_accessor :x
7
10
  attr_accessor :y
8
11
  attr_accessor :z
9
12
 
13
+ # [Input]
14
+ # _x_, _y_, _z_ should be Numeric.
15
+ # [Output]
16
+ # return new instance as Vector3.
10
17
  def initialize(x=0.0,y=0.0,z=0.0)
18
+ Util.check_arg_type(Numeric, x)
19
+ Util.check_arg_type(Numeric, y)
20
+ Util.check_arg_type(Numeric, z)
11
21
  super()
12
22
  @x = x
13
23
  @y = y
14
24
  @z = z
15
25
  end
26
+
27
+ def to_element_s
28
+ "[#{@x}, #{@y}, #{@z}]"
29
+ end
30
+
31
+ def to_s
32
+ "Vector3" + to_element_s
33
+ end
34
+
35
+ # [Input]
36
+ # _rhs_ should be Vector3.
37
+ # [Output]
38
+ # return true if rhs equals myself.
16
39
  def ==(rhs)
17
40
  equals_inner(rhs)
18
41
  end
42
+
43
+ # [Input]
44
+ # _rhs_ should be Vector3.
45
+ # [Output]
46
+ # return added result as Vector3.
19
47
  def +(rhs)
20
48
  add(rhs)
21
49
  end
50
+
51
+ # [Input]
52
+ # _rhs_ should be Vector3.
53
+ # [Output]
54
+ # return subtracted result as Vector3.
22
55
  def -(rhs)
23
56
  subtract(rhs)
24
57
  end
58
+
59
+ # [Input]
60
+ # _rsh_ should be Numeric.
61
+ # [Output]
62
+ # return multiplyed result as Vector3.
25
63
  def *(rhs)
26
64
  multiply(rhs)
27
65
  end
66
+
67
+ # [Input]
68
+ # _rhs_ should be Numeric.
69
+ # [Output]
70
+ # return divided result as Vector3.
28
71
  def /(rhs)
29
72
  divide(rhs)
30
73
  end
31
74
 
75
+ # [Input]
76
+ # _rhs_ should be Vector3.
77
+ # [Output]
78
+ # return inner product as Numeric
32
79
  def dot(rhs)
33
80
  Util.check_arg_type(Vector3, rhs)
34
81
  self.x*rhs.x + self.y*rhs.y + self.z*rhs.z
35
82
  end
83
+
84
+ # [Input]
85
+ # _rhs_ should be Vector3.
86
+ # [Output]
87
+ # return cross product as Vector3.
36
88
  def cross(rhs)
37
89
  Util.check_arg_type(Vector3, rhs)
38
90
  Vector3.new(
@@ -41,18 +93,25 @@ public
41
93
  self.x*rhs.y - self.y*rhs.x)
42
94
  end
43
95
 
96
+ # [Output]
97
+ # return vector length as Numeric
44
98
  def length
45
99
  Math::sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
46
100
  end
47
- def distance(rhs)
48
- Util.check_arg_type(Vector3, rhs)
49
- Math::sqrt((self.x - rhs.x)*(self.x - rhs.x) + (self.y - rhs.y)*(self.y - rhs.y) + (self.z - rhs.z)*(self.z - rhs.z))
50
- end
101
+
102
+ # [Input]
103
+ # _rhs_ should be Vector3.
104
+ # [Output]
105
+ # return distance between two points as Numeric.
51
106
  def distance(rhs)
52
107
  Util.check_arg_type(Vector3, rhs)
53
108
  Math::sqrt((self.x - rhs.x)*(self.x - rhs.x) + (self.y - rhs.y)*(self.y - rhs.y) + (self.z - rhs.z)*(self.z - rhs.z))
54
109
  end
55
110
 
111
+ # [Input]
112
+ # _rhs_ should be Vector3.
113
+ # [Output]
114
+ # return two vectors angle as Numeric (rad).
56
115
  def angle(rhs)
57
116
  Util.check_arg_type(Vector3, rhs)
58
117
  vec1Length = self.length ;
@@ -61,16 +120,28 @@ public
61
120
  v = self.dot(rhs)/(vec1Length*vec2Length)
62
121
  Math::acos( v )
63
122
  end
123
+
124
+ # [Output]
125
+ # return normalized vector as Vector3
64
126
  def normalize()
65
127
  self / self.length.to_f
66
128
  end
67
129
 
130
+ # [Input]
131
+ # _rhs_ should be Vector3
132
+ # [Output]
133
+ # return true if myself and rhs is parallel as boolean
68
134
  def parallel?(rhs)
69
135
  Util.check_arg_type(Vector3, rhs)
70
136
  return false if(self.length < self.tolerance or rhs.length < rhs.tolerance)
71
137
  return false if(self.cross(rhs).length > self.tolerance)
72
138
  return true
73
139
  end
140
+
141
+ # [Input]
142
+ # _rhs_ should be Vector3.
143
+ # [Output]
144
+ # return true if myself and rhs have same direction as boolean.
74
145
  def same_direction?(rhs)
75
146
  Util.check_arg_type(Vector3, rhs)
76
147
  return false if(!parallel?(rhs))
@@ -78,15 +149,24 @@ public
78
149
  return true
79
150
  end
80
151
 
152
+ # This function projects self vector to rhs vector.
153
+ # [Input]
154
+ # _rhs_ should be Vector3.
155
+ # [Output]
156
+ # return projected result as Vector3.
81
157
  def project_to(rhs)
82
158
  Util.check_arg_type(Vector3, rhs)
83
159
  return Vector3.new, 0.0 if( rhs.length < rhs.tolerance )
84
160
  parameter = self.dot( rhs ) / ( rhs.x * rhs.x + rhs.y * rhs.y + rhs.z * rhs.z ).to_f
85
161
  return rhs*parameter, parameter
86
162
  end
163
+
164
+ # [Output]
165
+ # return column vector as Matrix
87
166
  def to_column_vector
88
167
  return Matrix.column_vector([x,y,z])
89
168
  end
169
+
90
170
  private
91
171
  def equals_inner(rhs)
92
172
  return false if( !rhs.kind_of?(Vector3) )
data/test/test_box.rb CHANGED
@@ -1,4 +1,5 @@
1
- require 'box'
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'helper'
2
3
 
3
4
  include GMath3D
4
5
 
@@ -10,6 +11,10 @@ class BoxTestCase < MiniTest::Unit::TestCase
10
11
  @box = Box.new(Vector3.new(-3,2,5), Vector3.new(2,-2.5, 0))
11
12
  end
12
13
 
14
+ def test_to_s
15
+ assert_equal( "Box[min[-3, -2.5, 0], max[2, 2, 5]]", @box.to_s)
16
+ end
17
+
13
18
  def test_initalize
14
19
  assert_equal(0, @box_default.min_point.x)
15
20
  assert_equal(0, @box_default.min_point.y)
@@ -1,3 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'helper'
3
+
1
4
  include GMath3D
2
5
 
3
6
  MiniTest::Unit.autorun
@@ -7,15 +10,20 @@ class FiniteLineTestCase < MiniTest::Unit::TestCase
7
10
  start_point_tmp = Vector3.new(1.0, 0.0, 2.0)
8
11
  end_point_tmp = Vector3.new(1.0, -3.5, 1.0)
9
12
  line = FiniteLine.new(start_point_tmp, end_point_tmp)
10
-
13
+
11
14
  assert_equal(start_point_tmp ,line.start_point)
12
15
  assert_equal(end_point_tmp ,line.end_point )
13
-
16
+
14
17
  lineDefault = FiniteLine.new()
15
18
  assert_equal(Vector3.new(0,0,0), lineDefault.start_point)
16
19
  assert_equal(Vector3.new(1,0,0), lineDefault.end_point )
17
20
  end
18
-
21
+
22
+ def test_to_s
23
+ line = FiniteLine.new(Vector3.new(1,0,2), Vector3.new(1,-3.5,2))
24
+ assert_equal("FiniteLine[from[1, 0, 2], to[1, -3.5, 2]]", line.to_s)
25
+ end
26
+
19
27
  def test_direction
20
28
  start_point_tmp = Vector3.new(1.0, 0.0, 2.0)
21
29
  end_point_tmp = Vector3.new(1.0, -3.5, 1.0)
@@ -37,32 +45,32 @@ class FiniteLineTestCase < MiniTest::Unit::TestCase
37
45
  assert_equal( nil, line.point(-1.0))
38
46
  assert_equal( nil, line.point(1.2))
39
47
  end
40
-
48
+
41
49
  def test_length
42
50
  start_point_tmp = Vector3.new(0.0, 0.0, 2.0)
43
51
  end_point_tmp = Vector3.new(2.0, 2.0, 2.0)
44
52
  line = FiniteLine.new(start_point_tmp, end_point_tmp)
45
-
53
+
46
54
  assert_in_delta(Math::sqrt(8), line.length, line.tolerance)
47
55
  end
48
-
56
+
49
57
  def test_distance_to_point
50
58
  start_point_tmp = Vector3.new(0.0, 0.0, 2.0)
51
59
  end_point_tmp = Vector3.new(2.0, 2.0, 2.0)
52
60
  line = FiniteLine.new(start_point_tmp, end_point_tmp)
53
-
61
+
54
62
  targetPoint = Vector3.new(1.0, 1.0, -4.0)
55
63
  distance, pointOnLine, parameter = line.distance(targetPoint)
56
64
  assert_in_delta(6.0, distance, targetPoint.tolerance)
57
65
  assert_equal( Vector3.new(1.0, 1.0, 2.0), pointOnLine)
58
66
  assert_in_delta(0.5, parameter, targetPoint.tolerance)
59
-
67
+
60
68
  targetPoint2 = Vector3.new(3.0, 3.0, 2.0)
61
69
  distance, pointOnLine, parameter = line.distance(targetPoint2)
62
70
  assert_in_delta(Math::sqrt(2), distance, targetPoint.tolerance)
63
71
  assert_equal( end_point_tmp, pointOnLine)
64
72
  assert_in_delta(1.0, parameter, targetPoint.tolerance)
65
-
73
+
66
74
  targetPoint3 = Vector3.new(0.0, -1.0, 3.0)
67
75
  distance, pointOnLine, parameter = line.distance(targetPoint3)
68
76
  assert_in_delta(Math::sqrt(2), distance, targetPoint.tolerance)
@@ -74,7 +82,7 @@ class FiniteLineTestCase < MiniTest::Unit::TestCase
74
82
  distance, point_on_line, parameter = line.distance( target_point4 )
75
83
  assert_in_delta( 1, distance, line.tolerance )
76
84
  assert_equal( Vector3.new(1,3,3), point_on_line )
77
- assert_in_delta( 0.5, parameter, line.tolerance )
85
+ assert_in_delta( 0.5, parameter, line.tolerance )
78
86
  end
79
87
 
80
88
  def test_distance_to_line
@@ -148,7 +156,7 @@ class FiniteLineTestCase < MiniTest::Unit::TestCase
148
156
  assert_equal( Vector3.new(1,1,2), point2)
149
157
  assert_in_delta(0.5, parameter1, target_finite_line.tolerance)
150
158
  assert_in_delta(0.5, parameter2, target_finite_line.tolerance)
151
-
159
+
152
160
  #not intersect case1
153
161
  target_finite_line = FiniteLine.new(Vector3.new(2.0, 0.0, 4.0), Vector3.new(0.0, 2.0, 4.0))
154
162
  distance, point1, point2, parameter1, parameter2 = finite_line.distance(target_finite_line)
@@ -157,7 +165,7 @@ class FiniteLineTestCase < MiniTest::Unit::TestCase
157
165
  assert_equal( Vector3.new(1,1,4), point2)
158
166
  assert_in_delta(0.5, parameter1, target_finite_line.tolerance)
159
167
  assert_in_delta(0.5, parameter2, target_finite_line.tolerance)
160
-
168
+
161
169
  #not intersect case2
162
170
  target_finite_line = FiniteLine.new(Vector3.new(3.0, 2.0, 2.0), Vector3.new(5.0, 0.0, 2.0))
163
171
  distance, point1, point2, parameter1, parameter2 = finite_line.distance(target_finite_line)
@@ -184,7 +192,7 @@ class FiniteLineTestCase < MiniTest::Unit::TestCase
184
192
  assert_equal( Vector3.new(-2,2,0), point2)
185
193
  assert_in_delta(0, parameter1, target_finite_line.tolerance)
186
194
  assert_in_delta(1, parameter2, target_finite_line.tolerance)
187
-
195
+
188
196
  #parallel case1
189
197
  target_finite_line = FiniteLine.new(Vector3.new(4,4,0),Vector3.new(5,5,0))
190
198
  distance, point1, point2, parameter1, parameter2 = finite_line.distance(target_finite_line)
@@ -211,7 +219,7 @@ class FiniteLineTestCase < MiniTest::Unit::TestCase
211
219
  assert_equal( nil, point2)
212
220
  assert_equal( nil, parameter1)
213
221
  assert_equal( nil, parameter2)
214
-
222
+
215
223
  #including case1
216
224
  target_finite_line = FiniteLine.new(Vector3.new(2,2,2),Vector3.new(5,5,2))
217
225
  distance, point1, point2, parameter1, parameter2 = finite_line.distance(target_finite_line)
@@ -229,9 +237,8 @@ class FiniteLineTestCase < MiniTest::Unit::TestCase
229
237
  assert_equal( nil, point2)
230
238
  assert_equal( nil, parameter1)
231
239
  assert_equal( nil, parameter2)
232
-
233
240
  end
234
-
241
+
235
242
  def test_distance_to_invalid_value
236
243
  finite_line = FiniteLine.new(Vector3.new(0,1,2), Vector3.new(2,3,4))
237
244
  assert_raises ArgumentError do
data/test/test_geom.rb CHANGED
@@ -1,3 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'helper'
3
+
1
4
  include GMath3D
2
5
 
3
6
  MiniTest::Unit.autorun
data/test/test_line.rb CHANGED
@@ -1,3 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'helper'
3
+
1
4
  include GMath3D
2
5
 
3
6
  MiniTest::Unit.autorun
@@ -16,6 +19,11 @@ class LineTestCase < MiniTest::Unit::TestCase
16
19
  assert(Vector3.new(1,0,0) == lineDefault.direction )
17
20
  end
18
21
 
22
+ def test_to_s
23
+ line = Line.new(Vector3.new(2.0, 3, 5), Vector3.new(1.0, 1.0, 1.0))
24
+ assert_equal("Line[point[2.0, 3, 5], vector[1.0, 1.0, 1.0]", line.to_s);
25
+ end
26
+
19
27
  def test_point
20
28
  base_point_tmp = Vector3.new(2.0, 3.0, 5.0)
21
29
  direction_tmp = Vector3.new(1.0, 1.0, 0.0)
data/test/test_plane.rb CHANGED
@@ -1,3 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'helper'
3
+
1
4
  include GMath3D
2
5
 
3
6
  MiniTest::Unit.autorun
@@ -18,6 +21,10 @@ class PlaneTestCase < MiniTest::Unit::TestCase
18
21
  assert_equal(Geom.default_tolerance, @plane_default.tolerance)
19
22
  end
20
23
 
24
+ def test_to_s
25
+ assert_equal("Plane[point[0, 0, 1], normal[0.0, 0.0, 1.0]]", @plane.to_s)
26
+ end
27
+
21
28
  def test_distance_to_point
22
29
  target_point = Vector3.new(1,2,3)
23
30
  distance, closest_point = @plane.distance(target_point)
@@ -1,3 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'helper'
3
+
1
4
  include GMath3D
2
5
 
3
6
  MiniTest::Unit.autorun
@@ -18,6 +21,10 @@ class RectangleTestCase < MiniTest::Unit::TestCase
18
21
  assert_equal(Vector3.new(0,1,0), @rectangle_default.v_vector)
19
22
  end
20
23
 
24
+ def test_to_s
25
+ assert_equal("Rectangle[base[1, 2, 3], u[0, -0.5, 0], v[0, 0, 2]", @rectangle.to_s)
26
+ end
27
+
21
28
  def test_point
22
29
  point = @rectangle.point(0.2, 1.0)
23
30
  assert_equal(Vector3.new(1, 1.9, 5), point)
@@ -1,3 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'helper'
3
+
1
4
  include GMath3D
2
5
 
3
6
  MiniTest::Unit.autorun
@@ -18,6 +21,10 @@ class TriangleTestCase < MiniTest::Unit::TestCase
18
21
  assert_equal(Vector3.new(0,1,0), @triangle_default.vertices[2])
19
22
  end
20
23
 
24
+ def test_to_s
25
+ assert_equal("Triangle[[1, 2, 2], [1, 4, 2], [-1, 3, 0]]", @triangle.to_s)
26
+ end
27
+
21
28
  def test_point
22
29
  assert_equal(@triangle.vertices[0], @triangle.point( Array.new([1,0,0])))
23
30
  assert_equal(@triangle.vertices[1], @triangle.point( Array.new([0,1,0])))
@@ -109,13 +116,13 @@ class TriangleTestCase < MiniTest::Unit::TestCase
109
116
 
110
117
  def test_contains
111
118
  check_point = @triangle.center + @triangle.normal*3.0
112
- assert( !@triangle.contains( check_point) )
113
- assert( @triangle.contains( @triangle.center) )
114
- assert( @triangle.contains( Vector3.new( 1,3,2)))
115
- assert( @triangle.contains( Vector3.new(-1,3,0)))
116
- assert( @triangle_default.contains( Vector3.new( 0.5, 0.5, 0.0 ) ))
117
- assert( !@triangle_default.contains( Vector3.new( -1.0, 2.0, 0.0 )))
118
- assert( !@triangle_default.contains( Vector3.new( 1.0, 1.0, 0.0 )))
119
+ assert( !@triangle.contains?( check_point) )
120
+ assert( @triangle.contains?( @triangle.center) )
121
+ assert( @triangle.contains?( Vector3.new( 1,3,2)))
122
+ assert( @triangle.contains?( Vector3.new(-1,3,0)))
123
+ assert( @triangle_default.contains?( Vector3.new( 0.5, 0.5, 0.0 ) ))
124
+ assert( !@triangle_default.contains?( Vector3.new( -1.0, 2.0, 0.0 )))
125
+ assert( !@triangle_default.contains?( Vector3.new( 1.0, 1.0, 0.0 )))
119
126
  end
120
127
 
121
128
  def test_distance_to_point
data/test/test_util.rb CHANGED
@@ -1,3 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'helper'
3
+
1
4
  include GMath3D
2
5
 
3
6
  MiniTest::Unit.autorun
data/test/test_vector3.rb CHANGED
@@ -1,3 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'helper'
3
+
1
4
  include GMath3D
2
5
 
3
6
  MiniTest::Unit.autorun
@@ -5,7 +8,7 @@ MiniTest::Unit.autorun
5
8
  class Vector3TestCase < MiniTest::Unit::TestCase
6
9
  def setup
7
10
  @vector_init_zero = Vector3.new()
8
- @vector = Vector3.new(1.0, 2.0, 3.0)
11
+ @vector = Vector3.new(1, 2.0, 3.0)
9
12
  end
10
13
 
11
14
  def test_initalize
@@ -18,6 +21,18 @@ class Vector3TestCase < MiniTest::Unit::TestCase
18
21
  assert_equal(3.0, @vector.z)
19
22
 
20
23
  assert_equal(Geom.default_tolerance, @vector.tolerance)
24
+
25
+ assert_raises ArgumentError do
26
+ invalidResult = Vector3.new( "hoge" )
27
+ end
28
+ end
29
+
30
+ def test_to_s
31
+ assert_equal("Vector3[1, 2.0, 3.0]", @vector.to_s)
32
+ end
33
+
34
+ def test_to_element_s
35
+ assert_equal("[1, 2.0, 3.0]", @vector.to_element_s)
21
36
  end
22
37
 
23
38
  def test_assign_value
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gmath3D
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-24 00:00:00.000000000 +09:00
12
+ date: 2011-10-09 00:00:00.000000000 +09:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
17
- requirement: &2164436460 !ruby/object:Gem::Requirement
17
+ requirement: &2176871500 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 1.0.0
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *2164436460
25
+ version_requirements: *2176871500
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: jeweler
28
- requirement: &2164435040 !ruby/object:Gem::Requirement
28
+ requirement: &2176871020 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: 1.6.4
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *2164435040
36
+ version_requirements: *2176871020
37
37
  description: This library defines 3D geometric elements(point, line, plane etc..).
38
38
  It can get two(or more) elements relation, like distance between two elements.
39
39
  email: toshi0328@gmail.com
@@ -88,7 +88,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
88
88
  version: '0'
89
89
  segments:
90
90
  - 0
91
- hash: -1522515577061844315
91
+ hash: 3189821684836837166
92
92
  required_rubygems_version: !ruby/object:Gem::Requirement
93
93
  none: false
94
94
  requirements: