Преобразование точки в координатную рамку, выровненную по прямоугольнику, тогда проблема становится выровненной по оси и тривиальной.
Если прямоугольник состоит из следующих 4 точек:
a b
c d
Затем получим «x-axis» и «y-axis» прямоугольника как:
x = Normalize(d-c)
y = Normalize(a-c)
Затем построим матрицу вращения, используя x и y в качестве столбцов:
r = [ x | y ]
ЕслиВы используете трехмерные координаты, нам нужна ось z:
z = CrossProduct(x, y)
r = [ x | y | z ]
Ваша матрица преобразования из мировых координат в координаты вашего прямоугольника, ориентированные по оси, становится:
T = [ r^T | -r^T * c ]
[ 0^T | 1 ]
Здесь мымы выбрали нижний левый угол c как местное происхождение."R ^ T" является транспонированным.«0 ^ T» представляет собой 2-й или 3-й вектор-строку, заполненный нулями.1 только один.Обратите внимание, что это просто обратная сторона более простого преобразования прямоугольника в мир, которое равно
T^-1 = [ r | c ]
[ 0^T | 1 ]
. Мы можем использовать T для преобразования точки в выровненные по оси координаты.Не забудьте дополнить p конечным 1, поскольку T является однородной матрицей.
tp = T * p; // Don't forget to pad p with a trailing 1 before multiplying.
// Checks that p isn't below or to the left of the rectangle.
for ( int d = 0; d < num_dimensions; ++d ) {
if ( tp[d] < 0.0 ) {
return false;
}
}
// Checks that p isn't to the right of the rectangle
double width = Length(d-c);
if ( tp[0] > width ) {
return false;
}
// Checks that p isn't above the rectangle.
double height = Length(a-c);
if ( tp[1] > height ) {
return false;
}
// p must be inside or on the rectangle.
return true
Если вы используете трехмерные координаты, обратите внимание, что в приведенном выше примере не учитывается локальное значение z преобразованной точки tp.Даже если p находится вне плоскости прямоугольника, вышеприведенное ведет себя так, как будто оно спроецировано на поверхность прямоугольника.Если вы хотите проверить копланарность, заранее сделайте следующее:
if ( fabs(tp[2]) > some_small_positive_number ) {
return false; // point is out of the rectangle's plane.
}