gmath3D 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: