BLI_rct: Utilities for sanitizing coordinates (ensuring min <= max)

This might be useful in some places. Much of the code makes the implicit
assumption that the rectangle has valid coordinate order, good to make
it more explicit.
This commit is contained in:
Julian Eisel 2020-01-14 16:18:41 +01:00
parent 473fc35c70
commit 388d43d85a
2 changed files with 48 additions and 0 deletions

View File

@ -39,6 +39,10 @@ bool BLI_rcti_is_empty(const struct rcti *rect);
bool BLI_rctf_is_empty(const struct rctf *rect);
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax);
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax);
bool BLI_rctf_is_valid(const struct rctf *rect);
bool BLI_rcti_is_valid(const struct rcti *rect);
void BLI_rctf_sanitize(struct rctf *rect);
void BLI_rcti_sanitize(struct rcti *rect);
void BLI_rctf_init_pt_radius(struct rctf *rect, const float xy[2], float size);
void BLI_rcti_init_pt_radius(struct rcti *rect, const int xy[2], int size);
void BLI_rcti_init_minmax(struct rcti *rect);

View File

@ -477,6 +477,50 @@ void BLI_rcti_init(rcti *rect, int xmin, int xmax, int ymin, int ymax)
}
}
/**
* Check if X-min and Y-min are less than or equal to X-max and Y-max, respectively.
* If this returns false, #BLI_rctf_sanitize() can be called to address this.
*
* This is not a hard constraint or invariant for rectangles, in some cases it may be useful to
* have max < min. Usually this is what you'd want though.
*/
bool BLI_rctf_is_valid(const rctf *rect)
{
return (rect->xmin <= rect->xmax) && (rect->ymin <= rect->ymax);
}
bool BLI_rcti_is_valid(const rcti *rect)
{
return (rect->xmin <= rect->xmax) && (rect->ymin <= rect->ymax);
}
/**
* Ensure X-min and Y-min are less than or equal to X-max and Y-max, respectively.
*/
void BLI_rctf_sanitize(rctf *rect)
{
if (rect->xmin > rect->xmax) {
SWAP(float, rect->xmin, rect->xmax);
}
if (rect->ymin > rect->ymax) {
SWAP(float, rect->ymin, rect->ymax);
}
BLI_assert(BLI_rctf_is_valid(rect));
}
void BLI_rcti_sanitize(rcti *rect)
{
if (rect->xmin > rect->xmax) {
SWAP(int, rect->xmin, rect->xmax);
}
if (rect->ymin > rect->ymax) {
SWAP(int, rect->ymin, rect->ymax);
}
BLI_assert(BLI_rcti_is_valid(rect));
}
void BLI_rctf_init_pt_radius(rctf *rect, const float xy[2], float size)
{
rect->xmin = xy[0] - size;