Giao điểm của hai hình tam giác


19

Cho 4 điểm trên các mặt phẳng 2D A, B, C, D, tính diện tích của vùng giao nhau của các tam giác OABOCD, Olà tâm của mặt phẳng, có tọa độ (0, 0).

Các thuật toán chạy trong độ phức tạp thời gian không đổi (về các phép toán số học) được khuyến khích, nhưng không bị ép buộc.

Quy tắc

  • Mỗi điểm được biểu diễn dưới dạng hai số thực, biểu thị tọa độ X và Y của chúng.
    • Tùy chọn, nếu ngôn ngữ lập trình của bạn (hoặc một số thư viện ngôn ngữ lập trình của bạn) có Pointloại tích hợp hoặc tương đương, nó được phép lấy Pointđối tượng làm đầu vào.
  • Đầu vào được cho là 4 điểm, trong các định dạng, bao gồm nhưng không giới hạn ở:
    • Một danh sách 8 tọa độ.
    • Một danh sách gồm 4 điểm, mỗi điểm có thể được thể hiện dưới bất kỳ định dạng thuận tiện nào.
    • Hai danh sách 2 điểm.
    • Vân vân.
  • Bạn không thể giả sử thứ tự cụ thể của các điểm (thứ tự ngược chiều kim đồng hồ hoặc thứ tự theo chiều kim đồng hồ)
  • Bạn không thể cho rằng điểm Ođược thông qua là đầu vào. Nói cách khác, chương trình không được lấy và sử dụng đầu vào không liên quan.
  • Bạn không thể cho rằng tất cả các điểm là khác nhau. Nói cách khác, các hình tam giác có thể bị thoái hóa. Bạn cũng cần xử lý trường hợp đó (xem các trường hợp thử nghiệm bên dưới)
  • Sự khác biệt tuyệt đối hoặc tương đối phải nhỏ hơn các trường hợp thử nghiệm mẫu bên dưới.10-3

Tiêu chí chiến thắng

Đây là , câu trả lời ngắn nhất trong byte win!

Các trường hợp thử nghiệm mẫu

Ax Ay Bx By Cx Cy Dx Dy area

5 1 1 3 -1 0 0 -1 0
5 1 1 3 -1 0 0 0 0
5 1 1 3 0 0 0 0 0
5 1 1 3 3 4 4 -3 4.50418
5 1 1 3 1 2 2 1 1.5
5 1 1 3 -2 5 4 -2 1.74829
5 1 1 3 -2 5 5 4 2.96154
5 1 1 3 3 5 5 4 1.88462
5 1 1 3 3 5 3 1 3.92308
5 1 1 3 3 5 4 -1 5.26619
5 1 1 3 5 1 4 -1 0
5 1 1 3 5 1 1 3 7
1 3 1 3 5 1 1 3 0
1 3 1 3 1 3 1 3 0
4 8 4 -1 -2 6 -2 -3 0

1.2 3.4 -0.3 4.2 5 7.6 -1.1 2.4 2.6210759326188535
3.1 0.6 0.1 7.2 5.2 0.7 0.9 8 9.018496993987977

Nếu bất cứ ai muốn, đây là các đầu ra cho nhóm trường hợp thử nghiệm đầu tiên ở dạng chính xác:

0
0
0
46375/10296
3/2
1792/1025
77/26
49/26
51/13
23345/4433
0
7
0
0
0

Hình ảnh minh họa cho trường hợp thử nghiệm 5 1 1 3 3 4 4 -3(diện tích của tứ giác màu xanh lá cây là đầu ra dự kiến):

[ Hình ảnh]


Một trong những trường hợp thử nghiệm của bạn có 9 đầu vào thay vì 8. 1.2 3.4 -0.3 4.2 5 3 7.6 -1.1 2.4 0
Kelly Lowder

1
@KellyLowder Đã sửa.
dùng202729

Câu trả lời:


16

Ngôn ngữ Wolfram (Mathicala) , 55 byte

0&@@Area@BooleanRegion[And,Simplex[{0{,}}~Join~#]&/@#]&

Hãy thử trực tuyến!

Cạo một vài byte khỏi câu trả lời tầm thường.

%@{{{5, 1}, {1, 3}}, {{3, 4}, {4, -3}}} yields 46375/10296 or 4.504176379

Thay thế Areabằng DiscretizeRegionsẽ hiển thị các giao lộ.

nhập mô tả hình ảnh ở đây

Nhân tiện, điều này sẽ làm việc với bất kỳ đơn giản, không chỉ hình tam giác.

-1 Byte nhờ JungHwan Min

Đề xuất của @ user202729 đã thêm 4 byte nhưng làm cho nó mang lại 0 cho các tam giác suy biến


1
Đa giác cũng có thể được thay thế cho Simplex
Kelly Lowder

1
Thêm một byte: {{0,0}}to {0{,}}(điều này hoạt động vì biểu thức ước tính {Times[0, {Null, Null}]})
JungHwan Min

Thất bại cho trường hợp thử nghiệm này , được liệt kê trong các trường hợp thử nghiệm mẫu.
dùng202729

Đã lưu ý rằng điều này KHÔNG hoạt động trên TIO. Không chắc chắn những gì họ có dưới mui xe.
Kelly Lowder

1
Tôi thấy rằng nó không hoạt động cho giao điểm của hai dòng. Xấu của tôi để bỏ qua trường hợp thử nghiệm. Về mặt kỹ thuật đây không phải là hình tam giác. Tôi cho rằng nếu chúng ta sẽ có được kỹ thuật đó, có lẽ bạn nên thay đổi tiêu đề của bài viết cũng như câu đầu tiên. Chúng ta cũng có thể có một cuộc thảo luận thực sự bí truyền về việc liệu khu vực thậm chí có được xác định cho một đối tượng một chiều hay không, nhưng tôi thì không.
Kelly Lowder

5

Python 2 + PIL, 341 318 313 284 270 byte

Đặc biệt cảm ơn Dennis đã nhanh chóng thêm PIL trên TIO
-23 byte nhờ vào ông Xcoder

import PIL.Image as I,PIL.ImageDraw as D
l=[i*1000for i in[0,0]+input()+[0,0]]
z=zip(*[[i-min(t)for i in t]for t in l[::2],l[1::2]])
print sum(map(int.__mul__,*map(lambda i,c:D.Draw(i).polygon(c,1)or i.getdata(),map(I.new,'11',[[max(l)-min(l)]*2]*2),[z[:3],z[3:]])))/1e6

Hãy thử trực tuyến! hoặc Thử tất cả các trường hợp thử nghiệm

Để tính toán sự khác biệt, nghĩa đen là vẽ các hình tam giác và kiểm tra lượng pixel được vẽ trong cả hai hình ảnh.
Phương pháp này chèn một lỗi làm tròn, được làm mềm bằng cách tăng kích thước hình ảnh.

Giải trình

#the image/triangles are enlarged to increase the precision
#a pair of zeros are inserted in the start and at the end, this way "l" will have all 6 points to draw the triangles 
l=[i*1000for i in[0,0]+input()+[0,0]]
#split the input in x and y, where x=l[::2] and y=l[1::2]
#get the smallest number on each list, that will be "0" if there is no negative number, to be used as offset.
#this will be used to overcome the fact that PIL won't draw on negative coords
#zip "x" and "y" lists, to create a list containing the points
z=zip(*[[i-min(t)for i in t]for t in x,y])
#create 2 (B&W) blank images
#where the size is the difference between the smallest and the largest coord.
map(I.new,'11',[[max(l)-min(l)]*2]*2)
#draw both triangles and return the pixel list of each image
map(lambda i,c:D.Draw(i).polygon(c,1)or i.getdata(),<result of previous line>,[z[:3],z[3:]])
#count the amount of overlapping pixels by summing the color of each pixel, if the pixel is "1" in both images, then the triangles are overlapping, then the amount of pixels is divided by the initial enlarging factor squared (1e6)
print sum(map(int.__mul__,*<result of previous line>))/1e6
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.