https://www.acmicpc.net/problem/20149
20149번: 선분 교차 3
첫째 줄에 L1의 양 끝 점 x1, y1, x2, y2가, 둘째 줄에 L2의 양 끝 점 x3, y3, x4, y4가 주어진다.
www.acmicpc.net
선분 교차와 CCW 간의 관계는 참조 링크의 포스팅을 참조하면 된다.
선분이 일직선으로 겹칠 때(coincide), 주어진 점이 동일할 때(dotAndDot), 교차할 때(cross), 겹치지 않을 때를 구분해서 문제를 풀어야만 한다.
교차할 때, 겹치지 않을 때는 큰 문제가 되지 않았지만, 일직선으로 겹칠 때, 주어진 점이 동일할 때 어떻게 조건문을 만들어야 하는지 애먹었던 문제였다.
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <algorithm>
#include <string>
#include <iomanip>
using namespace std;
typedef long double ld;
typedef pair<int, int> pii;
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
ld x1, y1, x2, y2, x3, y3, x4, y4;
cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x4 >> y4;
ld p2p1x = x2 - x1; ld p2p1y = y2 - y1;
ld p2p3x = x2 - x3; ld p2p3y = y2 - y3;
ld p2p4x = x2 - x4; ld p2p4y = y2 - y4;
ld p4p3x = x4 - x3; ld p4p3y = y4 - y3;
ld p4p1x = x4 - x1; ld p4p1y = y4 - y1;
ld p4p2x = x4 - x2; ld p4p2y = y4 - y2;
ld ccw1 = p2p1x * p2p3y - p2p1y * p2p3x;
ld ccw2 = p2p1x * p2p4y - p2p1y * p2p4x;
ld ccw3 = p4p3x * p4p1y - p4p3y * p4p1x;
ld ccw4 = p4p3x * p4p2y - p4p3y * p4p2x;
bool cross{ true };
bool coincide{ false };
bool dotAndDot{ false };
int dot1, dot2;
if ((ccw1 < 0 && ccw2 < 0) || (ccw1 > 0 && ccw2 > 0)) cross = false;
if ((ccw3 < 0 && ccw4 < 0) || (ccw3 > 0 && ccw4 > 0)) cross = false;
if (ccw1 == 0 && ccw2 == 0 && ccw3 == 0 && ccw4 == 0)
{
if (max(x1, x2) < min(x3, x4)) cross = false;
if (min(x1, x2) > max(x3, x4)) cross = false;
if (max(y1, y2) < min(y3, y4)) cross = false;
if (min(y1, y2) > max(y3, y4)) cross = false;
if (min(x1, x2) < max(x3, x4) && max(x1, x2) > min(x3, x4)) coincide = true;
if (min(y1, y2) < max(y3, y4) && max(y1, y2) > min(y3, y4)) coincide = true;
}
if ((x1 == x3 && y1 == y3) || (x1 == x4 && y1 == y4))
{
dotAndDot = true;
dot1 = x1; dot2 = y1;
}
else if((x2 == x3 && y2 == y3) || (x2 == x4 && y2 == y4))
{
dotAndDot = true;
dot1 = x2; dot2 = y2;
}
cout << cross << "\n";
if (cross && !coincide)
{
if (dotAndDot) cout << dot1 << " " << dot2;
else
{
cout << fixed << setprecision(16);
cout << ((x2 - x1) * (x4 * y3 - x3 * y4) - (x4 - x3) * (x2 * y1 - x1 * y2))
/ ((x4 - x3) * (y2 - y1) - (x2 - x1) * (y4 - y3)) << " "
<< ((y2 - y1) * (y4 * x3 - y3 * x4) - (y4 - y3) * (y2 * x1 - y1 * x2))
/ ((y4 - y3) * (x2 - x1) - (y2 - y1) * (x4 - x3));
}
}
}
참조 링크
https://anz1217.tistory.com/105
CCW
세 점 \(A, B, C\)가 있습니다. 이 점들을 이용해 2개의 벡터 \(\overrightarrow{AB}, \overrightarrow{BC}\)를 만듭시다. 이 두 벡터의 외적값을 이용해 세 점에 대한 방향성을 알 수 있습니다. 1. \(\overrightarrow{AB}
anz1217.tistory.com
7869번: 두 원 - 기하(삼각함수) (0) | 2023.01.24 |
---|---|
2162번: 선분 그룹 - CCW, 유니온 파인드 (0) | 2023.01.23 |
11758번: CCW - CCW (0) | 2023.01.23 |
1005번: ACM Craft - 다익스트라, 위상 정렬 (0) | 2023.01.23 |
17472번: 다리 만들기 2 - 최소 스패닝 트리(MST) (0) | 2023.01.23 |
댓글 영역