RTS Drag-box math

closed account (2NywAqkS)
I'm working on an small RTS project and I've created a drag box to select units with but I'm not sure what the math is to work out if a unit should be selected or not, because it's not just a simple test to see if a point is in a box because units are also boxes not points.

Thanks,
Rowan.
Decide now what the rule will be. Pick something sensible like "for the purposes of selection by box, the centre of a unit's box shall be the point considered" or "for the purposes of selection by box, if ANY point in a unit's box is covered by the selection box, the unit is selected" or any other consistent, coherent scheme.

You have now made it simple.
Last edited on
closed account (2NywAqkS)
I've set it up so the centre of the unit's box is considered (because it seems easier), but ideally any point in the unit's box would be considered, and that's what I don't know how to do.
So how do you know that a point is inside a box?

Here's a diagram:

1
2
3
4
5
6
7
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x                                x
x                                x
x                                x
x                                x
x                                x
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

This is your selection box. See those four corners? They each have coordinates. Any point inside the box will have:

a horizontal coordinate greater than the left corners and less than the right corners AND
a vertical coordinate greater than the bottom corners and less than the top corners

So that's a set of very simple tests to establish if any given point is inside a box.

So if you can do this for ONE point, you can do it for LOTS of points. The only difference between testing for ONE point in the unit and for LOTS of points in a unit, is a couple of for loops.
Last edited on
closed account (2NywAqkS)
Using a couple of for loops to test for lots of points just seems like an inefficient way of doing things. Are you sure there isn't another test that can be done that works for every point in a rectangle?
The test does work for every point in a rectangle. The "lots" of points would be the points you are testing to see if they're inside the rectangle.
You can save yourself some time by only checking the corners of the unit box; so long as the selection box is bigger than any one unit box, and all boxes are rectangular, it's enough to test just the corners. However, if you have some situation like a very narrow but wide selection box, this could go right through the middle of a unit without clipping any corners.

Alternatively, there are some neat things you can do involving triangles and matrices and what have you. Detecting if things are inside other things is a very big field with lots of clever solutions.
Last edited on
You only need at most 2 for loops:

One for each rectangle
One for each point you want to check

Assuming you're talking about mouse-clicks only, then you only have one point, so you don't need that second loop, and can get by using just a single for loop for each rectangle.

Furthermore, you can have an "early out" so that as soon as any rectangle is found, you can stop looking:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
for( ... each rectangle 'r' ... )
{
  if( IsPointInRect( clickpos, r ) )
  {
    // user clicked in rectangle 'r'
    break;  // we can stop looking - exit the loop
  }
}

//...

bool IsPointInRect( Point p, Rect r )
{
  // this can also use the "early out" approach:
  if( p.x < r.left )  return false;
  if( p.x > r.right)  return false;
  if( p.y < r.top ) return false;
  if( p.y > r.bottom ) return false;

  return true;
}
Topic archived. No new replies allowed.