Thuật toán tạo các tam giác liền kề


14

Tôi có một hệ thống nơi bạn có thể nhấp một lần để đặt một nút trong một cảnh. Khi bạn đặt 3 nút, nó tạo thành một hình tam giác. Khi bạn đặt bất kỳ nút nào trong tương lai, nó sẽ tạo ra một tam giác mới bằng cách nối nút đó với 2 nút hiện có gần nhất.

Điều này hoạt động tốt hầu hết thời gian nhưng không hoàn hảo khi được sử dụng gần các hình tam giác với các góc rất nhọn, bởi vì một trong 2 nút gần nhất thường không phải là một nút nên được sử dụng.

Ví dụ, xem hình ảnh dưới đây. Tam giác màu đỏ tươi là cái đầu tiên được đặt. Nếu sau đó tôi nhấp vào vị trí được đánh dấu X, cái tôi nhận được là một hình tam giác mới có lớp phủ màu xanh. Những gì tôi muốn là một hình tam giác mới, nơi lớp phủ màu xanh lá cây. (ví dụ: đối xứng với màu đỏ tươi, trong ví dụ này. Làm rõ: Các hình tam giác màu lục và màu đỏ không trùng nhau - màu xanh lá cây kéo dài dưới màu xanh lam đến nút ngoài cùng bên trái)

Ví dụ về hành vi thực tế và mong muốn

Làm cách nào để xác định 2 đỉnh hiện có sẽ sử dụng khi tạo các tam giác mới để các tam giác không bị chồng lên nhau như thế này?

EDIT : Tìm kiếm cạnh gần nhất cho kết quả tốt hơn , nhưng không hoàn hảo. Hãy xem xét tình huống này:

nhập mô tả hình ảnh ở đây

Phép thử 'cạnh gần nhất' không rõ ràng và có thể trả về AB hoặc AC (vì điểm gần nhất với X cho cả hai là tại A). Kết quả mong muốn sẽ là AC, để tạo thành tam giác ACX không có cạnh trùng nhau. Làm thế nào tôi có thể đảm bảo kết quả này? (Tôi không cần phải thực hiện các thử nghiệm chồng chéo cạnh riêng lẻ như một bộ ngắt kết nối nếu có thể vì tôi lo ngại rằng thử nghiệm cạnh gần nhất không nhất thiết phải phát hiện ra 2 là chính xác, do các vấn đề chính xác về dấu phẩy động.)


Nó không đủ tốt để nhìn vào 5 đỉnh cuối cùng được đặt và chọn hai đỉnh gần nhất với đỉnh mới được đặt phải không? Tôi sẽ chỉ cho bạn các thuật toán cho các dải tam giác ( codercorner.com/Strips.htm ) nhưng chúng thường chỉ sử dụng hai hoặc ba cuối cùng bỏ qua một.
Roy T.

1
Là tam giác màu xanh lá cây chồng lên nhau màu đỏ tươi? Mục tiêu của việc này là gì? Người dùng có cần kiểm soát vị trí và cách thức hình tam giác được tạo ra hoặc hình tam giác của đám mây điểm có thể được chấp nhận không?
bummzack

Để đặt điều này trong một bối cảnh đồ thị, về cơ bản bạn muốn kết nối các nút của bạn, mà không có bất kỳ cạnh nào chồng chéo? (Giả sử các tam giác màu đỏ tươi / xanh lá cây sẽ chia sẻ một cạnh)
MichaelHouse

Roy T: không - chỉ chọn 2 cái gần nhất là sai, như tôi nghĩ ví dụ cho thấy. Là một cái gì đó không rõ ràng? Bummzack - Màu xanh lá cây không trùng với màu đỏ tươi. Mục tiêu là tạo lưới hoặc đồ thị của các hình tam giác này. Người dùng không cần kiểm soát, vâng. Byte56 - có, không có cạnh nên giao nhau.
Kylotan

2
Người dùng sẽ thực sự nhìn thấy các hình tam giác riêng lẻ? Hay nó sẽ là một bề mặt liên tục?
bummzack

Câu trả lời:


11

Thay vì tìm khoảng cách tối thiểu đến các nút, hãy tìm khoảng cách tối thiểu đến cạnh (tức là đoạn đường được xác định bởi các nút).

Sau đó, nếu điểm gần nhất là một đỉnh (mà bạn sẽ phải sử dụng một số phép thử epsilon ** dấu phẩy động), hãy so sánh góc giữa đường từ điểm mới đến đỉnh và mỗi cạnh được nối với đỉnh đó. Chọn một góc có góc tuyệt đối tối thiểu:

MinAngle(newPoint, vertex, edge1, edge2)
{
   newEdgeUnit = norm(newPoint - vertex); // don't actually need to normalize this
   edge1Unit = norm(edge1 - vertex);      // you probably have these from your dist to line tests
   edge2Unit = norm(edge2 - vertex);

   edge1Dot = dot(edge1Unit, newEdgeUnit);
   edge2Dot = dot(edge2Unit, newEdgeUnit);

   // you can simply compare dot products to find the minimum absolute angle
   if (edge1Dot > edge2Dot) return edge1;     // set up this way so you can generalize to an array
   return edge2;
}

** Để tránh thêm các hình tam giác suy biến, có thể phá vỡ phép thử epsilon, bạn có thể muốn đặt một vùng xung quanh mỗi đỉnh nơi việc thêm điểm không được phép, (một cái gì đó như không cho phép các điểm trong một số nhiều epsilon được sử dụng ở trên).


3
+1 - đây là IMHO một câu trả lời đơn giản hơn nhiều so với những câu hỏi khác và có nhiều khả năng cung cấp kết quả chính xác. Khoảng cách đến phân khúc cũng dễ dàng để tính toán, với một sơ đồ thông minh.
Steven Stadnicki

Đồng ý, đây là một phương pháp sạch hơn. Có lẽ là những gì tôi sẽ đến nếu tôi nghĩ về nó nhiều hơn: /
MichaelHouse

À, thật gần! Nhưng, như với câu trả lời của Byte56 và sơ đồ của Jimmy, đôi khi có 2 cạnh tương đương nhau, và một trong số chúng vi phạm các ràng buộc. Tôi đã cập nhật câu hỏi của mình.
Kylotan

@Kylotan Có lẽ trong trường hợp đó, chỉ cần kiểm tra cái nào trùng lặp và chọn tùy chọn khác sẽ làm gì? Tìm kiếm các hình tam giác chia sẻ cạnh bạn đã chọn và kiểm tra xem hình tam giác mới của bạn có nằm cùng cạnh với cạnh đó không.
Kevin Reid

@Kylotan Bạn có đảm bảo hình tam giác của bạn luôn có cùng một cuộn dây không? Nếu có, bạn có thể loại trừ cạnh có một điểm bình thường ra khỏi đỉnh mới của bạn (sử dụng sản phẩm chấm).
bummzack

6

Sau khi tam giác đầu tiên được đặt, khi đặt một đỉnh mới, bạn sẽ luôn tạo ra hai cạnh mới. Cạnh thứ ba cho tam giác mới sẽ luôn là cạnh chung với tam giác trước. Nếu bạn có thể tìm cách xác định cạnh được chia sẻ, bạn sẽ biết nên kết nối với đỉnh nào, nhưng đó là phần khó. Tôi tin rằng một cách bạn có thể làm điều này bằng cách vẽ một đường thẳng từ đỉnh mới của bạn đến trung tâm của ba cạnh cuối cùng được tạo ra (hoặc có thể là 3 cạnh gần nhất).

nhập mô tả hình ảnh ở đây

Nếu đường thẳng từ đỉnh của bạn đến trung tâm của cạnh không giao nhau với hai cạnh còn lại, bạn có cạnh được chia sẻ. Cạnh được chia sẻ sẽ cho bạn biết hai đỉnh để kết nối đỉnh mới của bạn.

Jimmy đã đưa ra trường hợp cho một điểm mơ hồ về nơi mà tam giác mới sẽ đi như thế này:

tam giác mơ hồ

Điều đó sẽ cho bạn cơ hội lựa chọn giữa hai hình tam giác hợp lệ. Có lẽ cà vạt phá vỡ điểm trung tâm là gần nhất.

Xem xét cập nhật của bạn, trong khi phức tạp hơn, giải pháp của tôi sẽ chỉ dẫn đến kết quả hòa khi bạn có hai hình tam giác hợp lệ. Sử dụng phương pháp này hình ảnh ví dụ thứ hai của bạn sẽ tạo ra kết quả bạn muốn.

nhập mô tả hình ảnh ở đây


Có thể có một tình huống trong đó hai trong số các đường thẳng không giao nhau với các cạnh (khi X gần với một đỉnh hơn so với cạnh)
Jimmy

@Jimmy bạn có thể vẽ một hình ảnh của một tình huống như vậy?
MichaelHouse


À đúng rồi, sau đó bạn có hai lựa chọn về nơi đặt tam giác! Một trong hai bên sẽ làm việc. Có lẽ bạn có thể buộc break với cái có khoảng cách ngắn nhất đến trung tâm.
MichaelHouse

@Kylotan giải pháp này không hiệu quả? Bạn đã đề cập trong một bình luận với Jeff rằng hình ảnh của Jimmy có hai trường hợp và một trường hợp vi phạm các ràng buộc, nhưng điều đó không đúng. Trong hình ảnh của Jimmy, cả hai trường hợp đều tạo ra các hình tam giác hợp lệ bằng phương pháp của tôi.
MichaelHouse

1

Có tam giác ABC màu đỏ của bạn, sau đó bạn kết hợp một đỉnh X mới. Tôi nghĩ rõ ràng là sẽ có hai đường thẳng bắt đầu tại D sẽ không giao nhau giữa bất kỳ cạnh nào của tam giác ABC.

Hai dòng này có thể là AX & BX, BX & CX hoặc AX & CX. Sau đó, bạn có thể coi vấn đề của mình là vấn đề cổ điển của "hai đường thẳng giao nhau"? Sau đó, bạn có thể kiểm tra cặp đường nào trong số các đường thẳng này không giao nhau với bất kỳ cạnh tam giác ABC nào sau đây, ví dụ, bất kỳ phương thức nào trong câu hỏi này . Do đó, bạn sẽ có hai cạnh mới của tam giác mới.


Điều này có vẻ tốt, nhưng cách bạn tuyên bố dường như cho rằng chỉ có một hình tam giác hiện có. Làm thế nào nó sẽ khái quát cho nhiều người?
Kylotan

Hừm ... nếu X và tam giác ABC của bạn cố định, tôi đoán là chỉ có một, phải không?
Dan

Hệ thống tạo ra một tam giác mới cho mỗi nút sau nút thứ hai.
Kylotan

Xin lỗi, tôi đã hiểu nhầm câu hỏi của bạn. Hãy để tôi xem làm thế nào tôi có thể mở rộng này đến nhiều hình tam giác.
Dan

Chà tôi đoán bạn có thể tìm kiếm hai đỉnh gần nhất với X mà không vượt qua bất kỳ cạnh nào khi kết nối với X?
bummzack

1

Tìm hiểu xem bạn đang ở một trong những vùng không rõ ràng (1, 2, 3 bên dưới), khá dễ dàng: coi mỗi cạnh của tam giác của bạn là mặt phẳng 2D và kiểm tra phía nào của mặt phẳng mà điểm mới của bạn nằm trên. Nếu bạn ở trong hai trong số chúng nhưng bên ngoài một, thì cái đó tương ứng với cạnh của tam giác đóng góp hai đỉnh cho tam giác mới của bạn.

Vùng Voronoi của một tam giác

Nếu bạn ở trong một và ngoài hai, bạn đang ở trong trường hợp mơ hồ trong đó phần gần nhất của tam giác với điểm mới của bạn là một góc. Trong trường hợp đó, bạn có thể tạo một mặt phẳng 2D từ trung điểm của cạnh đối diện (mặt phẳng bên trong) và đỉnh gần nhất (mặt phẳng được chia sẻ bởi hai mặt phẳng mà bạn nằm ngoài). Bạn có thể chọn một cạnh tùy thuộc vào phía nào của mặt phẳng này điểm mới của bạn nằm trên.

Lưu ý rằng kiểm tra mặt phẳng trong 2D hoạt động theo cách tương tự như trong 3D: chấm một vectơ từ bất kỳ nơi nào trên mặt phẳng tới điểm của bạn với mặt phẳng bình thường (trong 2D, đây là đường vuông góc của đường thẳng).

(Ngẫu nhiên, các vùng đỏ tươi được phân định trong hình ảnh này được gọi là vùng Voronoi; họ là những lĩnh vực không gian chứa điểm đó là gần nhất với một tính năng cạnh cụ thể hoặc đỉnh-của tam giác. Edit: thuật ngữ của tôi ở đây không phải là thực sự hoàn toàn chính xác, những vùng này không chính xác là vùng Voronoi.)


Tôi không rõ ngay lập tức làm thế nào điều này khái quát cho nhiều hình tam giác trong cảnh - đặc biệt nếu tính năng gần nhất là một đỉnh có thể được chia sẻ bởi hơn 1 hình tam giác.
Kylotan

@Kylotan Chỉ cần chạy thuật toán cho tất cả các hình tam giác, và chọn tính năng tổng thể gần nhất. Bạn cần một số logic tie-break bất kể điều gì. Nếu bạn kết thúc với tính năng gần nhất là một đỉnh được chia sẻ, thì bạn nên ở trong khu vực cạnh (# 1, # 2, # 3) chỉ cho một hình tam giác, vì vậy bạn có thể chọn nó không?
John Calsbeek
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.