Skip to main content
AI Assist is now on Stack Overflow. Start a chat to get instant answers from across the network. Sign up to save and share your chats.
read the question properly
Source Link
sh1
  • 5k
  • 1
  • 21
  • 34

Compute a single random value p between 0 and (width * height - rect_width * rect_height)Sorry; completely misinterpreted the question the first time.

If p is less than width * top_border, then x = p % width and y = p / width, and we're done.

Otherwise subract width * top_border from p. Now, if p is less than (width - rect_width) * rect_height, then x = p % (width - rect_width) and y = top_border + p / (width - rect_width); then if x >= left_border then add rect_widthyou just want to pick a point randomly on the xedge of a rectangle, and we're done.try something like this:

Otherwise, subtract (width - rect_width) * rect_height from p, and set x = p % width and y = bottom_border + p / width, and you're done.

p = random.randint(0, width + width + height + height) if p < (width + height): if p < width: obj.pos.x = p obj.pos.y = 0 else: obj.pos.x = width obj.pos.y = p - width else: p = p - (width + height) if p < width: obj.pos.x = width - p obj.pos.y = height else: obj.pos.x = 0 obj.pos.y = height - (p - width) 

BasicallySimply, without the cut-out you can calculateit picks a single variable p between 0 and width * height and set x = p % width and y = p / width. It's very easy to show that that's uniform. From that you have to subtractrandom point on a line the size ofsame length as the cut-out (so you can see howperimeter of the distribution should stay uniform); andrectangle, then wrap this new rangepiecewise wraps that line around the cut-out in three sections. Above, beside,rectangle to give x and belowy coordinates.

The 'beside' case is tricky, because every x result needs to appear on one side orTo ensure that the other ofdistribution stays uniform at the cut-outcorners, and never insideeach of it. This is done by starting with a value in the rangefour segments are taken as inclusive-exclusive intervals [0, width-rect_width)(can be 0, cannot be width or height) and for any valuethey're placed such that is greater than left_border moving it right to appear on the other sideeach one of that rectangle.

I might come back and explain this better, and maybe draw some pictures, but more likely I'll forget which is why I started writing this when I don't have much time to do it wellthem starts in a different corner.

Compute a single random value p between 0 and (width * height - rect_width * rect_height).

If p is less than width * top_border, then x = p % width and y = p / width, and we're done.

Otherwise subract width * top_border from p. Now, if p is less than (width - rect_width) * rect_height, then x = p % (width - rect_width) and y = top_border + p / (width - rect_width); then if x >= left_border then add rect_width to x, and we're done.

Otherwise, subtract (width - rect_width) * rect_height from p, and set x = p % width and y = bottom_border + p / width, and you're done.

Basically, without the cut-out you can calculate a single variable p between 0 and width * height and set x = p % width and y = p / width. It's very easy to show that that's uniform. From that you have to subtract the size of the cut-out (so you can see how the distribution should stay uniform); and then wrap this new range around the cut-out in three sections. Above, beside, and below.

The 'beside' case is tricky, because every x result needs to appear on one side or the other of the cut-out, and never inside of it. This is done by starting with a value in the range [0, width-rect_width), and for any value that is greater than left_border moving it right to appear on the other side of that rectangle.

I might come back and explain this better, and maybe draw some pictures, but more likely I'll forget which is why I started writing this when I don't have much time to do it well.

Sorry; completely misinterpreted the question the first time.

If you just want to pick a point randomly on the edge of a rectangle, try something like this:

p = random.randint(0, width + width + height + height) if p < (width + height): if p < width: obj.pos.x = p obj.pos.y = 0 else: obj.pos.x = width obj.pos.y = p - width else: p = p - (width + height) if p < width: obj.pos.x = width - p obj.pos.y = height else: obj.pos.x = 0 obj.pos.y = height - (p - width) 

Simply, it picks a random point on a line the same length as the perimeter of the rectangle, then piecewise wraps that line around the rectangle to give x and y coordinates.

To ensure that the distribution stays uniform at the corners, each of the four segments are taken as inclusive-exclusive intervals (can be 0, cannot be width or height) and they're placed such that each one of them starts in a different corner.

Source Link
sh1
  • 5k
  • 1
  • 21
  • 34

Compute a single random value p between 0 and (width * height - rect_width * rect_height).

If p is less than width * top_border, then x = p % width and y = p / width, and we're done.

Otherwise subract width * top_border from p. Now, if p is less than (width - rect_width) * rect_height, then x = p % (width - rect_width) and y = top_border + p / (width - rect_width); then if x >= left_border then add rect_width to x, and we're done.

Otherwise, subtract (width - rect_width) * rect_height from p, and set x = p % width and y = bottom_border + p / width, and you're done.

Basically, without the cut-out you can calculate a single variable p between 0 and width * height and set x = p % width and y = p / width. It's very easy to show that that's uniform. From that you have to subtract the size of the cut-out (so you can see how the distribution should stay uniform); and then wrap this new range around the cut-out in three sections. Above, beside, and below.

The 'beside' case is tricky, because every x result needs to appear on one side or the other of the cut-out, and never inside of it. This is done by starting with a value in the range [0, width-rect_width), and for any value that is greater than left_border moving it right to appear on the other side of that rectangle.

I might come back and explain this better, and maybe draw some pictures, but more likely I'll forget which is why I started writing this when I don't have much time to do it well.