<blockquote>
  <p>As far as I understand, if <code>p1.x</code> is less than <code>p2.x</code> then <code>pMin = p1</code>.</p>
</blockquote>

<p>Nope. That would be true if you wanted the caller to only pass the lower-left and upper-right points, but they can be any pair of opposite points. Let's truncate to two dimensions to make it simpler. If $p_1 = (1,2)$ and $p_2 = (2,1)$, they're not the bottom-left and top-right of a rectangle, they're the <em>other</em> two corners. The bottom-left corner is $(1,1)$ and the top-right corner is $(2,2)$. It's no different in three dimensions.</p>

<p>To put it another way, an axis-aligned bounding box is the Cartesian product of three intervals or ranges, one along each axis. It's the set of all points $(x,y,z)$ where $x_{min} &lt; x &lt; x_{max}\ \wedge y_{min} &lt; y &lt; y_{max}\ \wedge z_{min} &lt; z &lt; z_{max}$. You're trying to find the smallest box that contains all of the points you're passed. (In fact, you're only passed two, but it would be the same if you had a whole set of points.) To do that, you find the interval on each axis separately. Just because one of the points you're passed in has the smallest $x$ co-ordinate, that doesn't mean it'll have the smallest $y$ or $z$ co-ordinate, so you take the min and max separately for each axis.</p>

CC BY-SA 3.0
2018-01-01T00:55:35.140Z
2018-01-01T00:55:35.140Z
Dan Hulme
<p>In short; The constructor is correct.</p>

<blockquote>
  <p>As far as I understand, if p1.x is less than p2.x then pMin = p1. So we should only be checking against p1.x and p2.x.</p>
</blockquote>

<p>I get where the confusion comes from, but the explanation meant something else. It meant that when $p1$ and $p2$ are given, they are not always ordered so that $p1$ is always $pMin$ and $p2$ is always $pMax$. So we need to find out. However, it could be that when solely looking at the x-axis, $p1$ is $pMin$, but when looking at the y-axis, $p2$ is $pMin$. So, we need to find $pMin$ and $pMax$ for each of their components, seperately.</p>

<p>If we look at a two dimensional example, we can see more easily how it works.</p>

<p>We have $p1=(7, 4)$ and $p2=(2, 6)$.</p>

<p><a href="https://i.sstatic.net/ZkEGn.png" rel="noreferrer"><img src="https://i.sstatic.net/ZkEGn.png" alt="Graph of p1 and p2"></a></p>

<p>We want to get $pMin$ and $pMax$. $pMin$ should be the lowest value for all the components. $pMax$ should be the highest value for all the components. That would make calculations a lot easier of course.</p>

<p>When looking at the graph we can easily find $pMin$ and $pMax$.</p>

<p><a href="https://i.sstatic.net/CHVe3.png" rel="noreferrer"><img src="https://i.sstatic.net/CHVe3.png" alt="pMin and pMax plotted on a graph"></a></p>

<p>$pMin=(2, 4)$ and $pMax=(7, 6)$</p>

<p>We can see that for $pMin$, we took the lowest value from $p2$ for the x component and the lowest value from $p1$ for the y component.
For $pMax$, we took the highest value from $p1$ for the x component and the highest value from $p2$ for the y component.</p>

<p>If we would only look at the x component and determined $pMin$ and $pMax$ from that, we would get $pMin=(2, 6)$ and $pMax=(7, 4)$. This works for the x component, but it makes no sense on the y component, as $pMin$ has the highest y value.</p>

<p>The bounding boxes are still the same. We still store the same rectangle, we just used different points to store it.</p>

<p>When going to the third dimension, it is still exactly the same. You just do the same for the z component as you would do for the x and y components.</p>

CC BY-SA 3.0
2018-01-01T01:00:20.183Z
2018-01-01T01:00:20.183Z
bram0101
<p>Here's a constructor to construct a axis-aligned bounding box given two opposite vertices on the bounding box, from <a href="https://rads.stackoverflow.com/amzn/click/0128006455" rel="nofollow noreferrer">Pharr's <em>Physically Based Rendering</em>, Third Edition</a>. </p>

<pre><code>BBox(const Point &amp;p1, const Point &amp;p2) {
    pMin = Point(min(p1.x, p2.x), min(p1.y, p2.y), min(p1.z, p2.z));
    pMax = Point(max(p1.x, p2.x), max(p1.y, p2.y), max(p1.z, p2.z));
}
</code></pre>

<p>I don't understand why this works; for example if I take $P_1 = (1,2,3)$ and $P_2 = (2,1,4)$, I'll get $\text{pMin} = (1,1,3)$ and $\text{pMax} = (2,2,4)$. The bounding box between $P_1$ and $P_2$ is doesn't look same as bounding box between <code>pMin</code> and <code>pMax</code>. </p>

<p>The explanation for this constructor given in the book :</p>

<blockquote>
  <p>If the caller passes two corner points (<code>p1</code> and <code>p2</code>) to define the box, since <code>p1</code> and <code>p2</code> are not necessarily chosen so that <code>p1.x</code> &lt;= <code>p2.x</code>, and so on, the constructor needs to find their component-wise minimum and maximum values.      </p>
</blockquote>

<p>As far as I understand, if <code>p1.x</code> is less than <code>p2.x</code> then <code>pMin = p1</code>. So we should only be checking against <code>p1.x</code> and <code>p2.x</code>. </p>

<p>Am I missing something ? The above constructor doesn't feel correct for axis-aligned bounding boxes.</p>

<raytracing><mathematics>
AABB bounding boxes
user8277998
# AABB bounding boxes

(Asked by: username_0 on 2017-12-31)

Here's a constructor to construct a axis-aligned bounding box given two opposite vertices on the bounding box, from [Pharr's *Physically Based Rendering*, Third Edition](https://rads.stackoverflow.com/amzn/click/0128006455).

```
BBox(const Point &p1, const Point &p2) {
    pMin = Point(min(p1.x, p2.x), min(p1.y, p2.y), min(p1.z, p2.z));
    pMax = Point(max(p1.x, p2.x), max(p1.y, p2.y), max(p1.z, p2.z));
}

```

I don't understand why this works; for example if I take $P\_1 = (1,2,3)$ and $P\_2 = (2,1,4)$, I'll get $\text{pMin} = (1,1,3)$ and $\text{pMax} = (2,2,4)$. The bounding box between $P\_1$ and $P\_2$ is doesn't look same as bounding box between `pMin` and `pMax`.

The explanation for this constructor given in the book :

> If the caller passes two corner points (`p1` and `p2`) to define the box, since `p1` and `p2` are not necessarily chosen so that `p1.x` <= `p2.x`, and so on, the constructor needs to find their component-wise minimum and maximum values.

As far as I understand, if `p1.x` is less than `p2.x` then `pMin = p1`. So we should only be checking against `p1.x` and `p2.x`.

Am I missing something ? The above constructor doesn't feel correct for axis-aligned bounding boxes.

**Tags:** raytracing, mathematics


---

## 2 answers

### Answer by username_2 on 2018-01-01. Score: 7 | Accepted answer

In short; The constructor is correct.

> As far as I understand, if p1.x is less than p2.x then pMin = p1. So we should only be checking against p1.x and p2.x.

I get where the confusion comes from, but the explanation meant something else. It meant that when $p1$ and $p2$ are given, they are not always ordered so that $p1$ is always $pMin$ and $p2$ is always $pMax$. So we need to find out. However, it could be that when solely looking at the x-axis, $p1$ is $pMin$, but when looking at the y-axis, $p2$ is $pMin$. So, we need to find $pMin$ and $pMax$ for each of their components, seperately.

If we look at a two dimensional example, we can see more easily how it works.

We have $p1=(7, 4)$ and $p2=(2, 6)$.

[![Graph of p1 and p2](https://i.sstatic.net/ZkEGn.png)](https://i.sstatic.net/ZkEGn.png)

We want to get $pMin$ and $pMax$. $pMin$ should be the lowest value for all the components. $pMax$ should be the highest value for all the components. That would make calculations a lot easier of course.

When looking at the graph we can easily find $pMin$ and $pMax$.

[![pMin and pMax plotted on a graph](https://i.sstatic.net/CHVe3.png)](https://i.sstatic.net/CHVe3.png)

$pMin=(2, 4)$ and $pMax=(7, 6)$

We can see that for $pMin$, we took the lowest value from $p2$ for the x component and the lowest value from $p1$ for the y component.
For $pMax$, we took the highest value from $p1$ for the x component and the highest value from $p2$ for the y component.

If we would only look at the x component and determined $pMin$ and $pMax$ from that, we would get $pMin=(2, 6)$ and $pMax=(7, 4)$. This works for the x component, but it makes no sense on the y component, as $pMin$ has the highest y value.

The bounding boxes are still the same. We still store the same rectangle, we just used different points to store it.

When going to the third dimension, it is still exactly the same. You just do the same for the z component as you would do for the x and y components.


---

### Answer by username_1 on 2018-01-01. Score: 3

> As far as I understand, if `p1.x` is less than `p2.x` then `pMin = p1`.

Nope. That would be true if you wanted the caller to only pass the lower-left and upper-right points, but they can be any pair of opposite points. Let's truncate to two dimensions to make it simpler. If $p\_1 = (1,2)$ and $p\_2 = (2,1)$, they're not the bottom-left and top-right of a rectangle, they're the *other* two corners. The bottom-left corner is $(1,1)$ and the top-right corner is $(2,2)$. It's no different in three dimensions.

To put it another way, an axis-aligned bounding box is the Cartesian product of three intervals or ranges, one along each axis. It's the set of all points $(x,y,z)$ where $x\_{min} < x < x\_{max}\ \wedge y\_{min} < y < y\_{max}\ \wedge z\_{min} < z < z\_{max}$. You're trying to find the smallest box that contains all of the points you're passed. (In fact, you're only passed two, but it would be the same if you had a whole set of points.) To do that, you find the interval on each axis separately. Just because one of the points you're passed in has the smallest $x$ co-ordinate, that doesn't mean it'll have the smallest $y$ or $z$ co-ordinate, so you take the min and max separately for each axis.


---

