Я в растерянности. Я пытался реализовать этот код на:http://www.blackpawn.com/texts/pointinpoly/default.html
Однако я не знаю, как это возможно, что перекрестное произведение, присутствующее там между двумя 2D векторами, может также привести к 2D вектору. Это не имеет смысла для меня. Это также присутствует в некоторых примерах пересечения между многоугольниками и линиями, в прекрасной книге «Обнаружение столкновений в реальном времени» — где в кодах появляются даже скалярные тройки между 2D векторами (см., Например, стр. 189).
Проблема в том, что, насколько я могу судить, псевдо-перекрестное произведение двух 2D векторов может привести только к скаляру (v1.xv2.y-v1.yv2.x) или не более в трехмерном векторе, если добавить два ноля, поскольку этот скаляр представляет размер Z. Но как это может привести к двухмерному вектору?
Я не первый, кто спрашивает об этом, и, по совпадению, при попытке использовать тот же пример кода: Скрещенное произведение 2 2D векторов Однако, как легко увидеть, ответ, оригинальный вопрос при обновлении и комментарии в этой ветке оказались довольно беспорядочными, если я позволю себе так сказать.
Кто-нибудь знает, как я должен получить эти 2D-векторы из перекрестного произведения двух 2D-векторов? Если код должен быть предоставлен, я могу работать с C #, JavaScript и немного C ++.
РЕДАКТИРОВАТЬ — вот фрагмент кода в книге, как я уже упоминал выше:
int IntersectLineQuad(Point p, Point q, Point a, Point b, Point c, Point d, Point &r)
{
Vector pq = q - p;
Vector pa = a - p;
Vector pb = b - p;
Vector pc = c - p;
// Determine which triangle to test against by testing against diagonal first
Vector m = Cross(pc, pq);
float v = Dot(pa, m); // ScalarTriple(pq, pa, pc);
if (v >= 0.0f) {
// Test intersection against triangle abc
float u = -Dot(pb, m); // ScalarTriple(pq, pc, pb);
if (u < 0.0f) return 0;
float w = ScalarTriple(pq, pb, pa);
....
За страница, на которую вы ссылались, кажется, что они говорят о треугольнике в трехмерном пространстве:
Потому что треугольник может быть ориентирован любым способом в 3d-пространстве, …
Следовательно, все векторы, о которых они говорят, 3d векторы, и весь текст и код имеет смысл. Обратите внимание, что даже для двумерных векторов все также имеет смысл, если рассматривать кросс-произведение как 3d вектор, указывающий из экрана. И они упоминают это на странице тоже:
Если вы возьмете перекрестное произведение [B-A] и [p-A], вы получите вектор, указывающий за пределы экрана.
Их код тоже правильный, как для 2D, так и для 3D-случаев:
function SameSide(p1,p2, a,b)
cp1 = CrossProduct(b-a, p1-a)
cp2 = CrossProduct(b-a, p2-a)
if DotProduct(cp1, cp2) >= 0 then return true
else return false
Для 2d оба cp1
а также cp2
векторы, направленные за пределы экрана, и (3d) точечное произведение — это именно то, что вам нужно проверить; проверка только произведения соответствующих Z-компонентов одинакова. Если все в 3d, это тоже правильно. (Хотя я бы написал просто return DotProduct(cp1, cp2) >= 0
.)
За int IntersectLineQuad()
Я могу догадаться, что ситуация такая же: Quad
что бы это ни было, это 3D-объект, а также Vector
а также Point
в коде. Однако, если вы добавите больше деталей о том, что эта функция должна делать, это поможет.
Фактически, очевидно, что любая проблема, указанная в 2d, может быть расширена до 3d, и поэтому любой подход, который действителен в 3d, также будет действителен и для 2d, вам просто нужно представить третью ось, указывающую вне экрана. Поэтому я считаю, что это правильный (хотя и запутанный) метод, позволяющий полностью описать двумерную задачу в трехмерном выражении. Вы можете сами выполнить дополнительную работу, потому что при таком подходе некоторые значения всегда будут равны нулю, но в свою очередь (почти) один и тот же код будет работать и в общем трехмерном случае.
Других решений пока нет …