lib/perfect_shape/line.rb in perfect-shape-0.0.11 vs lib/perfect_shape/line.rb in perfect-shape-0.1.0

- old
+ new

@@ -180,10 +180,26 @@ def point_segment_distance(x1, y1, x2, y2, px, py) BigDecimal(::Math.sqrt(point_segment_distance_square(x1, y1, x2, y2, px, py)).to_s) end + + # Calculates the number of times the line from (x1,y1) to (x2,y2) + # crosses the ray extending to the right from (px,py). + # If the point lies on the line, then no crossings are recorded. + # +1 is returned for a crossing where the Y coordinate is increasing + # -1 is returned for a crossing where the Y coordinate is decreasing + def point_crossings(x1, y1, x2, y2, px, py) + return 0 if (py < y1 && py < y2) + return 0 if (py >= y1 && py >= y2) + # assert(y1 != y2); + return 0 if (px >= x1 && px >= x2) + return ((y1 < y2) ? 1 : -1) if (px < x1 && px < x2) + xintercept = x1 + (py - y1) * (x2 - x1) / (y2 - y1); + return 0 if (px >= xintercept) + (y1 < y2) ? 1 : -1 + end end include MultiPoint include Equalizer.new(:points) @@ -211,8 +227,19 @@ def relative_counterclockwise(x_or_point, y = nil) x, y = normalize_point(x_or_point, y) return unless x && y Line.relative_counterclockwise(points[0][0], points[0][1], points[1][0], points[1][1], x, y) + end + + # Calculates the number of times the line + # crosses the ray extending to the right from (px,py). + # If the point lies on the line, then no crossings are recorded. + # +1 is returned for a crossing where the Y coordinate is increasing + # -1 is returned for a crossing where the Y coordinate is decreasing + def point_crossings(x_or_point, y = nil) + x, y = normalize_point(x_or_point, y) + return unless x && y + Line.point_crossings(points[0][0], points[0][1], points[1][0], points[1][1], x, y) end end end