사각형의 대각선 모서리를 나타내는 (x1, y1) 및 (x2, y2) 2 점과 2 개의 종점을 나타내는 (x3, y3) 및 (x4, y4) 선분이 직사각형과 교차하는지 어떻게 확인할 수 있습니까?선분이 직사각형과 교차하는지 확인하는 방법은 무엇입니까?
(라인 세그먼트가 주어진 엔드 포인트 사이에 포함 바로 세그먼트입니다. 그것은 두 점으로 정의 무한 길이의 선이 아니다.)
사각형의 대각선 모서리를 나타내는 (x1, y1) 및 (x2, y2) 2 점과 2 개의 종점을 나타내는 (x3, y3) 및 (x4, y4) 선분이 직사각형과 교차하는지 어떻게 확인할 수 있습니까?선분이 직사각형과 교차하는지 확인하는 방법은 무엇입니까?
(라인 세그먼트가 주어진 엔드 포인트 사이에 포함 바로 세그먼트입니다. 그것은 두 점으로 정의 무한 길이의 선이 아니다.)
라인 여부를 확인하기 위해 a standard algorithm for checking whether two line segments intersect를 사용하는 한 아주 간단한 옵션이 될 것이다 세그먼트는 상자의 모서리를 구성하는 4 개의 선분과 교차합니다. 두 선분이 교차하는지 확인하는 것이 계산 상 매우 효율적이므로이 작업이 매우 빠르게 수행 될 것으로 기대합니다.
희망이 도움이됩니다.
모든 4 개의 꼭지점 (직사각형 모서리)의 내적을 선분의 방향 벡터와 함께 가져옵니다. 4 개 모두에 같은 부호 값이있는 경우 모든 정점은 선의 동일한면 (선분이 아니라 무한 선)에 있으므로 선이 직사각형을 교차하지 않습니다. 이 접근법은 2D 교차 탐지에서만 실행 가능합니다. 이것은 대다수를 신속하게 필터링하는 데 사용될 수 있습니다 (곱셈과 덧셈 만 사용). 선 대신 선분을 추가로 확인해야합니다.
나는 이것에 대해 생각해 왔습니다 ... 정확하지 않습니다. 모든 꼭지점은 선의 같은면에 놓일 수 있지만 여전히 반대 표지가있는 점 제품을 생성합니다. 또한 방향 벡터를 사용하면 실제로 선의 위치를 고려하지 않습니다. 두 개의 평행선을 선택할 수 있습니다 : 하나는 사각형을 교차하고 다른 하나는 교차하지 않습니다. 그들의 방향이 동일하기 때문에, 4 개의 내적은 두 개의 선에 대해 동일한 값을 생성 할 것이고, 이는 분명히 정리와 모순됩니다. 초기 아이디어가 좋았지 만, -1이되어야합니다. –
선분이 직사각형과 교차하는지 테스트하는 수식을 유도하는 방법을 이해하려면 vector dot product의 속성을 기억하는 것이 중요합니다.
선분을 단위 벡터 및 선분 시작점과 원점 사이의 거리로 나타냅니다. 또한 수직 벡터를 계산해야합니다
Vector vecLine = new Vector(a_ptEnd.X - a_ptStart.X, a_ptEnd.Y - a_ptStart.Y);
double dLengthLine = vecLine.Length;
vecLine /= dLengthLine;
double dDistLine = Vector.Multiply(vecLine, new Vector(a_ptStart.X, a_ptStart.Y));
하고, 선분에 대한 원점에서의 거리 : 여기 Vector
사용하여 PointF
변수 a_ptStart
및 a_ptEnd
에서 해당을 계산하는 몇 가지 C# 코드입니다. 단위 벡터를 9°으로 회전하는 것은 easy입니다.
Vector vecPerpLine = new Vector(-vecLine.Y, vecLine.X);
double dDistPerpLine = Vector.Multiply(vecPerpLine, new Vector(a_ptStart.X, a_ptStart.Y));
가 Vector
vecRect1
라는 변수 vecRect2
, vecRect3
및 vecRect4
에, 선분 대상의 경계 - 사각형의 네 모서리의 distance을 계산할
double dPerpLineDist1 = Vector.Multiply(vecPerpLine, vecRect1) - dDistPerpLine;
double dPerpLineDist2 = Vector.Multiply(vecPerpLine, vecRect2) - dDistPerpLine;
double dPerpLineDist3 = Vector.Multiply(vecPerpLine, vecRect3) - dDistPerpLine;
double dPerpLineDist4 = Vector.Multiply(vecPerpLine, vecRect4) - dDistPerpLine;
double dMinPerpLineDist = Math.Min(dPerpLineDist1, Math.Min(dPerpLineDist2,
Math.Min(dPerpLineDist3, dPerpLineDist4)));
double dMaxPerpLineDist = Math.Max(dPerpLineDist1, Math.Max(dPerpLineDist2,
Math.Max(dPerpLineDist3, dPerpLineDist4)));
모든 거리가 양수이거나 모든 거리가 음수이면 직사각형이 선의 한쪽면 또는 다른면에 있으므로 교차점이 없습니다. (제로 정도 직사각형 어떤 선분과 교차하지 않도록 고려된다.)
if (dMinPerpLineDist <= 0.0 && dMaxPerpLineDist <= 0.0
|| dMinPerpLineDist >= 0.0 && dMaxPerpLineDist >= 0.0)
/* no intersection */;
다음 프로젝트 선분 상 대상의 경계 사각형의 네 모서리. 이렇게하면 선의 원점과 해당 선의 사각형 모서리 투영 사이의 거리가 표시됩니다.
double dDistLine1 = Vector.Multiply(vecLine, vecRect1) - dDistLine;
double dDistLine2 = Vector.Multiply(vecLine, vecRect2) - dDistLine;
double dDistLine3 = Vector.Multiply(vecLine, vecRect3) - dDistLine;
double dDistLine4 = Vector.Multiply(vecLine, vecRect4) - dDistLine;
double dMinLineDist = Math.Min(dDistLine1, Math.Min(dDistLine2,
Math.Min(dDistLine3, dDistLine4)));
double dMaxLineDist = Math.Max(dDistLine1, Math.Max(dDistLine2,
Math.Max(dDistLine3, dDistLine4)));
사각형의 점이 선분의 범위 내에 있지 않으면 교차가 없습니다.
if (dMaxLineDist <= 0.0 || dMinLineDist >= dLengthLine)
/* no intersection */;
나는 그것이 충분하다고 생각한다.
이 방법은 3D로 일반화됩니까? 우리는 그 직사각형의 법선을 가정합니다. 세그먼트 방향과 법선을 사용하면 두 방향 모두에 수직 인 세 번째 방향을 얻을 수 있으므로 'vecPerpLine'을 계산할 수 있습니다. 나머지는 내적과 거리의 빼기를 사용합니다. 그건 나에게 의미가있다. 누군가 내 아이디어에 대해 의견을 말할 수 있습니까? – kotu
[line-rectangle collision detection] (http://stackoverflow.com/questions/2368211/line-rectangle-collision-detection)의 중복 가능 – templatetypedef
라인이 세그먼트 – kassak