제이, 40 39 34 바이트
3 :'(o.1)<(>./-<./)12 o.y*+{.y'@:-
익명 이항 함수는 점, 복용 P를 인수 중 하나와 지점의 목록으로, P (그것은 중요하지 어느 것이 어느 인수 않습니다) 다른 인수로, 그리고 반환 0
하거나 1
, 경우 p는 외부 또는 P 의 볼록 껍질 내부 . 점 p 및 점 P 는 복소수로 간주됩니다.
예
is_inside =: 3 :'(o.1)<(>./-<./)12 o.y*+{.y'@:-
0.5j0.5 is_inside 0j0 0j1 1j0 1j1
1
1.5j0.5 is_inside 0j0 0j1 1j0 1j1
0
또는...
파이썬 2, 함수, 121 103, 전체 프로그램, 162
파이썬 3, 149 바이트
import sys,cmath as C
p,q,*P=[complex(*eval(l.replace(*";,")))for l in sys.stdin]
A=[C.phase((r-p)/(q-p+(q==p)))for r in P]
print(max(A)-min(A)>C.pi)
STDIN을 통해 원래 게시물과 동일한 형식으로 입력을 받고 p가 P의 볼록 껍질에 있는지 여부를 나타내는 부울 값을 인쇄합니다.
설명
최대 및 최소 (부호)의 차이가 임의의 점 사이의 각도 여부 프로그램 시험 연구 에서 P , P , 및 고정 된 임의의 점 Q 에서 P는 (우리는 단지 최초의 지점 사용 P를 , ° 미만 180 초과). 즉, P의 모든 점이 p 주위의 180 ° 이하의 각도에 포함되어 있는지 테스트합니다 .
이 조건이 거짓 인 경우에만 p 는 P 의 볼록 껍질에 있습니다.
몇 바이트를 더 희생시키면서, 명시 적으로 각도를 계산할 필요가없는 비슷한 방법을 사용할 수 있습니다 : 위의 조건은 p 가 존재하는 경우에만 p 가 P 의 볼록 껍질 밖에 있다고 말하는 것과 같습니다. P의 모든 점이 l 의 같은쪽에 있도록 l ~ p 선 . 이러한 라인이 존재하는 경우, 사건의 포인트 중 하나 (또는 그 이상)하는 것입니다 같은 라인도있다 P (는 우리가 할 수있는 회전 리터 가의 포인트 중 하나에 닿을 때까지 P .)
(가칭 적으로)이 선을 찾으려면 l을 통해 p 와 P 의 첫 번째 점이되도록 합니다. 그런 다음 P 의 나머지 부분을 반복합니다 . 점들 중 하나가 l 의 왼쪽에 있다면 (우리는 전체적으로 약간의 방향성을 가정하고, 왼쪽이나 오른쪽은 실제로 중요하지 않다고 가정합니다) l 을 p 와 그 점을 통과하는 선으로 바꾸고 계속합니다. 우리는 모든 반복 처리 후 P를 , 경우 (단 경우) (P)는 다음의 모든 포인트 볼록 선체 외부에 P가 (또는 페이지)의 오른쪽에 있어야 L . 우리는 P 의 포인트를 두 번째 패스로 사용하는지 확인합니다..
파이썬 2, 172 바이트
import sys
P=[eval(l.replace(*";,"))for l in sys.stdin]
x,y=P.pop(0)
C=lambda(a,b),(c,d):(a-x)*(d-y)-(b-y)*(c-x)>0
l=reduce(lambda*x:x[C(*x)],P)
print any(C(l,q)for q in P)
또한,하자, 단일 패스에서 같은 일을하는 투 - 왼쪽의 두 점 사이의 realtion 수 Q 와 R 에서, P 있도록, q는 의 왼쪽에 R 경우 q는 왼쪽에 통과하는 라인 (P) 및 R . 투 - 좌측의 상 순서 관계 참고 P는 경우 및 모든 지점에만 P를 통과하는 어떤 행의 동일 측에있는 P 경우이고, p는 의 볼록 선체 외부에 P . 위에서 설명한 절차는 P 에서 최소 점을 찾습니다.이 순서, 즉 P 의 "가장 왼쪽"점 . 대신 두 개의 패스를 수행하는, 우리는에서 포인트 최대 (즉, "오른쪽"점)뿐만 아니라, 최소를 찾을 수 있습니다 P는 단일 패스에서 같은 순서를 WRT, 최소이 (가) 왼쪽에 있는지 확인 가장 왼쪽, 즉 왼쪽은 전 이적입니다.
p 가 P 의 볼록 껍질 바깥에 있으면 잘 작동합니다.이 경우 왼쪽에서 실제로는 주문 관계이지만 p 가 볼록 껍질 안에 있으면 깨질 수 있습니다 (예를 들어, P 의 점이 시계 반대 방향으로 실행되는 정 오각형의 정점이고 p 가 중심 인 위치에서이 알고리즘을 실행하면 발생합니다 .) 수용하기 위해 알고리즘을 약간 변경합니다 .P 에서 점 q 를 선택 하고 이등분합니다. p 와 q를 통과하는 선을 따라 P (즉, 우리는 P 를 q 주위로 분할합니다.wrt to-the-left-of.) 이제 우리는 P 의 "왼쪽 부분"과 "오른쪽 부분"을 가지고 있으며 , 각각은 하프 플레인에 포함되어 있기 때문에 왼쪽부터 왼쪽은 각각의 순서 관계입니다. 왼쪽 부분의 최소값과 오른쪽 부분의 최대 값을 찾아 위에서 설명한대로 비교합니다. 물론, 우리는 P 를 물리적으로 양분 할 필요가 없으며 , 단일 패스에서 최소 및 최대를 찾을 때 P의 각 점을 간단히 분류 할 수 있습니다 .
파이썬 2, 194 바이트
import sys
P=[eval(l.replace(*";,"))for l in sys.stdin]
x,y=P.pop(0)
C=lambda(a,b),(c,d):(a-x)*(d-y)-(b-y)*(c-x)>0
l=r=P[0]
for q in P:
if C(P[0],q):l=q*C(l,q)or l
elif C(q,r):r=q
print C(l,r)