티스토리 뷰

https://www.acmicpc.net/problem/6487

 

6487번: 두 직선의 교차 여부

두 개의 직선을 나타내는 4개의 점이 입력으로 주어질 때, 두 직선이 만나는지를 확인하는 프로그램을 작성하시오.

www.acmicpc.net

그냥 단순히 두 직선의 교차 여부와 교점만을 구하면 됩니다.

 

외적을 이용하면 직선의 교점을 뭔가 더 쉽게 계산할 수 있을 거 같은데 그냥 케이스 나눠서 계산시켰습니다. 일치하는 직선이거나 평행한 직선의 여부는 두 직선의 다른 점의 방향 벡터와 기존 방향 벡터의 외적을 다시 구해 일치여부를 확인하면 됩니다. 

 

코드는 다음과 같습니다.

#include <iostream>

using namespace std;

int N;
double x1, y1;
double x2, y2;
double x3, y3;
double x4, y4;
double x, y;

void init()
{
    cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x4 >> y4;
}

void calc()
{
    // 직선 방향 벡터 구해서 방향 다르면 교점 존재
    // 방향 같으면 교점 없거나 무한
    
    pair<double, double> a = {x2 - x1, y2 - y1};
    pair<double, double> b = {x4 - x3, y4 - y3};
    // a != (0,0), b != (0,0)
    
    // (a,b), (c,d) 외적 : ad-bc
    if(a.first * b.second - a.second * b.first != 0) {
        // 방향 다름 : 교점 존재
        if(a.first == 0 && a.second != 0 && b.first != 0 && b.second != 0){
            x = x1;
            // (u, v) 방향 벡터 : (x - x1) / u = (y - y1) / v : 직선
            y = ((x - x3) / b.first) * b.second + y3;
        }
        else if(a.first == 0 && a.second != 0 && b.first != 0 && b.second == 0) {
            x = x1;
            y = y3;
        }
        else if(a.first != 0 && a.second == 0 && b.first != 0 && b.second != 0) {
            y = y1;
            x = ((y - y3) / b.second) * b.first + x3;
        }
        else if(a.first != 0 && a.second == 0 && b.first == 0 && b.second != 0) {
            x = x3;
            y = y1;
        }
        else if(a.first != 0 && a.second != 0 && b.first == 0 && b.second != 0) {
            x = x3;
            y = ((x - x1) / a.first) * a.second + y1;
        }
        else if(a.first != 0 && a.second != 0 && b.first != 0 && b.second == 0) {
            y = y3;
            x = ((y - y1) / a.second) * a.first + x1;
        }
        else if(a.first != 0 && a.second != 0 && b.first != 0 && b.second != 0) {
            // 직선 : y = px + q 
            double p1 = a.second / a.first;
            double q1 = y1 - p1 * x1;
            double p2 = b.second / b.first;
            double q2 = y3 - p2 * x3;
            x = (-1) * (q1 - q2) / (p1 - p2);
            y = p1 * ((-1) * (q1 - q2) / (p1 - p2)) + q1;
        }
        
        printf("POINT %.2f %.2f\n", x, y);
    }
    else {
        // 방향 같음 : 평행 or 일치 직선 
        
        // 일치 직선
        // (x3, y3), (x1, y1) 사이의 직선의 방향 벡터랑 기존 방향 벡터랑 방향 일치
        pair<double, double> c = {x3 - x1, y3 - y1};
        if(a.first * c.second - a.second * c.first == 0) {
            printf("LINE\n");
        }
        else{
            printf("NONE\n");
        }
    }
}

int main()
{
    cin >> N;
    while(N--){
        init();
        calc();
    }
}

'알고리즘 > 백준' 카테고리의 다른 글

백준 10165 버스 노선  (0) 2022.08.16
백준 5582 공통 부분 문자열 C++  (0) 2022.08.12
백준 17779 게리멘더링 2 C++  (0) 2022.07.10
백준 16953 A -> B C++  (0) 2022.07.01
백준 11000 강의실 배정 C++  (0) 2022.06.02
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함