class Geom2D::Algorithms::PolygonOperation::SweepEvent

Represents one event of the sweep line phase, i.e. a (left or right) endpoint of a segment together with processing information.

Attributes

edge_type[RW]

The edge type of the event's segment, either :normal, :non_contributing, :same_transition or :different_transition.

in_out[RW]

True if the segment represents an inside-outside transition from (point.x, -infinity) into the polygon set to which the segment belongs.

in_result[RW]

True if this event's segment is part of the result polygon set.

left[RW]

True if the point is the left endpoint of the segment.

other_event[RW]

The other event. This event together with the other event represents a segment.

other_in_out[RW]

True if the closest segment downwards from this segment that belongs to the other polygon set represents an inside-outside transition from (point.x, -infinity).

point[R]

The point of this event, a Geom2D::Point instance.

polygon_type[R]

The type of polygon, either :clipping or :subject.

prev_in_result[RW]

The previous event/segment downwards from this segment that is part of the result polygon set.

Public Class Methods

new(left, point, polygon_type, other_event: nil, edge_type: :normal) click to toggle source

Creates a new SweepEvent.

# File lib/geom2d/algorithms/polygon_operation.rb, line 68
def initialize(left, point, polygon_type, other_event: nil, edge_type: :normal)
  @left = left
  @point = point
  @other_event = other_event
  @polygon_type = polygon_type
  @edge_type = edge_type
end

Public Instance Methods

above?(point) click to toggle source

Returns true if this event's line segment is above the point p.

# File lib/geom2d/algorithms/polygon_operation.rb, line 86
def above?(point)
  !below?(point)
end
below?(p) click to toggle source

Returns true if this event's line segment is below the point p.

# File lib/geom2d/algorithms/polygon_operation.rb, line 77
def below?(p)
  if left
    Algorithms.ccw(@point, @other_event.point, p) > 0
  else
    Algorithms.ccw(@other_event.point, @point, p) > 0
  end
end
in_result?(operation) click to toggle source

Returns true if this event's segment should be in the result based on the boolean operation.

# File lib/geom2d/algorithms/polygon_operation.rb, line 144
def in_result?(operation)
  case edge_type
  when :normal
    case operation
    when :intersection then !other_in_out
    when :union then other_in_out
    when :difference then polygon_type == :subject ? other_in_out : !other_in_out
    when :xor then true
    end
  when :same_transition
    operation == :intersection || operation == :union
  when :different_transition
    operation == :difference
  when :non_contributing
    false
  end
end
process_after?(event) click to toggle source

Returns true if this event should be *processed after the given event*.

This method is used for sorting events in the event queue of the main algorithm.

# File lib/geom2d/algorithms/polygon_operation.rb, line 98
def process_after?(event)
  if (cmp = float_compare(point.x, event.point.x)) != 0
    cmp > 0 # different x-coordinates, true if point.x is greater
  elsif (cmp = float_compare(point.y, event.point.y)) != 0
    cmp > 0 # same x-, different y-coordinates, true if point.y is greater
  elsif left != event.left
    left # same point; one is left, one is right endpoint; true if left endpoint
  elsif Algorithms.ccw(point, other_event.point, event.other_event.point) != 0
    above?(event.other_event.point) # both left or right; not collinear; true if top segment
  else
    polygon_type < event.polygon_type # true if clipping polygon
  end
end
segment() click to toggle source

Returns this event's line segment (point, other_event.point).

# File lib/geom2d/algorithms/polygon_operation.rb, line 163
def segment
  Geom2D::Segment(point, other_event.point)
end
segment_below?(event) click to toggle source

Returns true it this event's segment is below the segment of the other event.

This method is used for sorting events in the sweep line status data structure of the main algorithm.

This method is intended to be used only on left events!

# File lib/geom2d/algorithms/polygon_operation.rb, line 118
def segment_below?(event)
  if self == event
    false
  elsif Algorithms.ccw(point, other_event.point, event.point) != 0 ||
      Algorithms.ccw(point, other_event.point, event.other_event.point) != 0
    # segments are not collinear
    if point == event.point
      below?(event.other_event.point)
    elsif float_compare(point.x, event.point.x) == 0
      float_compare(point.y, event.point.y) < 0
    elsif process_after?(event)
      event.above?(point)
    else
      below?(event.point)
    end
  elsif polygon_type != event.polygon_type
    polygon_type > event.polygon_type
  elsif point == event.point
    object_id < event.object_id # just need any consistency criterion
  else
    process_after?(event)
  end
end
vertical?() click to toggle source

Returns true if this event's line segment is vertical.

# File lib/geom2d/algorithms/polygon_operation.rb, line 91
def vertical?
  float_equal(@point.x, other_event.point.x)
end