2010-03-09 37 views
5

Tôi đang xây dựng bộ chuyển đổi tệp CAD trên hai thư viện (Opencascade và DWF Toolkit).Tìm các đỉnh độc đáo từ 'canh tam giác'

Tuy nhiên, câu hỏi của tôi là plattform thuyết bất khả tri:

Given:

tôi đã tạo ra một lưới như một danh sách các mặt hình tam giác tạo thành một mô hình được xây dựng thông qua ứng dụng của tôi. Mỗi tam giác được xác định thông qua ba đỉnh, trong đó bao gồm ba phao (x, y & z tọa độ). Kể từ khi hình tam giác tạo thành một lưới, hầu hết các đỉnh được chia sẻ bởi nhiều hơn sau đó một hình tam giác.

Mục tiêu:

tôi cần phải tìm ra danh sách các đỉnh độc đáo, và để tạo ra một loạt các gương mặt bao gồm các bộ ba chỉ số trong danh sách này.

//step 1: build a list of unique vertices 
for each triangle 
    for each vertex in triangle 
     if not vertex in listOfVertices 
     Add vertex to listOfVertices 

//step 2: build a list of faces 
for each triangle 
    for each vertex in triangle 
     Get Vertex Index From listOfvertices 
     AddToMap(vertex Index, triangle) 

Trong khi tôi có một thực hiện mà thực hiện điều này, bước 1 (thế hệ của danh sách các đỉnh duy nhất) là rất chậm theo thứ tự của O (n:

gì tôi muốn làm điều này là !), vì mỗi đỉnh được so sánh với tất cả các đỉnh đã có trong danh sách. Tôi nghĩ "Này, cho phép xây dựng một hashmap của các thành phần đỉnh của tôi bằng cách sử dụng std :: map, để tăng tốc mọi thứ!", Chỉ để thấy rằng tạo ra một khóa duy nhất từ ​​ba giá trị dấu chấm động không phải là một nhiệm vụ tầm thường. Ở đây, các chuyên gia của stackoverflow đi vào chơi: Tôi cần một số loại hàm băm hoạt động trên 3 phao, hoặc bất kỳ chức năng nào khác tạo ra một giá trị duy nhất từ ​​một vị trí 3d-đỉnh.

+0

Độ độc đáo của đỉnh này phải như thế nào? Ý tôi là, bạn chỉ đang cố gắng tiết kiệm không gian, hay bạn cần cấu trúc liên kết rất mạnh mẽ. Giả sử đỉnh Va và Vb nhận được các id khác nhau pn và pq nhưng thực sự thực sự là 'giống nhau', đó có phải là bộ ngắt giao dịch không? – Tarydon

+0

Vâng, nó sẽ là kể từ khi tôi đang cố gắng để xuất khẩu mắt lưới của Topology. Nếu một Vertex duy nhất từ ​​nguồn sẽ tồn tại nhiều lần trong đích, các hình tam giác được biểu diễn từ nó sẽ không chia sẻ mép - cấu trúc liên kết có thể mở ra. – sum1stolemyname

Trả lời

3

Dump tất cả các đỉnh trong một mảng, sau đó thực hiện unique(sort(array)). Đây là O (k n log (n)), trong đó k là số tam giác trung bình có chung một đỉnh, thường là k < 7.

Thông báo trước duy nhất tôi có thể nghĩ đến là chức năng unique bạn sẽ có thể để có một con trỏ tới một hàm so sánh, kể từ khi bạn có thể muốn xem xét các đỉnh của bạn bằng nếu

distance(vertex1, vertex2) < threshold 

nhưng điều đó có vẻ là OK.

+0

Cách tiếp cận này hoạt động. Tôi thực hiện điều này bằng cách sử dụng một danh sách STL. +1 – sum1stolemyname

+0

Và nó là _much_ hiệu quả hơn theo cách đó. (35 giây với cách tiếp cận đầu tiên của tôi, 1,5 giây với cách tiếp cận tinh tế) – sum1stolemyname

+2

Có một lỗi khó chịu trong trường hợp này nếu bạn muốn nắm bắt các điểm trong khoảng cách ngưỡng của nhau. Không có gì đảm bảo rằng các điểm gần nhau "sắp xếp" gần nhau. Trong thực tế, tôi nghĩ rằng bạn có thể chứng minh rằng đối với bất kỳ chức năng sắp xếp có những điểm tùy ý gần nhau mà sắp xếp đến các địa điểm xa trong danh sách ... Không tốt. –

2

Ba giải pháp. Chắc chắn có những người khác

  1. Sử dụng bản đồ băm. Điều này sẽ chỉ hoạt động nếu "giống nhau" có nghĩa là giống nhau
  2. Sử dụng phân vùng không gian nhị phân để chia các điểm
  3. Sử dụng lưới thông thường để chia điểm của bạn.

Trong trường hợp 2 và 3 nếu bạn muốn chỉ định một số dung sai, bạn sẽ cần phải tìm kiếm nhiều hơn một phần của cây hoặc lưới. Trong trường hợp BSP, điều này có nghĩa là kiểm tra xem bạn có nằm trong khả năng chịu đựng của mặt phẳng phân chia hay không và nếu như vậy đệ quy vào cả hai nửa. Trong trường hợp lưới, điều này có nghĩa là kiểm tra tất cả các ô lân cận nằm trong dung sai. Không phải là quá khó, nhưng có nghĩa là sẽ khó sử dụng một giải pháp "ngoài giá".

+0

Nó đã cho tôi một chút để có được cách phân vùng không gian có thể giúp tôi - Đây là một cách tiếp cận thú vị. +1 – sum1stolemyname

0

Ý tưởng chung để lấy hàm băm là nhân mỗi bitpattern của phao với prime và thêm chúng lại với nhau. Một cái gì đó như thế:

unsigned int hash_point(float x, float y, float z) 
{ 
    unsigned int* px = (unsigned int*)&x; 
    unsigned int* py = (unsigned int*)&y; 
    unsigned int* pz = (unsigned int*)&z; 

    return (*px)*PRIME1 + (*py)*PRIME2 + (*pz)*PRIME3; 
} 

Bạn nên lưu ý rằng sizeof (unsigned int) được coi là bằng sizeof (float) tại đây. Mẫu ở đây chỉ để minh họa ý tưởng chính, bạn nên điều chỉnh nó cho nhu cầu của bạn.

+0

Khi x, y và z không phải là số nguyên, nhân chúng bằng số nguyên tố sẽ không giúp được gì nhiều. – Tarydon

+0

Chính xác. Bạn nên nhân bitpattern của phao, không nổi chính nó. –

+0

Hãy coi chừng rằng một số số có nhiều hơn một biểu diễn dạng bit như 0 và -0 giống nhau nhưng có các mẫu bit khác nhau. Điều này có nghĩa là chúng sẽ băm thành các giá trị khác nhau. Điều này có thể hoặc có thể không phải là một vấn đề cho ứng dụng của bạn mặc dù. –

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