Truy tìm phạm vi rộng trên lưới


8

Tôi hiện đang làm việc trên đường dẫn A * trên lưới và tôi đang tìm cách làm mịn đường dẫn được tạo, đồng thời xem xét mức độ của nhân vật di chuyển dọc theo lưới. Tôi đang sử dụng lưới cho tìm đường, tuy nhiên chuyển động của nhân vật là chuyển vùng miễn phí, không chuyển động nghiêm ngặt đối với chuyển động của ô.

Để đạt được một con đường trơn tru hơn, hiệu quả hơn, tôi đang thực hiện theo dõi đường kẻ trên lưới để xác định xem có các ô không thể tách rời giữa các ô để cạo các góc không cần thiết hay không.

Tuy nhiên, vì dấu vết dòng là 0, nó không xem xét phạm vi của ký tự và cho kết quả xấu (không trả lại các ô không thể bỏ qua chỉ bị bỏ qua bởi dòng, gây ra va chạm không mong muốn).

Vì vậy, những gì tôi đang tìm kiếm hơn là một thuật toán dòng xác định các ô bên dưới nó, tôi đang tìm một thuật toán xác định các ô theo một phạm vi rộng của ô. Đây là một hình ảnh để giúp hình dung vấn đề của tôi!

Đây là một hình ảnh để giúp hình dung vấn đề của tôi

Có ai có ý tưởng nào? Tôi đã làm việc với dây chuyền của Bresenham và các giải pháp thay thế khác nhưng tôi chưa tìm ra cách khắc phục vấn đề cụ thể này.


Tôi sẽ sử dụng hai dòng của Besenham với chiều rộng nửa gạch.
Jonathan Connell

Câu trả lời:


1

Sẽ thế nào nếu bạn vẽ một đường từ mọi góc của 'ô' bạn đang đi đến mọi góc của ô bạn muốn đến. Bạn thậm chí có thể tối ưu hóa điều này thành 3 dòng thay vì bốn. Điều này sẽ không phát hiện chính xác tất cả các ô trên đường dẫn?

Đối với các đường dẫn mượt mà hơn, hãy kiểm tra các bài viết về 'hành vi lái', đặc biệt là các kết hợp với A *, ví dụ như các liên kết này:


0

Tôi mới thực hiện thuật toán này cho một trò chơi của tôi vài ngày trước! (-số 8

Đây là ý tưởng của tôi trong một hình ảnh hình ảnh:

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

Lưu ý rằng thuật toán hoạt động với hình chữ nhật có kích thước bất kỳ. nó dựa trên thực tế là một góc của hình chữ nhật luôn va chạm đầu tiên với bất kỳ đường lưới nào. Điều này có nghĩa là bạn chỉ có thể theo dõi một tia và có được tất cả các giao điểm bạn cần.

Đây là thuật toán từng bước:

  1. Chọn góc "chuyển tiếp" của hình chữ nhật của bạn. Ví dụ, trong hình, hướng truy tìm nằm ở góc phần tư phía trên bên phải, vì vậy chúng tôi chọn góc trên bên phải.
  2. Theo dõi tia (không độ rộng) từ góc này đến đích của bạn. Bạn sẽ cần phải lặp đi lặp lại trên tất cả các giao điểm của tia của bạn với các đường lưới.
  3. Đối với tất cả các giao điểm của tia với các đường lưới, đặt hình chữ nhật của bạn tại điểm giao nhau. Mặt của nó sẽ nằm chính xác dọc theo một đường lưới, chạm vào một số ô lưới. Đây là những viên gạch mà hình chữ nhật của bạn va chạm vào thời điểm này!

Có một số trường hợp cạnh ở đây, như khi tia chính xác theo chiều dọc / ngang hoặc khi nó chạm chính xác vào một góc, nhưng chúng không khó.


0

Thủ tục này là một sự thích nghi của bresenham, giải quyết câu hỏi gốc.

vạch một đường có kích thước gạch trên lưới

final int cols = 64;
final int rows = 64;
color tiles = new color[cols*rows];

void squaretrace(int x1, int y1, int x2, int y2, color c) {
  if (x1==x2 && y1==y2) {
    tiles[x1+y1*cols] += c;
  } else {
    // make sure y1 is less or equal to y2
    if (y2 < y1) {
      int t = x1;
      x1 = x2;
      x2 = t;
      t = y1;
      y1 = y2;
      y2 = t;
    }
    // along y-axis
    if (x1==x2) {
      for(int y = y1; y <= y2; y++){
        tiles[x1 + y * cols] += c;
      }
    }
    // along x-axis
    else if (y1==y2) {
      int xLo, xHi;
      if(x1 < x2){
        xLo = x1;
        xHi = x2;
      }
      else{
        xLo = x2;
        xHi = x1;
      }
      for(int x = xLo; x <= xHi; x++){
        tiles[x + y1 * cols] += c;
      }
    }
    // northeast
    else if (x1 < x2) { 
      // NW and SE corner
      int dx = x2 - x1;
      int dy = y2 - y1;
      int m = 8;
      int k = (1<<m) * dx / dy;

      int minx = x1 << m;
      int maxx = (x1+1) << m;

      for (int y = y1; y <= y2; y++) {
        int xLo = minx >> m;
        if (y!=y1) minx += k;
        if (y<y2) maxx += k;
        int xHi = (maxx-1) >> m;
        for (int x = xLo; x <= xHi; x++) {
          tiles[x+y*cols] += c;
        }
        tiles[xLo+y*cols] += c;
        tiles[xHi+y*cols] += c;
      }
    }
    // northwest
    else {
      // NW and SE corner
      int dx = x2 - x1;
      int dy = y2 - y1;
      int m = 8;
      int k = (1<<m) * dx / dy;

      int minx = x1 << m;
      int maxx = (x1+1) << m;

      for (int y = y1; y <= y2; y++) {

        if (y<y2) minx += k;
        int xLo = minx >> m;
        int xHi = (maxx-1) >> m;
        if (y!=y1) maxx += k;

        for (int x = xLo; x <= xHi; x++) {
          tiles[x+y*cols] += c;
        }
        tiles[xLo+y*cols] += c;
        tiles[xHi+y*cols] += c;
      }
    }
  }
}
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.