2015-11-30 24 views
7

Tôi đang cố gắng viết một đoạn mã có danh sách các đa giác (được định nghĩa là danh sách các danh sách IntPoints) kiểm tra xem có bất kỳ liên lạc nào không và nếu hợp nhất chúng thành một đa giác . Để làm được điều này, tôi đã cố gắng trong hai phương pháp sau đây:Hợp nhất các đa giác cảm ứng cho kết quả sai

List<List<IntPoint>> output=new List<List<IntPoint>>(); 
output = Clipper.SimplifyPolygons(input,PolyFillType.pftPositive); 

Clipper c = new Clipper(); 
c.AddPaths(input, PolyType.ptClip, true); 
c.Execute(ClipType.ctUnion, output); 

Bây giờ cả hai kết hợp các đa giác cùng nhau khá dễ dàng tuy nhiên họ là một chút overzelous như bất kỳ không gian mở đa giác được bỏ qua và các khu vực mở được kết hợp đơn giản thành một đa giác duy nhất, có nghĩa là một cái gì đó như thế này: Sheer horror as a two polygons that are not touching are merged into a single square devoid of any meaning or life

xảy ra. Bây giờ điều này rõ ràng là sai vì hai đa giác này không chạm vào nhau. Kết quả tương tự cũng xảy ra với cả hai phương pháp. Kết quả sẽ giống như đầu vào. Bất kỳ ý tưởng làm thế nào để sửa lỗi này? Các sollution không phải sử dụng thư viện clipper (tôi không kết hôn với nó) nhưng tôi cần một cái gì đó sử dụng đa giác được xác định bởi một danh sách các điểm đầu vào là một List> nơi một Intpoint chỉ là một struct có chứa một x và một y.

Sửa Tôi nhận thấy rằng vấn đề này cũng xảy ra khi không có đa giác bên trong của đa giác khác, vì vậy giải pháp luôn luôn là "đầy" chỉnh sửa chỉnh sửa: đây cũng là một ví dụ về những gì đầu vào có thể là như

input[0][0] 
{ClipperLib.IntPoint} 
    X: -724 
    Y: -472 
input[0][1] 
{ClipperLib.IntPoint} 
    X: 428 
    Y: -472 
input[0][2] 
{ClipperLib.IntPoint} 
    X: 428 
    Y: -472 
    input[0][3] 
{ClipperLib.IntPoint} 
    X: 428 
    Y: 632 
input[0][4] 
{ClipperLib.IntPoint} 
    X: 428 
    Y: 632 
input[0][5] 
{ClipperLib.IntPoint} 
    X: -724 
    Y: 632 
input[0][6] 
{ClipperLib.IntPoint} 
    X: -724 
    Y: 632 
input[0][7] 
{ClipperLib.IntPoint} 
    X: -724 
    Y: -472 
input[0][8] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: -218 
input[0][9] 
{ClipperLib.IntPoint} 
    X: -107 
    Y: -218 
input[0][10] 
{ClipperLib.IntPoint} 
    X: -107 
    Y: -218 
input[0][11] 
{ClipperLib.IntPoint} 
    X: -107 
    Y: -209 
input[0][12] 
{ClipperLib.IntPoint} 
    X: -107 
    Y: -209 
input[0][13] 
{ClipperLib.IntPoint} 
    X: -320 
    Y: -172 
input[0][14] 
{ClipperLib.IntPoint} 
    X: -320 
    Y: -172 
input[0][15] 
{ClipperLib.IntPoint} 
    X: -320 
    Y: 132 
input[0][16] 
{ClipperLib.IntPoint} 
    X: -320 
    Y: 132 
input[0][17] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: 173 
input[0][18] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: 173 
input[0][19] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: -201 
input[0][20] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: -201 
input[0][21] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: -218 

Dữ liệu đầu vào này là một hình vuông có lỗ cắt vào đó.

+0

Bất kỳ ai cũng biết cách mô tả vấn đề này tốt nhất? Đa giác trong đa giác được hợp nhất? Không cho phép các vùng lân cận? – Thijser

+0

Tôi nghĩ rằng tôi có thể đã tìm thấy sollution nhưng điều đó sẽ phụ thuộc vào câu trả lời của https://stackoverflow.com/questions/34263601/algoritm-for-translating-list-of-wallsections-into-coherent-polygon – Thijser

Trả lời

2

Có cần phải là PolyType.ptSubject (thiếu mã của bạn) và PolyType.ptClip được thêm vào Clipper trước khi thực thi. Ngoài ra, bạn cần phải chọn ClipType rằng sẽ tạo ra kết quả bạn muốn, như hình dưới đây:

private void Form1_Paint(object sender, PaintEventArgs e) 
    { 
     clip = new List<List<IntPoint>>(); 
     clip.Add(pol2); 

     input = new List<List<IntPoint>>(); 
     input.Add(pol1); 

     output = new List<List<IntPoint>>(); 

     Clipper c = new Clipper(); 
     c.AddPaths(input, PolyType.ptSubject, true); 
     c.AddPaths(clip, PolyType.ptClip, true); 
     c.Execute(clipType, output); 

     DrawPolygon(output, e.Graphics, Pens.Red); 
    } 

XOR:

enter image description here

Union:

enter image description here

Intersection:

enter image description here

khác biệt: pol1 - pol2

enter image description here

khác biệt: pol2 - pol1

enter image description here

+0

Tôi nghĩ rằng vấn đề có nhiều hơn để làm với một định dạng đầu vào inproper hơn? – Thijser

+0

Tôi nghĩ rằng các addpath sẽ tự động thêm chúng làm đối tượng kể từ đó, cũng có nhiều hơn 2 (và trong một số trường hợp chỉ 1) đa giác. – Thijser

-3

Một điều bạn có thể nhìn vào là kiểu dữ liệu không gian được giới thiệu trong SQL Server 2008 khi xử lý các hình dạng hình học.

https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlgeometry.stintersection.aspx

Địa lý là cùng một URL nhưng với sqlgeography thay vì sqlgeometry

Bạn có thể sử dụng .STIntersects() == 1 và .STIntersection (AnotherShape) để lấy các nút giao thông. Ngoài ra còn có các phương pháp khác để cung cấp cho bạn kết quả tương tự như trên.

Lợi ích của việc này là nếu bạn kết hợp điều này với cơ sở dữ liệu của mình, bạn có thể sử dụng các chỉ mục không gian để làm cho nó nhanh hơn.

https://msdn.microsoft.com/en-us/library/bb934196.aspx

+0

Hữu ích nhưng phần mềm này không bao gồm bất cứ điều gì liên quan đến cơ sở dữ liệu và tôi không nghĩ rằng đó là một ý tưởng tốt để buộc mọi người cũng có một cơ sở dữ liệu được cài đặt. – Thijser

+0

Tôi hiểu mối lo ngại của bạn nhưng tương tự như làm việc với EntityFramework, bạn có thể sử dụng các lớp được bao gồm trong khuôn khổ .NET (DbGeometry/DbGeography) và điền chúng theo cách thủ công. Điều này không yêu cầu cơ sở dữ liệu hoặc thậm chí bất kỳ loại truy cập dữ liệu nào. Nó chỉ sử dụng chức năng được xây dựng trong các lớp được thiết kế để làm việc với các kiểu dữ liệu không gian dễ dàng hơn. –

+0

Câu trả lời này không liên quan gì đến những gì OP yêu cầu. – Randy

1

Dường như thư viện cần một số sự kết hợp của phiên bản PolyTree của Execute phương pháp, và một số xây dựng phức tạp hơn của đa giác lên trong đối tượng Clipper, mà sẽ đưa vào tài khoản cho dù đầu vào có chứa lỗ.

Không giống như đa giác màu xanh lá cây với lỗ được biểu diễn như một mảng điểm, nó phải là một PolyTree với đa giác bên ngoài và một đa giác lỗ bên trong.

+0

Bất kỳ ý tưởng làm thế nào tôi sẽ tiếp cận điều đó? – Thijser

+0

Tôi cũng đã thêm vào một ví dụ về định dạng đầu vào. – Thijser

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