J, 40 39 34 byte
3 :'(o.1)<(>./-<./)12 o.y*+{.y'@:-
Hàm dyadic ẩn danh, lấy một điểm, p , làm một trong các đối số của nó và một danh sách các điểm, P , làm đối số khác (không quan trọng đó là đối số nào) và trả về 0
hoặc 1
, nếu p ở bên ngoài hoặc bên trong thân lồi của P , tương ứng. Điểm p và các điểm trong P , được lấy dưới dạng số phức.
Thí dụ
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
hoặc là...
Python 2, hàm, 121 103, chương trình đầy đủ, 162
Python 3, 149 byte
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)
Đưa đầu vào, có cùng định dạng với bài đăng gốc, thông qua STDIN và in một giá trị boolean cho biết liệu p có nằm trong vỏ lồi của P không
Giải trình
Chương trình kiểm tra xem chênh lệch giữa góc tối đa và tối thiểu (đã ký) giữa bất kỳ điểm r nào trong P , p và điểm q tùy ý cố định trong P (chúng tôi chỉ sử dụng điểm đầu tiên trong P ), có nhỏ hơn 180 °. Nói cách khác, nó kiểm tra xem tất cả các điểm trong P có được chứa trong một góc 180 ° hoặc ít hơn, xung quanh p .
p nằm trong vỏ lồi của P khi và chỉ khi điều kiện này là sai.
Với chi phí thêm một vài byte, chúng ta có thể sử dụng một phương pháp tương tự không yêu cầu chúng ta tính toán rõ ràng các góc: Lưu ý rằng điều kiện trên tương đương với việc nói rằng p nằm ngoài vỏ lồi của P khi và chỉ khi tồn tại một đường thẳng từ l đến p , sao cho tất cả các điểm trong P nằm cùng phía với l . Nếu một dòng như vậy tồn tại, thì cũng có một dòng như vậy xảy ra với một (hoặc nhiều) điểm trong P (chúng ta có thể xoay l cho đến khi chạm vào một trong các điểm trong P. )
Để (ngập ngừng) tìm dòng này, chúng tôi bắt đầu bằng cách cho phép l là dòng qua p và điểm đầu tiên trong P . Sau đó chúng tôi lặp lại các điểm còn lại trong P ; nếu một trong những điểm nằm ở bên trái của l (chúng ta giả sử một số hướng trong suốt, bên trái hoặc bên phải không thực sự quan trọng), chúng ta thay thế l bằng dòng đi qua p và điểm đó, và tiếp tục. Sau khi chúng tôi lặp lại trên tất cả P , nếu (và chỉ khi) p nằm ngoài thân lồi, thì tất cả các điểm trong P phải ở bên phải của (hoặc trên) l . Chúng tôi kiểm tra xem bằng cách sử dụng lần thứ hai qua các điểm trong P.
Python 2, 172 byte
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)
Ngoài ra, để thực hiện điều tương tự trong một lần chạy, hãy đặt bên trái là một cảnh giới giữa hai điểm bất kỳ, q và r , trong P , sao cho q nằm bên trái của r nếu q ở bên trái của dòng đi qua p và r . Lưu ý rằng to-the-left-of là một mối quan hệ thứ tự trên P khi và chỉ khi tất cả các điểm trong P đang ở trên cùng một phía của một số dòng đi qua p , có nghĩa là, nếu p là bên ngoài thân tàu lồi của P . Quy trình được mô tả ở trên tìm thấy điểm tối thiểu trong PWRT lệnh này, ví dụ, điểm "tận cùng bên trái" tại P . Thay vì thực hiện hai lần chuyền, chúng ta có thể tìm điểm tối đa (nghĩa là điểm "ngoài cùng bên phải"), cũng như mức tối thiểu, các điểm trong P ghi cùng một thứ tự trong một lượt và xác minh rằng mức tối thiểu nằm ở bên trái của tối đa, tức là, một cách hiệu quả, từ bên trái sang phải là bắc cầu.
Điều này sẽ hoạt động tốt nếu p nằm ngoài vỏ lồi của P , trong trường hợp bên trái thực sự là một mối quan hệ trật tự, nhưng có thể bị phá vỡ khi p ở bên trong thân lồi (ví dụ: cố gắng tìm hiểu xem điều gì sẽ xảy ra nếu chúng ta chạy thuật toán này trong đó các điểm trong P là các đỉnh của một hình ngũ giác đều, chạy ngược chiều kim đồng hồ và p là tâm của nó.) Để phù hợp, chúng tôi thay đổi một chút thuật toán: Chúng tôi chọn một điểm q trong P và chia đôi P dọc theo đường đi qua p và q (nghĩa là chúng ta phân vùng P quanh qwrt to-the-left-of.) Bây giờ chúng ta có một "phần bên trái" và "phần bên phải" của P , mỗi phần được chứa trong một nửa mặt phẳng, do đó, bên trái là một mối quan hệ thứ tự trên mỗi; chúng tôi tìm thấy tối thiểu của phần bên trái và tối đa của phần bên phải và so sánh chúng như mô tả ở trên. Tất nhiên, chúng ta không phải chia đôi P về mặt vật lý , chúng ta chỉ có thể phân loại từng điểm trong P khi chúng ta tìm kiếm mức tối thiểu và tối đa, trong một lần duy nhất.
Python 2, 194 byte
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)