Skip to content

기하 ( ccw / 선분 교차 / 볼록 껍질 / rotating 캘리퍼스 / Line sweeping / Convex hull trick ) #32

@WonYong-Jang

Description

@WonYong-Jang

ccw

public static int ccw(Point a, Point b, Point c)
{
	long op = ( (a.dx*b.dy)+(b.dx*c.dy)+(c.dx*a.dy) - (a.dy*b.dx) + (b.dy*c.dx)+(c.dy*a.dx) );
	if(op > 0) return 1; // 반시계 방향
	else if(op < 0) return -1; // 시계 방향
	else return 0; // 세점이 평행
}

다각형의 내부 외부 판별

스크린샷 2019-06-29 오후 2 03 24

다각형의 내부 외부 판별 구현

  • 반직선은 항상 x축에 평행한 수평선임을 이용

반직선과 선분 사이에 교점이 존재하기 위한 조건은 2가지


1) 점 B의 y좌표가 두 선분 꼭지점의 y좌표 사이에 있다.
2) 점 B를 지나는 수평선과 선분 사이의 교점의 x좌표가 점 B의 좌표보다 크다.

=> 조건1을 만족하면 점 B를 지나는 수평 직선과 선분사이에 반드시 교점이 존재. 이때 오른쪽
반직선과의 교점만 세야 하므로 조건 2를 추가로 만족해야 반직선과 선분 사이의 교점 존재 여부를
올바르게 판별 가능!

스크린샷 2019-06-29 오후 2 19 02

스크린샷 2019-06-29 오후 2 19 11

public static boolean isCross(long tx, long ty)
{
	int crossCnt = 0;
	long mindy =0, maxdy =0;
	for(int i=0; i< N; i++)
	{
		Point p1 = p[i];
		Point p2 = p[(i+1) % N];
			
		mindy = min(p1.dy, p2.dy);
		maxdy = max(p1.dy, p2.dy);
			
		if(mindy <= ty && maxdy >= ty) // 선분 y 좌표 사이에 있는지 확인 
		{
				 
			long tmp = p2.dy - p1.dy; // 분모가 0 일 경우 제외 
			if(tmp == 0) continue;
			// 점과 직선사이의 수선의 발 좌표 공식
			long target = (ty - p1.dy)*(p2.dx - p1.dx) / (p2.dy - p1.dy) + p1.dx;
				
			if(tx < target) crossCnt++;
		}
	}
	if(crossCnt % 2 != 0) return true;
	else return false;
}

참고 링크 : https://bowbowbow.tistory.com/24

교차 판별

스크린샷 2019-06-15 오후 1 28 19

스크린샷 2019-06-15 오후 1 28 27

스크린샷 2019-06-15 오후 1 28 45

출처 : https://jason9319.tistory.com/358

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions