Module: Silicium::Geometry
Defined Under Namespace
Classes: Figure, Line2dCanon, Point, Rectangle, Triangle, VariablesOrderException
Instance Method Summary
collapse
-
#brute_min(points, current = Float::INFINITY) ⇒ Object
Closest pair of points___ find minimum distance between two points in set.
-
#clockwise(a, b, c) ⇒ Object
Determines if a clockwise crawl is performed for defined order of points.
-
#counter_clockwise(a, b, c) ⇒ Object
Determines if a counter-clockwise crawl is performed for defined order of points.
-
#cut_by_eq(line_equation) ⇒ Object
-
#distance_point_line2d(p1, p2, a) ⇒ Object
-
#distance_point_line_normalized2d(a, b, c, p) ⇒ Object
The distance from a point to a line on a plane Normalized equation of the line.
-
#distance_point_to_point2d(a, b) ⇒ Object
Calculates the distance from given points in two-dimensional space.
-
#divide_min(points) ⇒ Object
-
#insert_eq(line_equation) ⇒ Object
-
#minimal_convex_hull_2d(points) ⇒ Object
-
#needed_variables_order?(before, after) ⇒ Boolean
-
#not_polygon?(points) ⇒ Boolean
-
#oriented_area(a, b, c) ⇒ Object
-
#process_cf(line_equation, variable) ⇒ Object
-
#process_free_member(line_equation, variable) ⇒ Object
-
#process_line_by_coordinates(line_equation, func) ⇒ Object
-
#put_point_in_part(part, point, direction) ⇒ Object
-
#sign(integer) ⇒ Object
Function for checking sign of number.
-
#vector_length(vector) ⇒ Object
-
#vectors_product(v1, v2) ⇒ Object
Instance Method Details
#brute_min(points, current = Float::INFINITY) ⇒ Object
Closest pair of points___ find minimum distance between two points in set
266
267
268
269
270
271
272
273
274
|
# File 'lib/geometry.rb', line 266
def brute_min(points, current = Float::INFINITY)
return current if points.length < 2
head = points[0]
points.delete_at(0)
new_min = points.map { |x| distance_point_to_point2d(head, x)}.min
new_сurrent = [new_min, current].min
brute_min(points, new_сurrent)
end
|
#clockwise(a, b, c) ⇒ Object
Determines if a clockwise crawl is performed for defined order of points
157
158
159
|
# File 'lib/geometry.rb', line 157
def clockwise(a, b, c)
oriented_area(a, b, c).negative?
end
|
#counter_clockwise(a, b, c) ⇒ Object
Determines if a counter-clockwise crawl is performed for defined order of points
164
165
166
|
# File 'lib/geometry.rb', line 164
def counter_clockwise(a, b, c)
oriented_area(a, b, c).positive?
end
|
#cut_by_eq(line_equation) ⇒ Object
210
211
212
|
# File 'lib/geometry.rb', line 210
def cut_by_eq(line_equation)
line_equation.slice(line_equation.index('='), line_equation.length).sub('=', '')
end
|
#distance_point_line2d(p1, p2, a) ⇒ Object
138
139
140
141
|
# File 'lib/geometry.rb', line 138
def distance_point_line2d(p1, p2, a)
line_segment_length = distance_point_to_point2d(p1, p2)
((p2.y - p1.y) * a.x - (p2.x - p1.x) * a.y + p2.x * p1.y - p2.y * p1.x).abs / (line_segment_length * 1.0)
end
|
#distance_point_line_normalized2d(a, b, c, p) ⇒ Object
The distance from a point to a line on a plane Normalized equation of the line
146
147
148
|
# File 'lib/geometry.rb', line 146
def distance_point_line_normalized2d(a, b, c, p)
(p.x * a + p.y * b - c).abs
end
|
#distance_point_to_point2d(a, b) ⇒ Object
Calculates the distance from given points in two-dimensional space
15
16
17
|
# File 'lib/geometry.rb', line 15
def distance_point_to_point2d(a, b)
Math.sqrt((b.x - a.x)**2 + (b.y - a.y)**2)
end
|
#divide_min(points) ⇒ Object
276
277
278
279
280
281
282
|
# File 'lib/geometry.rb', line 276
def divide_min(points)
half = points.length / 2
points.sort_by! { |p| [p.x, p.y] }
minimum = [brute_min(points[0..half]), brute_min(points[half..points.length])].min
near_line = points.select { |x| x > half - minimum and x < half + minimum}
min([brute_min(near_line), minimum])
end
|
#insert_eq(line_equation) ⇒ Object
284
285
286
|
# File 'lib/geometry.rb', line 284
def insert_eq(line_equation)
line_equation.gsub(' ', '').insert(line_equation.length, '=')
end
|
#minimal_convex_hull_2d(points) ⇒ Object
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
# File 'lib/geometry.rb', line 182
def minimal_convex_hull_2d(points)
return points if not_polygon?(points)
points.sort_by! { |p| [p.x, p.y] }
first = points[0]
last = points.last
up = [first]
down = [first]
(1...points.size).each do |i|
point = points[i]
is_last = i == points.size - 1
put_point_in_part(up, point, :clockwise) if is_last || clockwise(first, point, last)
put_point_in_part(down, point, :counter_clockwise) if is_last || counter_clockwise(first, point, last)
end
up + down[1...-1]
end
|
#needed_variables_order?(before, after) ⇒ Boolean
231
232
233
|
# File 'lib/geometry.rb', line 231
def needed_variables_order?(before, after)
before < after
end
|
#not_polygon?(points) ⇒ Boolean
168
169
170
|
# File 'lib/geometry.rb', line 168
def not_polygon?(points)
points.empty? || points.size == 1 || points.size == 2
end
|
#oriented_area(a, b, c) ⇒ Object
150
151
152
|
# File 'lib/geometry.rb', line 150
def oriented_area(a, b, c)
a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)
end
|
#process_cf(line_equation, variable) ⇒ Object
200
201
202
203
204
205
206
207
208
|
# File 'lib/geometry.rb', line 200
def process_cf(line_equation, variable)
if line_equation.include?(variable)
before = line_equation.index('/') + 1
after = line_equation.index('=')
line_equation.slice(before..after).gsub('=', '').sub('*', '').gsub('(', '').gsub(')', '').to_f
else
0.0
end
end
|
#process_free_member(line_equation, variable) ⇒ Object
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'lib/geometry.rb', line 235
def process_free_member(line_equation, variable)
if line_equation.include?(variable)
before = line_equation.index(variable) + 1
after = line_equation.index('/')
throw VariablesOrderException unless needed_variables_order?(before, after)
line_equation.slice(before..after).gsub('/', '').to_f * -1
else
0.0
end
end
|
#process_line_by_coordinates(line_equation, func) ⇒ Object
214
215
216
217
218
219
220
221
222
223
224
|
# File 'lib/geometry.rb', line 214
def process_line_by_coordinates(line_equation, func)
copy_line = insert_eq(line_equation)
func = method(func)
res = []
res[0] = func.call(copy_line, 'x')
copy_line = cut_by_eq(copy_line)
res[1] = func.call(copy_line, 'y')
copy_line = cut_by_eq(copy_line)
res[2] = func.call(copy_line, 'z')
res
end
|
#put_point_in_part(part, point, direction) ⇒ Object
172
173
174
175
176
|
# File 'lib/geometry.rb', line 172
def put_point_in_part(part, point, direction)
direction = method(direction)
part.pop while part.size >= 2 && !direction.call(part[part.size - 2], part[part.size - 1], point)
part.push(point)
end
|
#sign(integer) ⇒ Object
Function for checking sign of number
132
133
134
|
# File 'lib/geometry.rb', line 132
def sign(integer)
integer >= 0 ? 1 : -1
end
|
#vector_length(vector) ⇒ Object
258
259
260
|
# File 'lib/geometry.rb', line 258
def vector_length(vector)
Math.sqrt(vector[0]**2 + vector[1]**2 + vector[2]**2)
end
|
#vectors_product(v1, v2) ⇒ Object
250
251
252
253
254
255
256
|
# File 'lib/geometry.rb', line 250
def vectors_product(v1, v2)
res = Array.new(3)
(0..2).each do |i|
res[i] = v1[(i + 1) % 3] * v2[(i + 2) % 3] - v1[(i + 2) % 3] * v2[(i + 1) % 3]
end
res
end
|