Giả sử rằng các họa tiết của bạn chiếm các bộ gạch là hình chữ nhật (nếu chúng chiếm các tập tùy ý, thì bạn không thể vẽ chính xác tất cả trong trường hợp chung), vấn đề là không có mối quan hệ tổng thứ tự giữa các phần tử, vì vậy bạn không thể sắp xếp họ sử dụng một loại sẽ dẫn đến so sánh O (nlogn).
Lưu ý rằng đối với bất kỳ hai đối tượng A và B, A phải được vẽ trước B (A <- B), B nên được vẽ trước A (B <- A) hoặc chúng có thể được vẽ theo bất kỳ thứ tự nào. Họ tạo thành một trật tự một phần. Nếu bạn tự vẽ một vài ví dụ với 3 đối tượng chồng chéo, bạn có thể nhận thấy rằng mặc dù đối tượng thứ 1 và thứ 3 không thể trùng nhau, do đó không có sự phụ thuộc trực tiếp, thứ tự vẽ của chúng phụ thuộc vào đối tượng thứ 2 nằm giữa chúng - tùy thuộc vào cách bạn đặt nó, bạn sẽ có được các đơn đặt hàng bản vẽ khác nhau. Tóm lại - các loại truyền thống không hoạt động ở đây.
Một giải pháp là sử dụng phép so sánh (được đề cập bởi Dani) và so sánh từng đối tượng với nhau để xác định các phụ thuộc của chúng và tạo thành một biểu đồ phụ thuộc (sẽ là DAG). Sau đó thực hiện sắp xếp tô pô trên biểu đồ để xác định thứ tự vẽ. Nếu không có quá nhiều đối tượng, điều này có thể đủ nhanh (nó O(n^2)
).
Một giải pháp khác là sử dụng cây tứ giác (để cân bằng - giả ) và lưu trữ hình chữ nhật của tất cả các đối tượng vào đó.
Sau đó lặp qua tất cả các đối tượng X và sử dụng cây tứ giác để kiểm tra xem có bất kỳ đối tượng Y nào trong dải phía trên đối tượng X bắt đầu bằng góc ngoài cùng bên trái và kết thúc với góc ngoài cùng bên phải của đối tượng X - cho tất cả Y, Y < - X. Như thế này, bạn vẫn sẽ phải tạo thành một biểu đồ và sắp xếp theo cấu trúc liên kết.
Nhưng bạn có thể tránh nó. Bạn sử dụng danh sách các đối tượng Q và một bảng các đối tượng T. Bạn lặp lại tất cả các vị trí có thể nhìn thấy từ các giá trị nhỏ hơn đến lớn hơn trên trục x (một hàng), đi từng hàng trên trục y. Nếu có một góc dưới cùng của một đối tượng tại vị trí đó, hãy thực hiện quy trình trên để xác định các phụ thuộc. Nếu một đối tượng X phụ thuộc vào một số đối tượng Y khác nằm phía trên nó (Y <- X) và mọi Y như vậy đã có trong Q, hãy thêm X vào Q. Nếu có một số Y không có trong Q, hãy thêm X vào T và biểu thị rằng Y <- X. Mỗi khi bạn thêm một đối tượng vào Q, bạn sẽ loại bỏ các phụ thuộc của các đối tượng đang chờ xử lý trong T. Nếu tất cả các phụ thuộc bị xóa, một đối tượng từ T sẽ được chuyển đến Q.
Chúng tôi giả định rằng các họa tiết đối tượng không nhìn ra các khe của chúng ở phía dưới, bên trái hoặc bên phải (chỉ ở trên cùng, giống như cây trong ảnh của bạn). Điều này sẽ cải thiện hiệu suất cho một số lượng lớn các đối tượng. Cách tiếp cận này sẽ một lần nữa O(n^2)
, nhưng chỉ trong trường hợp xấu nhất bao gồm các vật thể có kích thước kỳ lạ và / hoặc cấu hình kỳ lạ của các vật thể. Trong hầu hết các trường hợp, nó O(n * logn * sqrt(n))
. Biết chiều cao của các họa tiết của bạn có thể loại bỏ sqrt(n)
, bởi vì bạn không phải kiểm tra toàn bộ sọc ở trên. Tùy thuộc vào số lượng đối tượng trên màn hình, bạn có thể thử thay thế cây tứ giác bằng một mảng cho biết vị trí nào được lấy (có ý nghĩa nếu có nhiều đối tượng).
Cuối cùng, vui lòng kiểm tra mã nguồn này để biết một số ý tưởng: https://github.com/axel22/sages/blob/master/src/gui/scala/name/brijest/sages/gui/Canvas.scala