如何检查2个范围在红宝石中是否以任何方式相交?

Pix*_*elz 9 ruby range

我正在尝试在Gosu中用ruby编码Hitbox,并想检查2个范围是否满足(范围是坐标),我希望它简单地给出true或false

我调查了一下,找到了range.cover?代码,但是经过测试,这表明它仅检查一个范围是否完全适合另一个范围,而不检查它们是否仅部分连接。

#both sprites are arrays, with the following structure
#[image_data, sprite_x, sprite_y]
#image_data.width would return how wide the image is
#The x and y is the top left of the sprite
  def hit_scan(sprite1, sprite2)
    x_connect = (sprite1[1]..sprite1[1] + sprite1[0].width).cover?(sprite2[1]..(sprite2[1] + sprite2[0].width))
    y_connect = (sprite1[2]..sprite1[2] + sprite1[0].height).cover?(sprite2[2]..(sprite2[2] + sprite2[0].height)
    if x_connect == true
      if y_connect == true
        return true
      else
        return false
      end
    else
      return false
    end
  end
Run Code Online (Sandbox Code Playgroud)

这就是我尝试过的方法,只有当整个精灵都在另一个精灵中时,它才返回true。

我希望每当精灵接触时,它都会返回一个true语句,但是只有当一个精灵位于另一个中时,它才会返回true。

mrz*_*asa 6

您可以检查一个范围是否包含另一个范围的开始或结束:

r1 = (1..5)
r2 = (4..8)

r1.include?(r2.begin) || r1.include?(r2.end) || r2.include?(r1.begin) || r2.include?(r1.end)
Run Code Online (Sandbox Code Playgroud)

在您的情况下:

r1 = (sprite1[1]..sprite1[1] + sprite1[0].width)
r2 = (sprite2[1]..sprite2[1] + sprite2[0].width)
r1.include?(sprite2[1]) || r1.include?(sprite2[1] + sprite2[0].width) || 
  r2.include(sprite1[1]) || r2.include(sprite1[1] + sprite1[0].width)

Run Code Online (Sandbox Code Playgroud)

假设范围不是无限的。

  • 如果r2 = 0..8怎么办? (2认同)

Car*_*and 5

There are a number of cases to consider, as pointed out by @muistooshort in a comment.

I assume that the elements of the ranges are integers, as in the example.

Code

The easiest way to determine if two ranges intersect is to negate an expression that determines if they don't intersect.

def overlap?(r1, r2)
  return false if r1.size.zero? || r2.size.zero?
  !(range_last(r1) < r2.begin || range_last(r2) < r1.begin) 
end

def range_last(r)
  return Float::INFINITY if r.end==Float::INFINITY || r.end.nil?
  r.include?(r.end) ? r.end : r.end-1  
end
Run Code Online (Sandbox Code Playgroud)

Examples

overlap? 1..3, 2..5                               #=> true 
overlap? 1..3, 4..5                               #=> false 
overlap? 3..1, 0..5                               #=> false 
overlap? 1..4, 4..8                               #=> true 
overlap? 1...4, 4..8                              #=> false 
overlap? 4.., 1..4                                #=> true 
overlap? 4.., 1...4                               #=> false 
overlap? -Float::INFINITY..Float::INFINITY, 1..1  #=> true
overlap? -Float::INFINITY..7, 7..8                #=> true
overlap? -Float::INFINITY...7, 7..8               #=> false 
overlap? -4..Float::INFINITY, -6..-4              #=> true 
overlap? -4..Float::INFINITY, 6...-4              #=> false 
Run Code Online (Sandbox Code Playgroud)

Observe that the range 3..1 in the 3rd example is empty.

Note also:

range_last(1..)                                   #=> Infinity 
range_last(1..Float::INFINITY)                    #=> Infinity 
range_last(1..3)                                  #=> 3 
range_last(1...3)                                 #=> 2 
Run Code Online (Sandbox Code Playgroud)

If the two ranges, r1 and r2, are finite and of the two-dot variety one can replace range_last(r) with r.last.