Khu vực kết hợp của các vòng tròn chồng chéo


107

Gần đây tôi đã gặp phải một vấn đề trong đó tôi có bốn hình tròn (trung điểm và bán kính) và phải tính diện tích hợp của những hình tròn này.

Hình ảnh ví dụ:

Đối với hai vòng kết nối, nó khá dễ dàng,

Tôi chỉ có thể tính phần diện tích từng hình tròn không nằm trong hình tam giác và sau đó tính diện tích hình tam giác.

Nhưng có một thuật toán thông minh nào tôi có thể sử dụng khi có nhiều hơn hai vòng tròn không?


15
Đây là một vấn đề thực sự thú vị, tôi nhớ đã thấy nó trong lớp hình học trung học, nhưng không bao giờ tìm ra lời giải. Nếu bạn không thể tìm thấy câu trả lời ở đây, hãy thử đăng nó ở mathoverflow.net và để cho các nhà toán học có một vết nứt ở đó: P
Charles Ma

25
đôi khi các lập trình viên thực sự cần toán học thực sự
fa.

1
Làm thế nào để tìm ra câu trả lời cho câu hỏi này - "Chúng tôi có các đại diện bán hàng sống tại 4 địa điểm này, mỗi người phục vụ một khu vực với 4 bán kính này. Chúng tôi bao phủ bao nhiêu phần trăm đất nước?" Nếu bạn có một cơ sở dữ liệu thay đổi về các đại diện bán hàng, đây sẽ trở thành một câu hỏi lập trình!
Chris Roberts

5
Trên thực tế, đây là loại vấn đề mà các lập trình viên thực sự thích nghĩ đến.
MAK

2
@zvolkov: bảng mạch được mô tả bằng ngôn ngữ ghép hình vuông và hình tròn xuống và tùy chọn kéo chúng. "Tính diện tích đồng". (Điều này có thể cần thiết để tính toán thời gian khắc, biết có nên thêm tác phẩm nghệ thuật nhặt rác hay không, nhiều thứ khác nhau.)
DigitalRoss

Câu trả lời:


97

Tìm tất cả các giao điểm của đường tròn ngoại tiếp chu vi (ví dụ B, D, F, H trên sơ đồ sau). Nối chúng với nhau với tâm của các vòng tròn tương ứng để tạo thành một đa giác. Diện tích hợp của các đường tròn là diện tích của đa giác + diện tích của các lát tròn được xác định bởi các giao điểm liên tiếp và tâm đường tròn ở giữa chúng. Bạn cũng cần tính đến bất kỳ lỗ hổng nào.

chồng chéo vòng tròn


17
Điều gì xảy ra khi có một lỗ ở tâm?
John Gietzen

3
Bạn sẽ cần phải trừ đi đa giác được nối ở tâm cho lỗ từ tổng số và thêm các lát tròn cho đa giác đó vào tổng số.
Ants Aasma

3
hay nhưng tôi đoán điều này sẽ cần rất nhiều chi tiết thực hiện để xử lý tất cả các trường hợp đặc biệt (vòng tròn bên trong cái khác, không có giao điểm, lỗ, tiếp điểm một điểm ...)
fa.

1
Các trường hợp đặc biệt là khá dễ dàng. Các vòng kết nối bên trong các vòng kết nối khác bị loại bỏ do không có bất kỳ giao lộ ngoại vi nào. Một tiếp điểm có hiệu là hai giao điểm với khoảng cách bằng không. Các hình dạng bị ngắt kết nối có thể được tìm thấy thông qua thuật toán các thành phần được kết nối trên biểu đồ nơi hai vòng tròn được kết nối nếu khoảng cách giữa các tâm nhỏ hơn tổng bán kính. Các lỗ đều là đa giác ngoại trừ lỗ có diện tích lớn nhất. Các giao lộ theo chu vi là tất cả các giao lộ không nằm trong bất kỳ vòng tròn nào.
Ants Aasma

4
có, nhưng đường viền của các lỗ cũng là vòng cung (nhỏ). Tôi vẫn nghĩ rằng điều này cần rất nhiều mã để hoạt động tốt.
fa.

32

Tôi chắc rằng có một thuật toán thông minh, nhưng đây là một thuật toán ngu ngốc để tiết kiệm khi phải tìm kiếm nó;

  • đặt một hộp giới hạn xung quanh các vòng tròn;
  • tạo điểm ngẫu nhiên trong hộp giới hạn;
  • tìm xem liệu điểm ngẫu nhiên có nằm bên trong một trong các vòng tròn hay không;
  • tính toán diện tích bằng một số phép cộng và chia đơn giản (ratio_of_points_inside * area_of_bounds_box).

Chắc chắn là nó ngớ ngẩn, nhưng:

  • bạn có thể nhận được câu trả lời chính xác như bạn muốn, chỉ cần tạo thêm điểm;
  • nó sẽ hoạt động cho bất kỳ hình dạng nào mà bạn có thể tính toán sự khác biệt bên trong / bên ngoài;
  • nó sẽ song song đẹp mắt để bạn có thể sử dụng tất cả các lõi của mình.

2
Điều này sẽ hiệu quả, nhưng các phương pháp Monte-Carlo như phương pháp này, chỉ đơn giản dựa trên việc lấy mẫu đồng nhất, thường không có tốc độ hội tụ tốt nhất.
ShreevatsaR

2
Xin lỗi, mặc dù tôi đánh giá cao nỗ lực của bạn và cho rằng giải pháp của bạn là "thực tế có thể sử dụng được", tôi cho rằng cách tiếp cận của bạn là rất sai lầm. Đây là một vấn đề hơn có thể và nên được giải quyết bằng toán học, không phải là vũ phu. Lãng phí năng lượng và tập trung vào những vấn đề như thế này là lãng phí và xa hoa.
mafu

5
Bạn nói đúng, tôi xấu hổ về bản thân mình, nhưng tôi có một cụm với 12.000 lõi, tôi có thể đủ khả năng để trở nên xa hoa. Và tôi không thể tìm ra cách tạo ra giải pháp toán học thanh lịch cho nhiều bộ xử lý như vậy.
hiệu suất cao

8
Vốn dĩ không có gì sai với phương pháp Monte-Carlo (hoặc bất kỳ phương pháp ngẫu nhiên nào), miễn là nó cung cấp mức độ chính xác cần thiết và làm như vậy trong một khoảng thời gian hợp lý.
MAK

@mafutrct, bạn chắc chắn đúng. Tuy nhiên, bạn rất dễ mắc phải những sai lầm nhỏ trong toán học. Giải pháp này cung cấp một cách đơn giản để kiểm tra tính đúng đắn.
Richard

18

Câu trả lời của Ants Aasma đã đưa ra ý tưởng cơ bản, nhưng tôi muốn làm cho nó cụ thể hơn một chút. Hãy xem năm vòng tròn dưới đây và cách chúng được phân hủy.

Thí dụ

  • Các chấm màu xanh là tâm hình tròn.
  • Các chấm đỏ là giao điểm ranh giới vòng tròn.
  • Các chấm màu đỏ với bên trong màu trắng là các giao điểm ranh giới vòng tròn không nằm trong bất kỳ vòng tròn nào khác .

Việc xác định 3 loại chấm này rất dễ dàng. Bây giờ, hãy xây dựng một cấu trúc dữ liệu đồ thị trong đó các nút là các chấm màu xanh và các chấm màu đỏ với bên trong là màu trắng. Đối với mọi hình tròn, đặt một cạnh giữa hình tròn ở giữa (chấm xanh lam) và mỗi giao điểm của nó (chấm đỏ với bên trong trắng) trên ranh giới của nó.

Điều này phân tách liên kết vòng tròn thành một tập hợp các đa giác (màu xanh lam bóng mờ) và các miếng bánh hình tròn (màu xanh lá cây tô bóng mờ) tách rời từng cặp và che phủ liên kết ban đầu (nghĩa là một phân vùng). Vì mỗi mảnh ở đây là một thứ dễ dàng để tính diện tích, bạn có thể tính diện tích của liên hiệp bằng cách tính tổng diện tích của các mảnh.


Tôi nghĩ rằng tôi có thể tính toán một tập hợp các chấm đỏ / trắng khá dễ dàng tuy nhiên lý thuyết đồ thị của tôi không quá tuyệt vời: về mặt thuật toán, làm cách nào để bạn chuyển từ danh sách các nút + cạnh đến một vùng được tính toán?
user999305

1
Thuật toán có thể được đơn giản hóa bằng cách sử dụng một tập hợp các tam giác không chồng lên nhau thay vì các đa giác. Các vòng cung (vùng màu xanh lá cây) là các vùng chỉ chứa trong một vòng tròn. Mở rộng kích thước của đa giác khi bạn thêm nhiều vòng tròn hơn. (cuối cùng bạn có thể quên rằng bạn thậm chí đang nói về đa giác). Nó làm cho các thuộc tính boolean và các khu vực cũng dễ dàng hơn để tính toán. Khi một chấm đỏ rỗng trở thành một chấm đỏ đặc, bạn chỉ cần thêm nhiều hình tam giác hơn vào tập hợp của mình và bạn điều chỉnh vòng cung nó bị "ăn mất" bởi ngày càng nhiều vòng tròn giao nhau.
Steve

16

Đối với một giải pháp khác với giải pháp trước đó, bạn có thể tạo ra một ước tính với độ chính xác tùy ý bằng cách sử dụng quadtree.

Điều này cũng hoạt động đối với bất kỳ kết hợp hình dạng nào nếu bạn có thể biết được hình vuông nằm bên trong hay bên ngoài hoặc giao với hình dạng.

Mỗi ô có một trong các trạng thái: trống, đầy, một phần

Thuật toán bao gồm "vẽ" các vòng tròn trong quadtree bắt đầu với độ phân giải thấp (ví dụ 4 ô được đánh dấu là trống). Mỗi ô là:

  • bên trong ít nhất một vòng tròn, sau đó đánh dấu ô là đầy đủ,
  • bên ngoài tất cả các vòng kết nối, đánh dấu ô là trống,
  • khác đánh dấu ô là một phần.

Khi hoàn tất, bạn có thể tính toán ước tính diện tích: các ô đầy đủ cho giới hạn dưới, các ô trống cho giới hạn cao hơn, các ô riêng phần cho lỗi diện tích tối đa.

Nếu lỗi quá lớn đối với bạn, bạn sẽ tinh chỉnh từng ô cho đến khi có được độ chính xác phù hợp.

Tôi nghĩ điều này sẽ dễ thực hiện hơn phương pháp hình học có thể yêu cầu xử lý rất nhiều trường hợp đặc biệt.


3
Tôi đoán rằng điều này sẽ hội tụ nhanh hơn thuật toán điểm bên trong / bên ngoài monte carlo.
Frank Krueger

Điều này dường như dễ thực hiện hơn rất nhiều. Chắc chắn là phương pháp vũ phu tốt nhất được đề xuất. Cảm ơn!
Anton Hansson

lực vũ phu ở đây được gọi là định lý ép
fa.

Đó là loại thuật toán bạn sử dụng trong số học khoảng. en.wikipedia.org/wiki/Interval_arithmetic
rjmunro

13

Tôi thích cách tiếp cận đối với trường hợp 2 vòng tròn giao nhau - đây là cách tôi sử dụng một biến thể nhỏ của cùng một cách tiếp cận cho ví dụ phức tạp hơn.

Nó có thể cung cấp cái nhìn sâu sắc hơn về việc tổng quát thuật toán cho số lượng lớn hơn các vòng tròn bán chồng chéo.

Sự khác biệt ở đây là tôi bắt đầu bằng cách liên kết các trung tâm (vì vậy có một điểm giữa tâm của các vòng tròn, thay vì giữa những nơi mà các vòng tròn giao nhau) Tôi nghĩ điều này cho phép nó khái quát tốt hơn.

(trong thực tế, có thể phương pháp monte-carlo là đáng giá)

văn bản thay thế
(nguồn: secretGeek.net )


1
Tôi nghĩ rằng thực hiện kiểu phân chia đa giác được đề xuất bởi hình ảnh của bạn có lẽ sẽ là một cách tiếp cận rất tốt. Có rất nhiều chi tiết cần tìm ra để viết mã. Làm thế nào nó sẽ xử lý một chuỗi hai mươi vòng tròn, mỗi vòng chỉ chồng lên nhau cuối cùng và tiếp theo trong chuỗi? Dễ dàng tìm ra bằng tay, nhưng thuật toán của bạn là gì?
PeterAllenWebb

4

Nếu bạn muốn có một câu trả lời rời rạc (trái ngược với một câu trả lời liên tục), bạn có thể làm điều gì đó tương tự như thuật toán vẽ pixel.

Vẽ các vòng tròn trên lưới, sau đó tô màu cho từng ô của lưới nếu ô đó chủ yếu nằm trong một vòng tròn (tức là, ít nhất 50% diện tích của nó nằm bên trong một trong các vòng tròn). Làm điều này cho toàn bộ lưới (trong đó lưới kéo dài tất cả diện tích được bao phủ bởi các vòng tròn), sau đó đếm số ô màu trong lưới.


3

Hmm, vấn đề rất thú vị. Cách tiếp cận của tôi có thể sẽ là một cái gì đó dọc theo các dòng sau:

  • Tìm ra cách tính diện tích giao nhau giữa một số hình tròn tùy ý là gì, tức là nếu tôi có 3 hình tròn, tôi cần tìm ra giao điểm giữa các hình tròn đó là gì. Phương pháp "Monte-Carlo" sẽ là một cách tốt để ước lượng điều này ( http://local.wasp.uwa.edu.au/~pbourke/geometry/circlearea/ ).
  • Loại bỏ bất kỳ vòng tròn nào được chứa hoàn toàn trong một vòng tròn khác lớn hơn (nhìn vào bán kính và môđun của khoảng cách giữa tâm của hai vòng tròn) Tôi không nghĩ là bắt buộc.
  • Chọn 2 hình tròn (gọi chúng là A và B) và tính tổng diện tích bằng công thức sau:

(điều này đúng với bất kỳ hình dạng nào, có thể là hình tròn hoặc hình dạng khác)

area(A∪B) = area(A) + area(B) - area(A∩B)

Ở đâu A ∪ Bcó nghĩa là A kết hợp B và A ∩ Bcó nghĩa là A giao nhau B (bạn có thể giải quyết điều này từ bước đầu tiên.

  • Bây giờ tiếp tục thêm các vòng tròn và tiếp tục tính diện tích được thêm vào dưới dạng tổng / trừ các diện tích của các vòng tròn và các khu vực giao nhau giữa các vòng tròn. Ví dụ đối với 3 hình tròn (gọi là vòng tròn phụ C), chúng tôi tính diện tích bằng công thức sau:

(Điều này giống như ở trên, nơi Ađã được thay thế bằng A∪B)

area((A∪B)∪C) = area(A∪B) + area(C) - area((A∪B)∩C)

Nơi area(A∪B)chúng tôi vừa làm việc và area((A∪B)∩C)có thể tìm thấy:

area((A∪B)nC) = area((A∩C)∪(B∩C)) = area(A∩C) + area(A∩B) - area((A∩C)∩(B∩C)) = area(A∩C) + area(A∩B) - area(A∩B∩C)

Nơi bạn có thể tìm thấy khu vực (A∩B∩C) từ phía trên.

Một chút khó khăn là bước cuối cùng - càng nhiều vòng tròn được thêm vào thì nó càng trở nên phức tạp hơn. Tôi tin rằng có một sự mở rộng để tính ra khu vực giao nhau với một liên hợp hữu hạn, hoặc cách khác, bạn có thể tính toán nó một cách đệ quy.

Ngoài ra, liên quan đến việc sử dụng Monte-Carlo để tính gần đúng diện tích của phần nghiêng, tôi tin rằng có thể giảm giao điểm của một số hình tròn tùy ý thành giao điểm của 4 trong số các hình tròn đó, điều này có thể được tính toán chính xác (không biết làm thế nào để làm điều này Tuy nhiên).

Có lẽ có một cách tốt hơn để làm điều này btw - độ phức tạp tăng lên đáng kể (có thể theo cấp số nhân, nhưng tôi không chắc chắn) cho mỗi vòng kết nối bổ sung được thêm vào.


Có vấn đề gì với định dạng? Cũng xin lỗi về việc sử dụng n và u cho ngã tư và công đoàn, có lẽ là một cách tốt hơn ...
Justin

1
đã thêm một số dấu hiệu liên hợp unicode (∪) và giao nhau (∩). hy vọng chúng hoạt động.
Spoike

3

Tôi đang nghiên cứu vấn đề mô phỏng các trường sao chồng lên nhau, cố gắng ước tính số lượng sao thực từ các vùng đĩa thực tế trong các trường dày đặc, nơi các ngôi sao sáng lớn hơn có thể che khuất những ngôi sao mờ hơn. Tôi cũng đã hy vọng có thể làm điều này bằng cách phân tích chính thức chặt chẽ, nhưng không thể tìm ra một thuật toán cho nhiệm vụ. Tôi đã giải quyết nó bằng cách tạo các trường sao trên nền xanh lam dưới dạng các đĩa màu xanh lá cây, có đường kính được xác định bằng một thuật toán xác suất. Một thói quen đơn giản có thể ghép nối chúng để xem có sự trùng lặp không (chuyển cặp ngôi sao thành màu vàng); sau đó số lượng pixel của các màu tạo ra vùng quan sát được để so sánh với vùng lý thuyết. Sau đó, điều này tạo ra một đường cong xác suất cho các số đếm thực sự. Có thể bạo lực, nhưng nó có vẻ hoạt động tốt. (nguồn: 2from.com )


2

Đây là một thuật toán dễ triển khai trong thực tế và có thể được điều chỉnh để tạo ra lỗi nhỏ tùy ý:

  1. Tính gần đúng mỗi vòng tròn bằng một đa giác đều có tâm ở cùng một điểm
  2. Tính đa giác là hợp của các đường tròn gần đúng
  3. Tính diện tích của đa giác đã hợp nhất

Bước 2 và 3 có thể được thực hiện bằng cách sử dụng các thuật toán chuẩn, dễ tìm từ hình học tính toán.

Rõ ràng, bạn càng sử dụng nhiều cạnh cho mỗi đa giác gần đúng, thì câu trả lời của bạn càng gần chính xác hơn. Bạn có thể tính gần đúng bằng cách sử dụng các đa giác nội tiếp và ngoại tiếp để có được giới hạn cho câu trả lời chính xác.


2

Có những giải pháp hiệu quả cho vấn đề này bằng cách sử dụng những gì được gọi là sơ đồ nguồn. Đây thực sự là một môn toán nặng và không phải là thứ mà tôi muốn giải quyết. Để có giải pháp "dễ dàng", hãy tra cứu các thuật toán quét dòng. Nguyên tắc cơ bản ở đây là bạn chia hình thành các dải, trong đó việc tính toán diện tích trên mỗi dải là tương đối dễ dàng.

Vì vậy, trên hình có chứa tất cả các hình tròn mà không có gì bị cọ xát, hãy vẽ một đường ngang tại mỗi vị trí là đỉnh của hình tròn, đáy của hình tròn hoặc giao điểm của 2 hình tròn. Lưu ý rằng bên trong các dải này, tất cả các khu vực bạn cần tính toán trông giống nhau: một "hình thang" với hai cạnh được thay thế bằng các đoạn tròn. Vì vậy, nếu bạn có thể tìm ra cách tính một hình dạng như vậy, bạn chỉ cần thực hiện nó cho tất cả các hình dạng riêng lẻ và cộng chúng lại với nhau. Độ phức tạp của phương pháp đơn giản này là O (N ^ 3), trong đó N là số hình tròn trong hình. Với một số cách sử dụng cấu trúc dữ liệu thông minh, bạn có thể cải thiện phương pháp quét dòng này thành O (N ^ 2 * log (N)), nhưng trừ khi bạn thực sự cần, nó có lẽ không đáng để gặp rắc rối.



1

Tùy thuộc vào vấn đề bạn đang cố gắng giải quyết, nó có thể đủ để có được giới hạn trên và dưới. Giới hạn trên rất dễ dàng, chỉ là tổng của tất cả các vòng tròn. Đối với giới hạn dưới, bạn có thể chọn một bán kính sao cho không có vòng tròn nào chồng lên nhau. Để tốt hơn, hãy tìm bán kính lớn nhất (tính đến bán kính thực tế) cho mỗi vòng tròn để nó không chồng lên nhau. Cũng khá đơn giản nếu loại bỏ bất kỳ vòng tròn nào bị trùng lặp hoàn toàn (Tất cả các vòng tròn như vậy đều thỏa mãn | P_a - P_b | <= r_a) trong đó P_a là tâm của hình tròn A, P_b là tâm của hình tròn B và r_a là bán kính của A ) và điều này tốt hơn cả giới hạn trên và giới hạn dưới. Bạn cũng có thể nhận được Giới hạn trên tốt hơn nếu bạn sử dụng công thức cặp của mình trên các cặp tùy ý thay vì chỉ tổng của tất cả các vòng tròn. Có thể có một cách tốt để chọn "tốt nhất"

Với giới hạn trên và dưới, bạn có thể điều chỉnh tốt hơn cách tiếp cận Monte-carlo, nhưng không có gì cụ thể xuất hiện trong tâm trí. Một tùy chọn khác (một lần nữa tùy thuộc vào ứng dụng của bạn) là sắp xếp các vòng tròn và đếm pixel. Về cơ bản nó là cách tiếp cận Monte-carlo với một phân phối cố định.


0

Điều này có thể được giải quyết bằng cách sử dụng Định lý Green , với độ phức tạp là n ^ 2log (n). Nếu bạn không quen thuộc với Định lý Green và muốn biết thêm, đây là videoghi chú từ Học viện Khan. Nhưng vì lợi ích của vấn đề của chúng tôi, tôi nghĩ rằng mô tả của tôi sẽ đủ.

Xin lỗi vì các liên kết đến ảnh, vì tôi không thể đăng ảnh. (Không đủ điểm danh tiếng)

Phương trình tổng quát của Định lý Green

Nếu tôi đặt LM sao cho

Tình trạng

thì RHS chỉ đơn giản là diện tích của Vùng R và có thể thu được bằng cách giải tích phân đóng hoặc LHS và đây chính xác là những gì chúng ta sẽ làm.

Tất cả các hợp nhất có thể được chia thành các tập hợp các vòng tròn rời rạc giao nhau

Vì vậy, Tích phân dọc theo con đường theo chiều ngược chiều kim đồng hồ cho chúng ta Diện tích của vùng và tích phân dọc theo chiều kim đồng hồ cho chúng ta âm của Vùng . Vì thế

AreaOfUnion = (Tích hợp dọc theo vòng cung màu đỏ theo hướng ngược chiều kim đồng hồ + Tích hợp dọc theo vòng cung màu xanh theo chiều kim đồng hồ)

Nhưng mẹo hay là đối với mỗi vòng tròn nếu chúng ta tích hợp các cung không nằm bên trong bất kỳ vòng tròn nào khác, chúng ta nhận được diện tích cần thiết của mình tức là chúng ta nhận được tích hợp theo hướng ngược chiều kim đồng hồ dọc theo tất cả các cung màu đỏ và tích hợp dọc theo tất cả các cung xanh dọc theo chiều kim đồng hồ. CÔNG VIỆC HOÀN THÀNH!!!

Ngay cả những trường hợp khi một vòng tròn không giao với bất kỳ đường tròn nào khác cũng được quan tâm.

Đây là liên kết GitHub tới Mã C ++ của tôi


-1

Phương pháp vẽ pixel (theo đề xuất của @Loadmaster) vượt trội hơn so với giải pháp toán học theo nhiều cách:

  1. Thực hiện đơn giản hơn nhiều . Vấn đề trên có thể được giải quyết trong ít hơn 100 dòng mã, như giải pháp JSFiddle này thể hiện (chủ yếu là vì nó đơn giản hơn nhiều về mặt khái niệm và không có trường hợp cạnh hoặc ngoại lệ nào để giải quyết).
  2. Nó dễ dàng thích ứng với các vấn đề chung hơn. Nó hoạt động với bất kỳ hình dạng nào, bất kể hình thái, miễn là nó có thể kết xuất được với thư viện bản vẽ 2D (tức là, “tất cả chúng!”) - hình tròn, hình elip, hình splines, đa giác, bạn đặt tên cho nó. Heck, ngay cả hình ảnh bitmap.
  3. Độ phức tạp của giải pháp vẽ pixel là ~ O [n], so với ~ O [n * n] đối với giải pháp toán học. Điều này có nghĩa là nó sẽ hoạt động tốt hơn khi số lượng hình dạng tăng lên.
  4. Và nói về hiệu suất, bạn sẽ thường được tăng tốc phần cứng miễn phí, vì hầu hết các thư viện 2D hiện đại (như canvas của HTML5, tôi tin rằng) sẽ giảm tải công việc kết xuất cho các trình tăng tốc đồ họa.

Một nhược điểm của pixel-painting là độ chính xác hữu hạn của giải pháp. Nhưng điều đó có thể điều chỉnh được bằng cách chỉ cần kết xuất với các bức tranh lớn hơn hoặc nhỏ hơn khi tình hình yêu cầu. Cũng xin lưu ý rằng tính năng khử răng cưa trong mã kết xuất 2D (thường được bật theo mặc định) sẽ mang lại độ chính xác cấp độ pixel tốt hơn. Vì vậy, ví dụ: hiển thị một hình 100x100 vào một canvas có cùng kích thước, theo tôi, sẽ mang lại độ chính xác theo thứ tự 1 / (100 x 100 x 255) = .000039% ... có lẽ là "đủ tốt" cho tất cả trừ những vấn đề khắt khe nhất.

<p>Area computation of arbitrary figures as done thru pixel-painting, in which a complex shape is drawn into an HTML5 canvas and the area determined by comparing the number of white pixels found in the resulting bitmap.  See javascript source for details.</p>

<canvas id="canvas" width="80" height="100"></canvas>

<p>Area = <span id="result"></span></p>
// Get HTML canvas element (and context) to draw into
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

// Lil' circle drawing utility
function circle(x,y,r) {
  ctx.beginPath();
  ctx.arc(x, y, r, 0, Math.PI*2);
  ctx.fill();
}

// Clear canvas (to black)
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Fill shape (in white)
ctx.fillStyle = 'white';
circle(40, 50, 40);
circle(40, 10, 10);
circle(25, 15, 12);
circle(35, 90, 10);

// Get bitmap data
var id = ctx.getImageData(0, 0, canvas.width, canvas.height);
var pixels = id.data; // Flat array of RGBA bytes

// Determine area by counting the white pixels
for (var i = 0, area = 0; i < pixels.length; i += 4) {
  area += pixels[i]; // Red channel (same as green and blue channels)
}

// Normalize by the max white value of 255
area /= 255;

// Output result
document.getElementById('result').innerHTML = area.toFixed(2);

Giải pháp này không tính đến việc thực hiện các phép tính toán học với diện tích của các vòng tròn. Nó bỏ sót điểm của câu hỏi OP. Thường thì hình học kết xuất chỉ là một nửa trận chiến khi xử lý các hình dạng hình học
Steve
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.