module Silicium::Geometry
Constants
- Point
Represents a point as two coordinates in two-dimensional space
Public Instance Methods
brute_min(points, current = Float::INFINITY)
click to toggle source
Closest pair of points___ find minimum distance between two points in set
# 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)
click to toggle source
Determines if a clockwise crawl is performed for defined order of points
# File lib/geometry.rb, line 157 def clockwise(a, b, c) oriented_area(a, b, c).negative? end
counter_clockwise(a, b, c)
click to toggle source
Determines if a counter-clockwise crawl is performed for defined order of points
# File lib/geometry.rb, line 164 def counter_clockwise(a, b, c) oriented_area(a, b, c).positive? end
cut_by_eq(line_equation)
click to toggle source
# 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)
click to toggle source
The distance from a point to a line on a plane The line is defined by two points en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
# 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)
click to toggle source
The distance from a point to a line on a plane Normalized equation of the line
# 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)
click to toggle source
Calculates the distance from given points in two-dimensional space
# 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)
click to toggle source
# 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)
click to toggle source
# File lib/geometry.rb, line 284 def insert_eq(line_equation) line_equation.gsub(' ', '').insert(line_equation.length, '=') end
minimal_convex_hull_2d(points)
click to toggle source
Returns an array containing points that are included in the minimal convex hull for a given array of points e-maxx.ru/algo/convex_hull_graham
# 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)
click to toggle source
# File lib/geometry.rb, line 231 def needed_variables_order?(before, after) before < after end
not_polygon?(points)
click to toggle source
# File lib/geometry.rb, line 168 def not_polygon?(points) points.empty? || points.size == 1 || points.size == 2 end
oriented_area(a, b, c)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
Function for checking sign of number
# File lib/geometry.rb, line 132 def sign(integer) integer >= 0 ? 1 : -1 end
vector_length(vector)
click to toggle source
# 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)
click to toggle source
# 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