class GreinerHormann::Polygon
Attributes
first[RW]
first_intersect[RW]
last_unprocessed[RW]
verticies[RW]
Public Class Methods
new(pnts)
click to toggle source
# File lib/greiner_hormann/polygon.rb, line 5 def initialize(pnts) self.first = self.first_intersect = self.last_unprocessed = nil self.verticies = 0 pnts.each do |pnt| add_vertex(Vertex.new(*pnt)) end end
Public Instance Methods
add_vertex(vert)
click to toggle source
# File lib/greiner_hormann/polygon.rb, line 14 def add_vertex(vert) if self.first.nil? self.first = vert self.first.next_node = vert self.first.prev_node = vert else next_n = self.first prev_n = next_n.prev_node next_n.prev_node = vert vert.next_node = next_n vert.prev_node = prev_n prev_n.next_node = vert end self.verticies += 1 end
clip(clip, source_forwards, clip_forwards)
click to toggle source
Clip polygon against another one. Result depends on algorithm direction:
Intersection: forwards forwards Union: backwars backwards Diff: backwards forwards
# File lib/greiner_hormann/polygon.rb, line 106 def clip(clip, source_forwards, clip_forwards) source_vert = self.first clip_vert = clip.first loop do unless source_vert.is_intersection loop do unless clip_vert.is_intersection i = Intersection.new(source_vert, get_next(source_vert.next_node), clip_vert, clip.get_next(clip_vert.next_node)) if i.valid source_intersection = Vertex.create_intersection(i.x, i.y, i.to_source) clip_intersection = Vertex.create_intersection(i.x, i.y, i.to_clip) source_intersection.corresponding = clip_intersection clip_intersection.corresponding = source_intersection insert_vertex(source_intersection, source_vert, get_next(source_vert.next_node)) clip.insert_vertex(clip_intersection, clip_vert, clip.get_next(clip_vert.next_node)) end end clip_vert = clip_vert.next_node break if clip_vert == clip.first end end source_vert = source_vert.next_node break if source_vert == self.first end source_vert = self.first clip_vert = clip.first source_in_clip = source_vert.is_inside(clip) clip_in_source = clip_vert.is_inside(self) source_forwards ^= source_in_clip clip_forwards ^= clip_in_source loop do if source_vert.is_intersection source_vert.is_entry = source_forwards source_forwards = !source_forwards end source_vert = source_vert.next_node break if source_vert == self.first end loop do if clip_vert.is_intersection clip_vert.is_entry = clip_forwards clip_forwards = !clip_forwards end clip_vert = clip_vert.next_node break if clip_vert == clip.first end list = [] while has_unprocessed current = get_first_intersect clipped = Polygon.new([]) clipped.add_vertex(Vertex.new(current.x, current.y)) loop do current.visit if current.is_entry loop do current = current.next_node clipped.add_vertex(Vertex.new(current.x, current.y)) break if current.is_intersection end else loop do current = current.prev_node clipped.add_vertex(Vertex.new(current.x, current.y)) break if current.is_intersection end end current = current.corresponding break if current.visited end list << clipped.get_points end if list.length == 0 list << self.get_points if source_in_clip list << clip.get_points if clip_in_source list = nil if list.length == 0 end list end
get_first_intersect()
click to toggle source
# File lib/greiner_hormann/polygon.rb, line 57 def get_first_intersect v = self.first_intersect || self.first loop do break if v.is_intersection && !v.visited v = v.next_node break if v == self.first end self.first_intersect = v v end
get_next(v)
click to toggle source
# File lib/greiner_hormann/polygon.rb, line 49 def get_next(v) c = v while c.is_intersection c = c.next_node end c end
get_points()
click to toggle source
# File lib/greiner_hormann/polygon.rb, line 87 def get_points points = [] v = self.first loop do points << [v.x, v.y] v = v.next_node break if v == self.first end points end
has_unprocessed()
click to toggle source
# File lib/greiner_hormann/polygon.rb, line 70 def has_unprocessed v = self.last_unprocessed || self.first loop do if v.is_intersection && !v.visited self.last_unprocessed = v return true end v = v.next_node break if v == self.first end self.last_unprocessed = nil false end
insert_vertex(vert, start, finish)
click to toggle source
# File lib/greiner_hormann/polygon.rb, line 32 def insert_vertex(vert, start, finish) curr_n = start while curr_n != finish && curr_n.distance < vert.distance curr_n = curr_n.next_node end vert.next_node = curr_n prev_n = curr_n.prev_node vert.prev_node = prev_n prev_n.next_node = vert curr_n.prev_node = vert self.verticies += 1 end