5

Say that we start with this situation:enter image description here

blue numbers correspond to index of the position

This was generated by using this script:

# u v parameters allow to define how many points according to x and y

u, v = (3, 3)
x = np.linspace(0, 2, u)
y = np.linspace(0, 1, v)

# meshgrid used to create a grid out of several arrays
xx, yy, zz = np.meshgrid(x, y, 0)

# reshaping matrix
coords = np.dstack((xx,yy,zz))
coords = np.vstack(coords)

Considering that u and v can be different and very large numbers, the main objective would be to create an array of list following this scheme: enter image description here

meaning something like :

[[0 1 4 3]
 [1 2 5 4]
 [3 4 7 6]
 [4 5 8 7]]

@hpaulj here are some examples which shows the influence of u and v parameters

enter image description here

The solution I was able to find corresponds to this:

listing = np.array([((u)*j+i, (u)*j+i+1, (u)*j+i+u+1, (u)*j+i+u) for j in range(v-1) for i in range(u-1)])

Can anyone think of a better way (cleaner, faster, more array) to achieve the same result?

4
  • hello, should the solution contain the indices or the values at each point?
    – Nonlinear
    Commented Jul 2 at 10:42
  • @Nonlinear hello, I'm not really sure to well understand ... The real values of each points correspond to xyz coordinates. Blue numbers corresponds to indices. For example, point 0 has an index equal to 0 and real value x = 0 y = 0 z = 0. No matter the real values the listing should contain point indices.
    – Certes
    Commented Jul 2 at 10:51
  • The relation between the 2 code blicks isn't obvious. Both use u,v but otherwise how are coords and listing related?
    – hpaulj
    Commented Jul 2 at 15:53
  • @hpaulj Hi, I've just edited the question to add a picture showing what's going on when we change u and v parameters. u and v are used to split data along x and y axis. But anyway the goal is to generate a list of list gathering indices of vertices like represented on the pictures (no matter what are their real coordinates). I hope this seems clearer. I am also going to ask another question which will this time focus on the position of the vertices rather than on their index.
    – Certes
    Commented Jul 4 at 7:56

3 Answers 3

2

Something like this, not necessarily fastest possible, but I think its much cleaner than your current version

import numpy as np

points_indices = np.arange(9).reshape((3, 3))

quads = np.array([
    points_indices[:-1, :-1].flatten(),  # left bottom corners
    points_indices[:-1, 1:].flatten(),    # right bottom corners
    points_indices[1:, 1:].flatten(),   # top right corners
    points_indices[1:, :-1].flatten(),   # top-left corners
]).T

print(quads)
[[0 1 4 3]
 [1 2 5 4]
 [3 4 7 6]
 [4 5 8 7]]

You may want to remove those comments.

1

If you have u columns and v rows, assuming both u >= 2 and v >= 2, then a cycle starting at index i will be [i, i + 1, i + u + 1, i + u], assuming i is a valid starting point, i.e. not on the right or top edge. You can use this plus a little broadcasting magic to build your array in a few simple instructions:

u, v = 3, 3
indices = np.empty((v - 1, u - 1, 4), dtype=int)
indices[:, :, :] = [0, 1, u+1, u]
start_index = np.arange(u * v).reshape(v, u)[:-1, :-1]
indices += start_index[:, :, None]
indices = indices.reshape([-1, 4])
1

This is an indexing problem. Your grid is given by

grid = np.arange(u * v).reshape(u, v)

We assume u >= 2 and v >= 2. The first box can be obtained thusly:

grid[[0, 1, 1, 0], [0, 0, 1, 1]]

All the other boxes are obtained by incrementing the indices shown here. In fact, we have the following indices

x = np.tile(np.array([0, 1, 1, 0]) + np.arange(u - 1)[:, None], (v - 1, 1))
y = np.repeat(np.array([0, 0, 1, 1]) + np.arange(v - 1)[:, None], u - 1, axis=0)

Now you can do

grid[x, y]

But even that's not technically necessary. The elements of grid follow a very deterministic formula:

grid[i, j] == i + u * j

That means that you don't need grid at all, just the indices x and y:

x + u * y

Not the answer you're looking for? Browse other questions tagged or ask your own question.