2009-07-29 25 views
40

Tôi cần tìm một điểm là trung tâm trực quan của một đa giác có hình dạng bất thường. Bởi trung tâm thị giác, tôi có nghĩa là một điểm xuất hiện ở trung tâm của một khu vực rộng lớn của đa giác một cách trực quan. Ứng dụng này là để đặt một nhãn bên trong đa giác.Cách nhanh nhất để tìm trung tâm "trực quan" của một đa giác có hình dạng bất thường là gì?

Dưới đây là một giải pháp sử dụng bên trong đệm:

https://web.archive.org/web/20150708063910/http://proceedings.esri.com/library/userconf/proc01/professional/papers/pap388/p388.htm

Nếu đây là để được sử dụng, một cách hiệu quả và nhanh chóng để tìm ra bộ đệm là gì? Nếu cách nào khác được sử dụng, đó là cách đó?

Một ví dụ tốt về đa giác thực sự khó khăn là một U khổng lồ dày (được viết bằng Arial Black hoặc Impact hoặc một số phông chữ như vậy).

+0

Điều gì nếu tập hợp được xác định bởi đa giác là (rất cao) không lồi (en.wikipedia.org/wiki/Convex_set); được phép có trung tâm bên ngoài đa giác? – Reunanen

+0

Có, nhưng với mục đích ghi nhãn, chúng ta cần tìm một điểm bên trong. –

+0

@Mikhil: để mở rộng nhận xét của @ Pukku, bạn có thể vui lòng đăng một khía cạnh "khó" của vấn đề này, tức làmột hình dạng khó có thể gắn nhãn cho các câu trả lời "ngây thơ" như trung tâm khối lượng? Những người tôi có thể nghĩ dễ dàng là một U khổng lồ hoặc tiểu bang Florida (trung tâm khối lượng của những hình dạng này nằm ngoài ranh giới) –

Trả lời

7

Nếu bạn có thể chuyển đổi các đa giác thành một hình ảnh nhị phân, sau đó bạn có thể sử dụng nền tảng tồn tại trong lĩnh vực xử lý hình ảnh, ví dụ .: A Fast Skeleton Algorithm on Block Represented Binary Images.

Nhưng điều này là không thực sự hợp lý trong trường hợp chung, vì lỗi discretization và làm việc thêm.

Tuy nhiên, có thể bạn tìm thấy những hữu ích:

EDIT: Có lẽ bạn muốn tìm kiếm những điểm đó là trung tâm của vòng tròn lớn nhất chứa trong đa giác. Nó không nhất thiết phải luôn luôn ở trong trung tâm quan sát, nhưng hầu hết thời gian có lẽ sẽ cho kết quả mong đợi, và chỉ trong những trường hợp bệnh lý hơi một cái gì đó hoàn toàn tắt.

+0

Xem thêm http://stackoverflow.com/questions/1109536/an-algorithm-for-inflating-deflating-offsetting-buffering-polygons –

+2

Tôi nghĩ đây là những cược tốt nhất của bạn cho đến nay . Bạn có thể điều chỉnh phần trên bằng cách kéo giãn đa giác theo chiều dọc theo hệ số 2 hoặc 3, sau đó tìm vòng tròn lớn nhất chứa trong đa giác kéo dài. Điều này sẽ cung cấp cho bạn lớn nhất * ellipse * chứa trong đa giác, mà sẽ cung cấp cho bạn vị trí tốt nhất để đưa nhãn của bạn. – jprete

+0

Hai trong số ba liên kết trong câu trả lời này đã chết. – Nir

-2

Vấn đề này có thể tương tự như việc tìm kiếm "trung tâm khối lượng" giả sử mật độ đồng nhất.

EDIT: Phương pháp này sẽ không hoạt động nếu đa giác có "lỗ hổng"

+0

No. Xem hình 4 trong giấy ESRI mà OP liên kết tới. –

+0

Dường như giả định của tôi là những gì họ đã sử dụng trong # 2; thời gian duy nhất nó bị phá vỡ là theo điều kiện này: "Tuy nhiên, phương pháp này cung cấp một kết quả không chính xác nếu một đa giác có lỗ" – Janie

+1

No. Hãy tưởng tượng một người khổng lồ U. Không có lỗ, và trung tâm của khối lượng không phải là bên trong ranh giới của đa giác. Tôi nghĩ câu trả lời của bạn chỉ đúng cho đa giác lồi. –

1

Tính vị trí trung tâm (x, y) của mỗi cạnh của đa giác. Bạn có thể làm điều này bằng cách tìm sự khác biệt giữa các vị trí của các đầu của mỗi cạnh. Lấy trung bình của mỗi trung tâm trong mỗi chiều. Đây sẽ là trung tâm của đa giác.

+0

Tôi nghĩ rằng điều này gặp vấn đề tương tự như giải pháp của tôi khi nói đến hình dạng không lồi cao ... – Janie

+0

Đúng, và không lấy trọng số trung bình, nó cũng nhấn mạnh các cạnh ngắn, ngay cả khi đa giác lồi. – Reunanen

-1

Tôi nghĩ nếu bạn đã phá vỡ đa giác trở lại vào đỉnh của nó, và sau đó áp dụng một hàm để tìm thân lồi lớn nhất, và sau đó tìm trung tâm khỏi thân lồi, nó sẽ khớp với trung tâm "rõ ràng".

Tìm thân lồi lớn nhất cho các đỉnh: Look under the Simple Polygon paragraph.

Trung bình các đỉnh của thân lồi để tìm trung tâm.

+0

Tôi tự hỏi. Điều gì sẽ xảy ra, nếu đa giác của tôi là một 'U' khổng lồ? –

+0

Nó sẽ chọn một trong các cạnh. Hành vi mong muốn trong tình huống đó là gì? – CookieOfFortune

+0

Đối với một U khổng lồ, một giải pháp chấp nhận được là giữa phần dày phía dưới. –

-1

Nếu tôi hiểu điểm của giấy bạn liên kết đến (một vấn đề thú vị, btw), kỹ thuật "đệm bên trong" này tương tự như mô hình hóa hình dạng được đề cập trong một phần đường đang bị hòa tan bởi axit từ các cạnh trong (ví dụ như khoảng cách bộ đệm tăng, ít hình dạng ban đầu vẫn còn) Các bit cuối cùng còn lại là nơi lý tưởng để đặt một nhãn.

Làm thế nào để thực hiện điều này trong một thuật toán không may là không phải là rất rõ ràng với tôi ....

+0

Các phần mềm GIS như PostGIS có các chức năng như ST_Buffer để thực hiện điều này. Tôi không biết, nhanh quá. –

-1

bạn có thể đặt nhãn ở trung tâm ngây thơ (của hộp bounding, có lẽ), và sau đó di chuyển nó dựa trên các giao điểm của các cạnh đa giác cục bộ và BB của nhãn? Di chuyển dọc theo các tiêu chuẩn của các cạnh giao nhau, và nếu nhiều cạnh cắt nhau, tổng các chỉ tiêu của chúng cho chuyển động?

Chỉ cần đoán ở đây; trong loại vấn đề này, tôi có lẽ sẽ cố gắng giải quyết lặp đi lặp lại miễn là hiệu suất không quá quan tâm.

0

Làm thế nào để tìm ra "vòng tròn" của đa giác (vòng tròn lớn nhất vừa với nó), và sau đó căn giữa nhãn ở giữa đó? Dưới đây là một vài liên kết để giúp bạn bắt đầu:

http://www.mathopenref.com/polygonincircle.html
https://nrich.maths.org/discus/messages/145082/144373.html?1219439473

này sẽ không hoạt động hoàn hảo trên tất cả các đa giác, rất có thể; một đa giác trông giống như một C sẽ có nhãn ở một vị trí hơi khó lường. Nhưng lợi thế sẽ là nhãn sẽ luôn chồng chéo một phần cứng của đa giác.

+0

Sẽ không chậm nếu đa giác có nhiều hình tam giác? –

+0

Tôi không biết; phải không? –

-1

Không có nhiều thời gian để xây dựng hoặc kiểm tra điều này ngay bây giờ, nhưng tôi sẽ cố gắng làm nhiều hơn nữa khi tôi có cơ hội.

Sử dụng centroid làm phương thức chính của bạn. Kiểm tra xem liệu trọng tâm có nằm trong đa giác hay không; nếu không, hãy vẽ một đường thẳng qua điểm gần nhất và ở phía bên kia của đa giác. Tại điểm giữa của phần của đường đó nằm trong đa giác, hãy đặt nhãn của bạn.

Bởi vì điểm gần nhất với centroid có khả năng bị ràng buộc một khu vực khá lớn, tôi nghĩ rằng điều này có thể cho kết quả tương tự như vòng vây của Kyralessa. Tất nhiên, điều này có thể trở nên bối rối nếu bạn có một đa giác có lỗ. Trong trường hợp đó, các vòng tròn có thể sẽ tốt hơn nhiều. Mặt khác, nó mặc định là phương pháp centroid (nhanh?) Cho các trường hợp điển hình.

+0

Trường hợp thử nghiệm bệnh lý # 3: một hình dạng giống như búp bê đối xứng với một hình chữ nhật mỏng và hai octagons lớn ở hai đầu. Centroid nằm trong đa giác nhưng hình chữ nhật là một nơi không phù hợp để gắn nhãn vì nó có thể không vừa. –

1

Tôi không nói rằng đây là nhanh nhất, nhưng nó sẽ cung cấp cho bạn một điểm bên trong đa giác. Tính toán Straight Skeleton. Điểm bạn đang tìm kiếm là trên bộ xương này. Bạn có thể chọn một với khoảng cách bình thường ngắn nhất đến trung tâm của hộp giới hạn ví dụ.

2

Phương pháp Centroid đã được đề xuất nhiều lần. Tôi nghĩ rằng đây là một nguồn tài nguyên tuyệt vời mô tả các quá trình (và nhiều thủ thuật hữu ích khác với đa giác) rất trực giác:

http://paulbourke.net/geometry/polygonmesh/centroid.pdf

Ngoài ra, để đặt một nhãn UI đơn giản, nó có thể là đủ để chỉ tính toán bounding hộp của đa giác (một hình chữ nhật được xác định bởi x thấp nhất và cao nhất và tọa độ y của bất kỳ đỉnh trong đa giác), và nhận được trung tâm của nó tại địa chỉ:

{ 
    x = min_x + (max_x - min_x)/2, 
    y = min_y + (max_y - min_y)/2 
} 

Đây là nhanh hơn so với tính toán trọng tâm một chút, mà có thể là quan trọng đối với một ứng dụng thời gian thực hoặc nhúng.Cũng cần lưu ý rằng nếu đa giác của bạn là tĩnh (chúng không thay đổi hình dạng), bạn có thể tối ưu hóa bằng cách lưu kết quả của trung tâm BB/tâm tính khối lượng (tương ứng với đỉnh đầu tiên của đa giác) đến cấu trúc dữ liệu của đa giác.

+1

Suy nghĩ tốt, nhưng không phải lúc nào cũng hiệu quả, vì trung tâm của hộp giới hạn có thể nằm ngoài chính hình đa giác. ! [Trung tâm của hộp giới hạn bên ngoài đa giác (img)] (https://www.jonathanschmid.de/ext/stackoverflow-1203135.png) – Jonny

-2

bạn có thể sử dụng Trung tâm của Mass (hoặc Trung tâm của trọng lực) phương pháp được sử dụng trong công trình dân dụng, đây là một liên kết hữu ích từ wikipedia:

http://en.wikipedia.org/wiki/Center_of_mass

6

Làm thế nào về:

Nếu centroid của đa giác nằm bên trong đa giác, sau đó sử dụng nó, khác:

1) Mở rộng một đường thẳng từ trung tâm qua đa giác chia đa giác thành hai nửa diện tích bằng

2) "Trung tâm hình ảnh" là điểm nửa điểm giữa điểm gần nhất nơi đường chạm vào chu vi và điểm tiếp theo cắt chu vi theo hướng đi xa từ tâm

Dưới đây là một vài hình ảnh để minh họa cho nó:

enter image description here

enter image description here

+0

Yêu bạn đời! Thực sự thông minh! Bây giờ trong điều khoản của việc thực hiện, bạn và hoặc bất cứ ai khác giải quyết? –

+0

@MaraisRossouw Tôi đã đăng câu trả lời cho câu hỏi tương tự với câu hỏi của OP sử dụng phương pháp này: http://stackoverflow.com/a/39408054/3628232 –

6

tôi đã tìm thấy một giải pháp rất tốt để này từ MapBox gọi Polylabel. Toàn bộ nguồn có sẵn trên Github của chúng.

Về cơ bản, nó cố gắng tìm trung tâm hình ảnh của đa giác như T Austin đã nói.

enter image description here

Một số thông tin chi tiết đề nghị này có thể là một giải pháp thực hiện:

Thật không may, tính [giải pháp lý tưởng] vừa phức tạp và chậm chạp. Các giải pháp được công bố cho vấn đề này yêu cầu Triangulation Delaunay hạn chế hoặc tính toán một bộ xương thẳng như các bước tiền xử lý - cả hai bước đều chậm và dễ xảy ra lỗi.

Đối với trường hợp sử dụng của chúng tôi, chúng tôi không cần giải pháp chính xác - chúng tôi sẵn sàng trao đổi một số độ chính xác để tăng tốc độ. Khi chúng tôi đặt nhãn trên một bản đồ, điều quan trọng hơn là nó được tính bằng mili giây so với để hoàn hảo về mặt toán học.

Lưu ý nhanh về việc sử dụng. Mã nguồn hoạt động tuyệt vời cho Javascript out of the box tuy nhiên nếu bạn có ý định về việc sử dụng điều này với một đa giác "bình thường" thì bạn nên bọc nó trong một mảng trống rỗng như các chức năng ở đây mất GeoJSONPolygons chứ không phải là đa giác bình thường tức là

var myPolygon = [[x1, y1], [x2, y2], [x3, y3]]; 
var center = polylabel([myPolygon]); 
+1

Làm cách nào tôi bỏ lỡ nhu cầu về mảng phụ ... bạn thưa bạn một cuộc sống tiết kiệm! – complistic

+0

@complistic Hah .. thành thật mà nói ... tôi đã bỏ lỡ điều này và tôi đã mất nhiều thời gian hơn nó phải tìm nó :) – Chris

Các vấn đề liên quan