Index to coordinates conversion, according the matrix shape

Hello,

I would like to converte an index (of a flatten array) to a
multi-dimensions coordinates (of the multi-dimensions version of the
previous flatten array).

Example:

Considering the following 2 dimensions array (3x3):

    [ [ -, -, - ],
      [ *, -, - ],
      [ -, -, - ] ]

We can see that, the coordinates of the checked case is [0, 1].

Now, if we flat this array, it looks like:

    [ -, -, -, *, -, -, -, -, - ]

Here, we can see the coordinate (or the index) of the checked case is 3.

But how can we do the opposite? I mean, a method looking like:

    index_to_coordinates([3, 3], 3) # => [0, 1]

Thanks!

···

--
Posted via http://www.ruby-forum.com/.

This is a perfect case for modulo (%). It gives the remainder of a division.

     def index_to_coordinates arr_size, index
       x = index % arr_size[0]
       y = (index - x) / arr_size[0]
       return x, y
     end

     coordinates [3, 3], 3 # => [0, 1]

You will notice that the "matrix height" (arr_size[1]) is not used for the calculation. However, you might want to check that the index you ask is not out of bounds.

PS: I usually make some stupid mistakes when doing math, so the code above may be incorrect. However, the basic idea is here: modulo.

···

On 5/9/11 12:14 AM, Paul A. wrote:

Hello,

I would like to converte an index (of a flatten array) to a
multi-dimensions coordinates (of the multi-dimensions version of the
previous flatten array).

Example:

Considering the following 2 dimensions array (3x3):

     [ [ -, -, - ],
       [ *, -, - ],
       [ -, -, - ] ]

We can see that, the coordinates of the checked case is [0, 1].

Now, if we flat this array, it looks like:

     [ -, -, -, *, -, -, -, -, - ]

Here, we can see the coordinate (or the index) of the checked case is 3.

But how can we do the opposite? I mean, a method looking like:

     index_to_coordinates([3, 3], 3) # => [0, 1]

Thanks!

A small example from a project of mine. Maybe you'll find things of
interest (the each method does that conversion, for instance).

class Grid
  include Enumerable

  attr_reader :width, :height, :depth
  def initialize(width, height, depth)
    @width = width
    @height = height
    @depth = depth
    @tiles = Array.new(width * height * depth)
  end

  def include?(x, y, z)
    (0..@width).include?(x) &&
    (0..@height).include?(y) &&
    (0..@depth).include?(z)
  end

  def (x, y, z)
    if include? x, y, z
      @tiles[z * @width * @height + y * @width + x]
    else
      raise "Tile out of bound : (#{x}, #{y}, #{z}) - #{self}"
    end
  end

  def =(x, y, z, v)
    if include? x, y, z
      @tiles[z * @width * @height + y * @width + x] = v
    else
      raise "Tile out of bound : (#{x}, #{y}, #{z}) - #{self}"
    end
  end

  def each
    @tiles.each_with_index do |v, i|
      yield v,
            i % @width, # x
            (i / @width) % @height, # y
            i / (@height * @width) # z
    end
  end

  def window(x, y, z, w, h, d)
    z.upto(z + d - 1) do |sz|
      y.upto(y + h - 1) do |sy|
        x.upto(x + w - 1) do |sx|
          yield self[sx, sy, sz], sx, sy, sz
        end
      end
    end
  end
end

Fred

···

Le 9 mai 2011 à 00:14, Paul A. a écrit :

But how can we do the opposite? I mean, a method looking like:

    index_to_coordinates([3, 3], 3) # => [0, 1]

--
No will to wake for this morn
To see another black rose born
Deathbed is slowly covered with snow
                                            (Nightwish, End of All Hope)

Hashmal wrote in post #997453:

This is a perfect case for modulo (%). It gives the remainder of a
division.

     def index_to_coordinates arr_size, index
       x = index % arr_size[0]
       y = (index - x) / arr_size[0]
       return x, y
     end

     coordinates [3, 3], 3 # => [0, 1]

Waw, thanks. But... is this okay with matrix of more then 2 dimensions?
:slight_smile:

Such as this one:

  NArray.object(2,3,2):
  [ [ [ nil, nil ],
      [ nil, nil ],
      [ nil, nil ] ],
    [ [ nil, nil ],
      [ nil, nil ],
      [ nil, nil ] ] ]

···

--
Posted via http://www.ruby-forum.com/\.