gmath3D 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/quat.rb CHANGED
@@ -1,170 +1,170 @@
1
- require 'gmath3D'
2
-
3
- module GMath3D
4
- #
5
- # Quat represents quaternion.
6
- #
7
- class Quat
8
- public
9
- attr_accessor :x
10
- attr_accessor :y
11
- attr_accessor :z
12
- attr_accessor :w
13
-
14
- # [Input]
15
- # _x_, _y_, _z_, _w_should be Numeric.
16
- # [Output]
17
- # return new instance of Quat.
18
- def initialize(x=0.0,y=0.0,z=0.0,w=0.0)
19
- Util3D.check_arg_type(Numeric, x)
20
- Util3D.check_arg_type(Numeric, y)
21
- Util3D.check_arg_type(Numeric, z)
22
- Util3D.check_arg_type(Numeric, w)
23
- super()
24
- @x = x
25
- @y = y
26
- @z = z
27
- @w = w
28
- end
29
-
30
- # [Input]
31
- # _axsi_ should be Vector3 and _angle_ should be Numeric.
32
- # [Output]
33
- # return new instance of Quat.
34
- def self.from_axis(axis, angle)
35
- Util3D.check_arg_type(Vector3, axis)
36
- Util3D.check_arg_type(Numeric, angle)
37
- s = Math.sin(0.5*angle)
38
- x = s * axis.x
39
- y = s * axis.y
40
- z = s * axis.z
41
- w = Math.cos(0.5*angle)
42
- return Quat.new(x,y,z,w)
43
- end
44
-
45
- # [Input]
46
- # _matrix_ should be Matrix which row and column size are 3.
47
- # [Output]
48
- # return new instance of Quat.
49
- def self.from_matrix(mat)
50
- fourWSquaredMinus1 = mat[0,0] + mat[1,1] + mat[2,2]
51
- fourXSquaredMinus1 = mat[0,0] - mat[1,1] - mat[2,2]
52
- fourYSquaredMinus1 = mat[1,1] - mat[0,0] - mat[2,2]
53
- fourZSquaredMinus1 = mat[2,2] - mat[0,0] - mat[1,1]
54
-
55
- biggestIndex = 0
56
- fourBiggestSquaredMinus1 = fourWSquaredMinus1
57
- if(fourXSquaredMinus1 > fourBiggestSquaredMinus1)
58
- fourBiggestSquaredMinus1 = fourXSquaredMinus1
59
- biggestIndex = 1
60
- end
61
- if(fourYSquaredMinus1 > fourBiggestSquaredMinus1)
62
- fourBiggestSquaredMinus1 = fourYSquaredMinus1
63
- biggestIndex = 2
64
- end
65
- if(fourZSquaredMinus1 > fourBiggestSquaredMinus1)
66
- fourBiggestSquaredMinus1 = fourZSquaredMinus1
67
- biggestIndex = 3
68
- end
69
-
70
- biggestVal = Math.sqrt(fourBiggestSquaredMinus1 + 1.0) * 0.5
71
- multi = 0.25 / biggestVal
72
-
73
- case biggestIndex
74
- when 0
75
- w = biggestVal
76
- x = (mat[1,2] - mat[2,1]) *multi
77
- y = (mat[2,0] - mat[0,2]) *multi
78
- z = (mat[0,1] - mat[1,0]) *multi
79
- when 1
80
- x = biggestVal;
81
- w = (mat[1,2] - mat[2,1]) *multi
82
- y = (mat[0,1] + mat[1,0]) *multi
83
- z = (mat[2,0] + mat[0,2]) *multi
84
- when 2
85
- y = biggestVal;
86
- w = (mat[2,0] - mat[0,2]) *multi
87
- x = (mat[0,1] + mat[1,0]) *multi
88
- z = (mat[1,2] + mat[2,1]) *multi
89
- when 3
90
- z = biggestVal;
91
- w = (mat[0,1] - mat[1,0]) *multi
92
- x = (mat[2,0] + mat[0,2]) *multi
93
- y = (mat[1,2] + mat[2,1]) *multi
94
- end
95
- return Quat.new(x,y,z,w)
96
- end
97
-
98
- def to_element_s
99
- "[#{@x}, #{@y}, #{@z}, #{@w}]"
100
- end
101
-
102
- def to_s
103
- "Quat" + to_element_s
104
- end
105
-
106
- # [Input]
107
- # _rhs_ should be Quat.
108
- # [Output]
109
- # return true if rhs equals myself.
110
- def ==(rhs)
111
- return false if( !rhs.kind_of?(Quat) )
112
- return false if(self.x != rhs.x)
113
- return false if(self.y != rhs.y)
114
- return false if(self.z != rhs.z)
115
- return false if(self.w != rhs.w)
116
- true
117
- end
118
-
119
- # [Output]
120
- # return conjugated Quat.
121
- def conjugate
122
- return Quat.new( -self.x, -self.y, -self.z, self.w)
123
- end
124
-
125
- # [Output]
126
- # return normalized result as Quat.
127
- def normalize()
128
- mag = Math.sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
129
- return Quat.new(self.x/mag, self.y/mag, self.z/mag, self.w/mag)
130
- end
131
-
132
- # [Input]
133
- # _rhs_ should be Quat.
134
- # [Output]
135
- # return added result as Quat.
136
- def +(rhs)
137
- Util3D.check_arg_type(Quat, rhs)
138
- t1 = Vector3.new(self.x, self.y, self.z)
139
- t2 = Vector3.new(rhs.x, rhs.y, rhs.z)
140
- dot = t1.dot(t2)
141
- t3 = t2.cross(t1)
142
-
143
- t1 *= rhs.w
144
- t2 *= self.w
145
-
146
- tf = t1 + t2 + t3
147
- rtn_w = self.w * rhs.w - dot
148
-
149
- return Quat.new(tf.x, tf.y, tf.z, rtn_w)
150
- end
151
-
152
- # [Input]
153
- # _rsh_ should be Quat.
154
- # [Output]
155
- # return (outer products) multiplyed result as Quat.
156
- def *(rhs)
157
- Util3D.check_arg_type(Quat, rhs)
158
-
159
- pw = self.w; px = self.x; py = self.y; pz = self.z;
160
- qw = rhs.w ; qx = rhs.x ; qy = rhs.y ; qz = rhs.z;
161
-
162
- w = pw * qw - px * qx - py * qy - pz * qz
163
- x = pw * qx + px * qw + py * qz - pz * qy
164
- y = pw * qy - px * qz + py * qw + pz * qx
165
- z = pw * qz + px * qy - py * qx + pz * qw
166
- return Quat.new( x,y,z,w )
167
- end
168
- end
169
- end
170
-
1
+ require 'gmath3D'
2
+
3
+ module GMath3D
4
+ #
5
+ # Quat represents quaternion.
6
+ #
7
+ class Quat
8
+ public
9
+ attr_accessor :x
10
+ attr_accessor :y
11
+ attr_accessor :z
12
+ attr_accessor :w
13
+
14
+ # [Input]
15
+ # _x_, _y_, _z_, _w_should be Numeric.
16
+ # [Output]
17
+ # return new instance of Quat.
18
+ def initialize(x=0.0,y=0.0,z=0.0,w=0.0)
19
+ Util3D.check_arg_type(Numeric, x)
20
+ Util3D.check_arg_type(Numeric, y)
21
+ Util3D.check_arg_type(Numeric, z)
22
+ Util3D.check_arg_type(Numeric, w)
23
+ super()
24
+ @x = x
25
+ @y = y
26
+ @z = z
27
+ @w = w
28
+ end
29
+
30
+ # [Input]
31
+ # _axsi_ should be Vector3 and _angle_ should be Numeric.
32
+ # [Output]
33
+ # return new instance of Quat.
34
+ def self.from_axis(axis, angle)
35
+ Util3D.check_arg_type(Vector3, axis)
36
+ Util3D.check_arg_type(Numeric, angle)
37
+ s = Math.sin(0.5*angle)
38
+ x = s * axis.x
39
+ y = s * axis.y
40
+ z = s * axis.z
41
+ w = Math.cos(0.5*angle)
42
+ return Quat.new(x,y,z,w)
43
+ end
44
+
45
+ # [Input]
46
+ # _matrix_ should be Matrix which row and column size are 3.
47
+ # [Output]
48
+ # return new instance of Quat.
49
+ def self.from_matrix(mat)
50
+ fourWSquaredMinus1 = mat[0,0] + mat[1,1] + mat[2,2]
51
+ fourXSquaredMinus1 = mat[0,0] - mat[1,1] - mat[2,2]
52
+ fourYSquaredMinus1 = mat[1,1] - mat[0,0] - mat[2,2]
53
+ fourZSquaredMinus1 = mat[2,2] - mat[0,0] - mat[1,1]
54
+
55
+ biggestIndex = 0
56
+ fourBiggestSquaredMinus1 = fourWSquaredMinus1
57
+ if(fourXSquaredMinus1 > fourBiggestSquaredMinus1)
58
+ fourBiggestSquaredMinus1 = fourXSquaredMinus1
59
+ biggestIndex = 1
60
+ end
61
+ if(fourYSquaredMinus1 > fourBiggestSquaredMinus1)
62
+ fourBiggestSquaredMinus1 = fourYSquaredMinus1
63
+ biggestIndex = 2
64
+ end
65
+ if(fourZSquaredMinus1 > fourBiggestSquaredMinus1)
66
+ fourBiggestSquaredMinus1 = fourZSquaredMinus1
67
+ biggestIndex = 3
68
+ end
69
+
70
+ biggestVal = Math.sqrt(fourBiggestSquaredMinus1 + 1.0) * 0.5
71
+ multi = 0.25 / biggestVal
72
+
73
+ case biggestIndex
74
+ when 0
75
+ w = biggestVal
76
+ x = (mat[1,2] - mat[2,1]) *multi
77
+ y = (mat[2,0] - mat[0,2]) *multi
78
+ z = (mat[0,1] - mat[1,0]) *multi
79
+ when 1
80
+ x = biggestVal;
81
+ w = (mat[1,2] - mat[2,1]) *multi
82
+ y = (mat[0,1] + mat[1,0]) *multi
83
+ z = (mat[2,0] + mat[0,2]) *multi
84
+ when 2
85
+ y = biggestVal;
86
+ w = (mat[2,0] - mat[0,2]) *multi
87
+ x = (mat[0,1] + mat[1,0]) *multi
88
+ z = (mat[1,2] + mat[2,1]) *multi
89
+ when 3
90
+ z = biggestVal;
91
+ w = (mat[0,1] - mat[1,0]) *multi
92
+ x = (mat[2,0] + mat[0,2]) *multi
93
+ y = (mat[1,2] + mat[2,1]) *multi
94
+ end
95
+ return Quat.new(x,y,z,w)
96
+ end
97
+
98
+ def to_element_s
99
+ "[#{@x}, #{@y}, #{@z}, #{@w}]"
100
+ end
101
+
102
+ def to_s
103
+ "Quat" + to_element_s
104
+ end
105
+
106
+ # [Input]
107
+ # _rhs_ should be Quat.
108
+ # [Output]
109
+ # return true if rhs equals myself.
110
+ def ==(rhs)
111
+ return false if( !rhs.kind_of?(Quat) )
112
+ return false if(self.x != rhs.x)
113
+ return false if(self.y != rhs.y)
114
+ return false if(self.z != rhs.z)
115
+ return false if(self.w != rhs.w)
116
+ true
117
+ end
118
+
119
+ # [Output]
120
+ # return conjugated Quat.
121
+ def conjugate
122
+ return Quat.new( -self.x, -self.y, -self.z, self.w)
123
+ end
124
+
125
+ # [Output]
126
+ # return normalized result as Quat.
127
+ def normalize()
128
+ mag = Math.sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
129
+ return Quat.new(self.x/mag, self.y/mag, self.z/mag, self.w/mag)
130
+ end
131
+
132
+ # [Input]
133
+ # _rhs_ should be Quat.
134
+ # [Output]
135
+ # return added result as Quat.
136
+ def +(rhs)
137
+ Util3D.check_arg_type(Quat, rhs)
138
+ t1 = Vector3.new(self.x, self.y, self.z)
139
+ t2 = Vector3.new(rhs.x, rhs.y, rhs.z)
140
+ dot = t1.dot(t2)
141
+ t3 = t2.cross(t1)
142
+
143
+ t1 *= rhs.w
144
+ t2 *= self.w
145
+
146
+ tf = t1 + t2 + t3
147
+ rtn_w = self.w * rhs.w - dot
148
+
149
+ return Quat.new(tf.x, tf.y, tf.z, rtn_w)
150
+ end
151
+
152
+ # [Input]
153
+ # _rsh_ should be Quat.
154
+ # [Output]
155
+ # return (outer products) multiplyed result as Quat.
156
+ def *(rhs)
157
+ Util3D.check_arg_type(Quat, rhs)
158
+
159
+ pw = self.w; px = self.x; py = self.y; pz = self.z;
160
+ qw = rhs.w ; qx = rhs.x ; qy = rhs.y ; qz = rhs.z;
161
+
162
+ w = pw * qw - px * qx - py * qy - pz * qz
163
+ x = pw * qx + px * qw + py * qz - pz * qy
164
+ y = pw * qy - px * qz + py * qw + pz * qx
165
+ z = pw * qz + px * qy - py * qx + pz * qw
166
+ return Quat.new( x,y,z,w )
167
+ end
168
+ end
169
+ end
170
+
data/lib/rectangle.rb CHANGED
@@ -1,155 +1,155 @@
1
- require 'matrix'
2
-
3
- require 'gmath3D'
4
-
5
- module GMath3D
6
- #
7
- # Rectangle represents a four edged finite plane on 3D space.
8
- #
9
- class Rectangle < Geom
10
- public
11
- attr_accessor:base_point
12
- attr_accessor:u_vector
13
- attr_accessor:v_vector
14
-
15
- include BoxAvailable
16
-
17
- # [Input]
18
- # _base_point_ , _u_vector_, _v_vector_ should be Vector3.
19
- # _u_vector_ and _v_vector_ should be orthogonalized.
20
- # [Output]
21
- # return new instance of Rectangle.
22
- def initialize(base_point_arg = Vector3.new(), u_vector_arg = Vector3.new(1,0,0), v_vector_arg = Vector3.new(0,1,0))
23
- Util3D.check_arg_type(::Vector3, base_point_arg)
24
- Util3D.check_arg_type(::Vector3, u_vector_arg)
25
- Util3D.check_arg_type(::Vector3, v_vector_arg)
26
- super()
27
- self.base_point = base_point_arg
28
- self.u_vector = u_vector_arg
29
- self.v_vector = v_vector_arg
30
- end
31
-
32
- def initialize_copy( original_obj )
33
- @base_point = original_obj.base_point.dup
34
- @u_vector = original_obj.u_vector.dup
35
- @v_vector = original_obj.v_vector.dup
36
- end
37
-
38
- # [Input]
39
- # _rhs_ is Rectangle.
40
- # [Output]
41
- # return true if rhs equals myself.
42
- def ==(rhs)
43
- return false if rhs == nil
44
- return false if( !rhs.kind_of?(Rectangle) )
45
- return false if( self.base_point != rhs.base_point)
46
- return false if( self.u_vector != rhs.u_vector)
47
- return false if( self.v_vector != rhs.v_vector)
48
- return true
49
- end
50
-
51
- def to_s
52
- "Rectangle[base#{@base_point.to_element_s}, u#{@u_vector.to_element_s}, v#{@v_vector.to_element_s}"
53
- end
54
-
55
- # [Input]
56
- # _u_, _v_ should be Numeric.
57
- # [Output]
58
- # return point on rectangle as Vector3.
59
- def point(u, v)
60
- Util3D.check_arg_type(::Numeric, u)
61
- Util3D.check_arg_type(::Numeric, v)
62
- return base_point + u_vector*u + v_vector*v
63
- end
64
-
65
- # [Output]
66
- # return edges of rectangle as Array of FiniteLine.
67
- def edges
68
- edge_ary = Array.new(4)
69
- edge_ary[0] = FiniteLine.new( base_point, base_point+u_vector)
70
- edge_ary[1] = FiniteLine.new( base_point+u_vector, base_point+u_vector+v_vector)
71
- edge_ary[2] = FiniteLine.new( base_point+u_vector+v_vector, base_point+v_vector)
72
- edge_ary[3] = FiniteLine.new( base_point+v_vector, base_point)
73
- return edge_ary
74
- end
75
-
76
- # [Output]
77
- # return vertices of rectangle as Array of Vector3.
78
- def vertices
79
- vertices = Array.new(4)
80
- vertices[0] = base_point
81
- vertices[1] = base_point+u_vector
82
- vertices[2] = base_point+u_vector+v_vector
83
- vertices[3] = base_point+v_vector
84
- return vertices
85
- end
86
-
87
- # [Output]
88
- # return normal of rectangle as Vector3.
89
- def normal
90
- return (u_vector.cross(v_vector)).normalize()
91
- end
92
-
93
- # [Output]
94
- # return point of opposite to base_point as Vector3.
95
- def opposite_point
96
- return base_point + u_vector + v_vector
97
- end
98
-
99
- # [Output]
100
- # return center point as Vector3.
101
- def center_point
102
- return base_point + u_vector*0.5 + v_vector*0.5
103
- end
104
-
105
- # [Output]
106
- # return rectangle area as Numeric.
107
- def area
108
- return (u_vector.cross(v_vector)).length
109
- end
110
-
111
- # [Input]
112
- # _check_point_ shold be Vector3.
113
- # [Output]
114
- # return u, v parametes on check_point as [Numeric, Numeric].
115
- def uv_parameter(check_point)
116
- Util3D.check_arg_type(::Vector3, check_point)
117
- mat = Matrix[[u_vector.x, u_vector.y, u_vector.z],
118
- [v_vector.x, v_vector.y, v_vector.z],
119
- [normal.x, normal.y, normal.z]]
120
- vec = (check_point - base_point).to_column_vector
121
- ans = mat.t.inv*vec
122
- return ans[0,0], ans[1,0]
123
- end
124
-
125
- # [Input]
126
- # _target_ shold be Vector3.
127
- # [Output]
128
- # return "distance, point on rectangle" as [Numeric, Vector3].
129
- def distance(target)
130
- # with Point
131
- if(target.kind_of?(Vector3))
132
- return distance_to_point(target)
133
- elsif(target.kind_of?(Line))
134
- #with Line
135
- # return distance_to_line(target)
136
- end
137
- Util3D.raise_argurment_error(target)
138
- end
139
-
140
- private
141
- def distance_to_point(check_point)
142
- u,v = self.uv_parameter(check_point)
143
- if(u >= 0 && u <= 1 && v >= 0 && v <= 1)
144
- point_on_rect = self.point( u, v )
145
- distance = point_on_rect.distance(check_point)
146
- return distance, point_on_rect
147
- end
148
- # rectangle does not contain projected point
149
- # check distance to FiniteLines
150
- finite_lines = self.edges
151
- return FiniteLine.ary_distanc_to_point(finite_lines, check_point)
152
- end
153
- end
154
- end
155
-
1
+ require 'matrix'
2
+
3
+ require 'gmath3D'
4
+
5
+ module GMath3D
6
+ #
7
+ # Rectangle represents a four edged finite plane on 3D space.
8
+ #
9
+ class Rectangle < Geom
10
+ public
11
+ attr_accessor:base_point
12
+ attr_accessor:u_vector
13
+ attr_accessor:v_vector
14
+
15
+ include BoxAvailable
16
+
17
+ # [Input]
18
+ # _base_point_ , _u_vector_, _v_vector_ should be Vector3.
19
+ # _u_vector_ and _v_vector_ should be orthogonalized.
20
+ # [Output]
21
+ # return new instance of Rectangle.
22
+ def initialize(base_point_arg = Vector3.new(), u_vector_arg = Vector3.new(1,0,0), v_vector_arg = Vector3.new(0,1,0))
23
+ Util3D.check_arg_type(::Vector3, base_point_arg)
24
+ Util3D.check_arg_type(::Vector3, u_vector_arg)
25
+ Util3D.check_arg_type(::Vector3, v_vector_arg)
26
+ super()
27
+ self.base_point = base_point_arg
28
+ self.u_vector = u_vector_arg
29
+ self.v_vector = v_vector_arg
30
+ end
31
+
32
+ def initialize_copy( original_obj )
33
+ @base_point = original_obj.base_point.dup
34
+ @u_vector = original_obj.u_vector.dup
35
+ @v_vector = original_obj.v_vector.dup
36
+ end
37
+
38
+ # [Input]
39
+ # _rhs_ is Rectangle.
40
+ # [Output]
41
+ # return true if rhs equals myself.
42
+ def ==(rhs)
43
+ return false if rhs == nil
44
+ return false if( !rhs.kind_of?(Rectangle) )
45
+ return false if( self.base_point != rhs.base_point)
46
+ return false if( self.u_vector != rhs.u_vector)
47
+ return false if( self.v_vector != rhs.v_vector)
48
+ return true
49
+ end
50
+
51
+ def to_s
52
+ "Rectangle[base#{@base_point.to_element_s}, u#{@u_vector.to_element_s}, v#{@v_vector.to_element_s}"
53
+ end
54
+
55
+ # [Input]
56
+ # _u_, _v_ should be Numeric.
57
+ # [Output]
58
+ # return point on rectangle as Vector3.
59
+ def point(u, v)
60
+ Util3D.check_arg_type(::Numeric, u)
61
+ Util3D.check_arg_type(::Numeric, v)
62
+ return base_point + u_vector*u + v_vector*v
63
+ end
64
+
65
+ # [Output]
66
+ # return edges of rectangle as Array of FiniteLine.
67
+ def edges
68
+ edge_ary = Array.new(4)
69
+ edge_ary[0] = FiniteLine.new( base_point, base_point+u_vector)
70
+ edge_ary[1] = FiniteLine.new( base_point+u_vector, base_point+u_vector+v_vector)
71
+ edge_ary[2] = FiniteLine.new( base_point+u_vector+v_vector, base_point+v_vector)
72
+ edge_ary[3] = FiniteLine.new( base_point+v_vector, base_point)
73
+ return edge_ary
74
+ end
75
+
76
+ # [Output]
77
+ # return vertices of rectangle as Array of Vector3.
78
+ def vertices
79
+ vertices = Array.new(4)
80
+ vertices[0] = base_point
81
+ vertices[1] = base_point+u_vector
82
+ vertices[2] = base_point+u_vector+v_vector
83
+ vertices[3] = base_point+v_vector
84
+ return vertices
85
+ end
86
+
87
+ # [Output]
88
+ # return normal of rectangle as Vector3.
89
+ def normal
90
+ return (u_vector.cross(v_vector)).normalize()
91
+ end
92
+
93
+ # [Output]
94
+ # return point of opposite to base_point as Vector3.
95
+ def opposite_point
96
+ return base_point + u_vector + v_vector
97
+ end
98
+
99
+ # [Output]
100
+ # return center point as Vector3.
101
+ def center_point
102
+ return base_point + u_vector*0.5 + v_vector*0.5
103
+ end
104
+
105
+ # [Output]
106
+ # return rectangle area as Numeric.
107
+ def area
108
+ return (u_vector.cross(v_vector)).length
109
+ end
110
+
111
+ # [Input]
112
+ # _check_point_ shold be Vector3.
113
+ # [Output]
114
+ # return u, v parametes on check_point as [Numeric, Numeric].
115
+ def uv_parameter(check_point)
116
+ Util3D.check_arg_type(::Vector3, check_point)
117
+ mat = Matrix[[u_vector.x, u_vector.y, u_vector.z],
118
+ [v_vector.x, v_vector.y, v_vector.z],
119
+ [normal.x, normal.y, normal.z]]
120
+ vec = (check_point - base_point).to_column_vector
121
+ ans = mat.t.inv*vec
122
+ return ans[0,0], ans[1,0]
123
+ end
124
+
125
+ # [Input]
126
+ # _target_ shold be Vector3.
127
+ # [Output]
128
+ # return "distance, point on rectangle" as [Numeric, Vector3].
129
+ def distance(target)
130
+ # with Point
131
+ if(target.kind_of?(Vector3))
132
+ return distance_to_point(target)
133
+ elsif(target.kind_of?(Line))
134
+ #with Line
135
+ # return distance_to_line(target)
136
+ end
137
+ Util3D.raise_argurment_error(target)
138
+ end
139
+
140
+ private
141
+ def distance_to_point(check_point)
142
+ u,v = self.uv_parameter(check_point)
143
+ if(u >= 0 && u <= 1 && v >= 0 && v <= 1)
144
+ point_on_rect = self.point( u, v )
145
+ distance = point_on_rect.distance(check_point)
146
+ return distance, point_on_rect
147
+ end
148
+ # rectangle does not contain projected point
149
+ # check distance to FiniteLines
150
+ finite_lines = self.edges
151
+ return FiniteLine.ary_distanc_to_point(finite_lines, check_point)
152
+ end
153
+ end
154
+ end
155
+