7개의 댓글이 있습니다.
-
-
Taeyoon_Lee -
딱봐도 절망적인 문제였습니다.ㅋㅋ 이번 모의고사에는 기하문제가 많았네요. C, E, G..
16년 전 link
-
-
-
Being -
이건 유리수 연산만으로 모든 것을 해결하는 방법입니다.
2. 삼각형 A 를 포함하는 평면 P를 구한다. n(normal vector) = vec(A1->A2) cross vec(A1->A3)
d = n \dot A1
=> n \dot p = d 인 평면 완성3. 평면 P 위에 삼각형 B가 지나는 자취를 구한다. (이 자취를 B' 라고 합시다.)
두 점 s와 e를 지나는 직선의 자취 p = s + t(e - s) for real t
평면과 교점: n \dot p = d
n \dot (s + t(e - s)) = d
n \dot s + t n \dot (e - s) = d
t = (d - n \dot s) / (n \dot (e - s))
=> 교점 구하기 끝4. A와 B' 간에 이루는 도형을 구한다.
2D로 변환하기 위해서 orthogonal basis를 새로 잡습니다. (orthonormal말고..)basis_1 = vec(A1 -> A2)
basis_2 = vec(A1 -> A3) - (vec(A1 -> A3) \dot basis_1) / (norm(basis_1)^2) * basis_1 (projection을 잘 생각해보세요. 선형대수학 하면 금방 나오는 부분입니다)
basis_3 = northogonal basis를 모두 구했으니, 점 p를 이 basis로 변환하려면
( p \dot basis_1 / (norm(basis_1)^2) , p \dot basis_2 / (norm(basis_2)^2) , p \dot basis_3 / (norm(basis_3)^2) )
이렇게 해서 z가 상수(d)인 x, y, z를 구했습니다. 그러면 z를 고려하지 않고 x, y 두 변수 위에서(2D) 교차하는지 따지는 것은 polygon clipping을 통해 해결합니다. 즉, 변환된 삼각형 A의 각 변을 따라서 삼각형 B를 잘라내어 새로운 도형을 만듭니다. 이건 2D 직선 교차로 간단하게 해결할 수 있죠. (신경써야 할 부분은 삼각형 B가 항상 'polygon'으로 주어지는 것이 아니라는 것이죠. 어디까지나 평면과 교차하는 부분의 자취 모양을 하고 있으니 직선이거나 점일 수도 있습니다. 그래서 일반적인 polygon-polygon clipping만 해선 위험할 수 있구요)
clipping된 polygon의 꼭지점의 수를 구하면 완성!
0 EMPTY
1 POINT
2 SEGMENT
3~ OTHERS
16년 전 link
-
-
정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.
astein
Solved / AC ratio: 0 ( - % )
Fastest submission : - ( unsolved )
Writer: Astein
결국 도전하신 분들이 아무도 없게 된 버림받은 비운의 문제입니다 :$ 사실 출제하는 입장에서는 알고리즘을 생각하는 것 자체는 쉽기 때문에 그렇게 어렵다고 판단받지 못했던 문제였습니다. 물론 다들 코딩하면서 이러한 판단이 틀렸다고 공감했지만요.
전체적인 접근방법은 아래와 같습니다.
void GetPlane(Point A, Point B, Point C)
{
Point v1 = Point(B.x - A.x, B.y - A.y, B.z - A.z);
Point v2 = Point(C.x - A.x, C.y - A.y, C.z - A.z);
// A x B = (a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1)
Point v3 = Point(v1.y * v2.z - v1.z * v2.y,
v1.z * v2.x - v1.x * v2.z,
v1.x * v2.y - v1.y * v2.x);
a = v3.x, b = v3.y, c = v3.z;
if (a == 0 && b == 0 && c == 0)
{
// not a plane
assert(false);
}
int g = gcd(a, gcd(b, c));
a /= g, b /= g, c /= g;
d = -(a * A.x + b * A.y + c * A.z);
}
3번과정까지 진행했으면 "2차원 평면 위에 삼각형 두 개(또는 삼각형과 점 or 선분)가 있을 때, 이루는 도형이 어떤 형태인지를 구하시오" 문제가 됩니다.
4) 그러면 각각의 케이스에 대해 가능한 경우를 살펴보도록 하지요.
4-1) 삼각형과 점 -> EMPTY, POINT
4-2) 삼각형과 선분 -> EMPTY, POINT, SEGMENT
4-3) 삼각형과 삼각형 -> EMPTY, POINT, SEGMENT, OTHERS (넓이를 가지는 도형)
이 됩니다. 그러면 이제 출력 케이스 별로 어떤 체크를 하면 되는지 살펴볼까요?
16년 전