Вот реализация функции box_mul
, которая стоит за оператором *(box, point)
(от https://github.com/postgres/postgres/blob/master/src/backend/utils/adt/geo_ops.c):
static inline void
point_mul_point(Point *result, Point *pt1, Point *pt2)
{
point_construct(result,
float8_mi(float8_mul(pt1->x, pt2->x),
float8_mul(pt1->y, pt2->y)),
float8_pl(float8_mul(pt1->x, pt2->y),
float8_mul(pt1->y, pt2->x)));
}
Datum
box_mul(PG_FUNCTION_ARGS)
{
BOX *box = PG_GETARG_BOX_P(0);
Point *p = PG_GETARG_POINT_P(1);
BOX *result;
Point high,
low;
result = (BOX *) palloc(sizeof(BOX));
point_mul_point(&high, &box->high, p);
point_mul_point(&low, &box->low, p);
box_construct(result, &high, &low);
PG_RETURN_BOX_P(result);
}
или переведено на более "человеческий" язык:
((x<sub>1</sub>, y<sub>1</sub>), (x<sub>2</sub>, y<sub>2</sub>)) * (x, y) :- ((x<sub>1</sub>*x - y<sub>1</sub>*y, x<sub>1</sub>*y + y<sub>1</sub>*x), (x<sub>2</sub>*x - y<sub>2</sub>*y, x<sub>2</sub>*y + y<sub>2</sub>*x))
Для вашего примера
((1,1),(0,0)) * (0,2) = ((1*0 - 1*2, 1*2 + 1*0), (0*0 - 0*2, 0*2 + 0 * 0)) = ((-2,2),(0,0))
и, наконец, box_construct()
преобразует его в (0,2),(-2,0)
(просто отметьте select '((-2,2),(0,0))'::box;
)
Если вы знаете / помните геометрический смысл этих преобразований - опубликуйте свой окончательный ответ здесь.